De-obfuscating a botnet infection
Last night I was working on a PHP website for a client when I stumbled upon this line of code whitespaced way off the screen on the first line of a few of our files: https://gist.github.com/ryepdx/5016290
That looked pretty suspicious to me, so I googled “$GLOBALS['QQOO']” and the only result that came up was this Pastebin: http://pastebin.com/71nwAsj6
Definitely didn’t like the look of that, so I grepped the rest of our files and found the same code embedded in the same way on four more files. I removed it from all of them, re-uploaded the cleaned files, and got to work figuring out what this code was doing.
I copied the code, commented out the call to “$Ill11I1lI” at the end of “function Q0QQOOQO,” and echoed out $Ill11I1lI. This gave me “preg_replace.” A little research revealed that the “/e” flag in preg_replace makes preg_replace automatically eval the result. (This seems like a spectacularly bad design decision to me, but that’s just my opinion.)
So I echoed “Q0QQOOQO(710, 2563)” to see what code they were trying to make preg_replace run. I got back: https://gist.github.com/ryepdx/5016310
More preg_replace eval’ing, so I commented out the call to “$Q00Q0QOQQ” and echoed IlI11lll(721, 2563). I got back a pretty sizable string of code, which I formatted and then took the liberty of renaming what was pretty obviously a “get string” function to “get_string.” That gave me this code: https://gist.github.com/ryepdx/5015935
I then did a search for all calls to “get_string” and isolated them to one line each, then used a little regex-fu to generate this PHP file: https://gist.github.com/ryepdx/5015963
And then I used the output from that PHP script to create a Python script (I realize I could have just used PHP, but my Python-fu is stronger) to find and replace all the calls to “get_string” with their actual returned values: https://gist.github.com/ryepdx/5015978
That got me a file I could actually read somewhat. I started working my way down the file, renaming variables like “$QO0OQO” and “$IIl11I” to things like “$curl” and “$curl_init.” After working at it like a crossword puzzle (“What’s a name for the third parameter in fsockopen?”) for around half an hour, I was finally treated to its final, naked, legible form (which I then filled with helpful comments): https://gist.github.com/ryepdx/5016252
Basically this code allows the botnet owners to execute arbitrary PHP code on the infected server. Not a very friendly piece of code!
TL;DR: Found obfuscated botnet code on a client’s server and spent about an hour and a half making it readable: https://gist.github.com/ryepdx/5016252
I’ve found similar code myself on sites I’ve done work on. I’m unsure how this crap gets there. I assume some sort of vulnerable templateing as that’s the only place evaluation is ever taking place but I could never pin it down.
Have you come up with a good way to defend against these? I’ve just game up and decided to fix file/folder permissions on certain seemingly vulnerable scripts rather than to step through them and debug someone else’s monster and hope they come out with a patch in the future. Then I wrote a shell script using inotify (http://linux.die.net/man/7/inotify) to watch the file system for changes to files and email me whenever it notices them so I can track down activity to a single script and investigate.
Obama should pass law to make PHP illegal to use in servers
Ohhh… it’s funny because PHP is believed to be insecure! Genius, you really showed them this time! It’s great that you brought this up here, I think everyone can appreciate such an accurate comment.
http://www.reddit.com/r/ThanksObama
Beautifully Executed.