From time to time, I look at WordPress, which as you may have guessed, runs my blog. It’s had a spotty security history. If I can find something in a few minutes, I’ll help out as it’s my data at risk.

But then they go and do this:


<?php

if ( !defined( 'ABSPATH' ) )
exit;

/** @ignore */
function dvortr( $str ) {
return strtr(
$str,
'\',.pyfgcrl/=\\aoeuidhtns-;qjkxbmwvz"<>PYFGCRL?+|AOEUIDHTNS_:QJKXBMWVZ[]',
'qwertyuiop[]\\asdfghjkl;\'zxcvbnm,./QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?-='
);
}

$j = clean_url( site_url( '/wp-includes/js/jquery/jquery.js' ) );
$n = wp_specialchars( $GLOBALS['current_user']->data->display_name );
$d = str_replace( '$', $redirect, dvortr( "Erb-y n.y ydco dall.b aiacbv Wa ce]-irxajt- dp.u]-$-VIr XajtWzaVv" ) );

wp_die( <<<EOEE
<style type="text/css">
html body { font-family: courier, monospace; }
#hal { text-decoration: blink; }

<script type="text/javascript" src="$j"></script>
<script type="text/javascript">
/* <![CDATA[ */
var n = '$n';
eval(function(p,a,c,k,e,r){e= ... crap deleted ...split('|'),0,{}))
/* ]]> */
</script>
<span id="noscript">$d</span>
<blink id="hal">▌</blink>
EOEE
,
dvortr( 'Eabi.p!' )
);

So what does it do? Let’s undo this obfuscation one thing at a time:

The Caesar Cipher was easy – I created a new PHP file with the dvortr() function and the strings to be decoded. They came out as:


Don't let this happen again. Go Back.
Danger!

The packer was also easy, I changed the code to pump out the HTML on the command line, plonked that back into Eclipse, and changed the definition of eval to alert, one of the more evil / stupid things JavaScript can get up to:


eval = alert;
eval(...)

I then copy and pasted the code in the alert pop up and re-formatted it in Eclipse.

Guess what? It’s got another layer of obfuscation, again using the same crappy caesar cipher. Figuring out the strings and what it does it pretty easy from that point on.

Interestingly, when Firebug stumbles across code it thinks is compressed JS, it stops showing you the code. WTF? You can still step through it one line at a time, but the compressor is NOT a security mechanism, and hiding it will not stop me. I will report a bug with the Firebug team as stopping the display of JavaScript is a defect, not a feature to protect the revenues / reputations of compressors.

So, decoding in multiple passes, the final output is this:


Self-comparison detected.
Initiating infinite loop eschewal protocol.
Self destruct in... 3
2
1

It’s an easter egg error message when a revision comparison fails. Or something like that. This is completely unnecessary – there’s no dark secret here requiring this level of sneakiness, and it’s an excellent place for malicious folks to hide attacks.

The code is so obscure, that no static analysis tool can inspect it, or security auditor would normally take the time out to look at it, and yet it may contain an XSS or DOM injection, or it may contain malware if the download is corrupted, or a fake version comes out

I really wish that folks who think this sort of thing is necessary really stop to think about the amount of time it took them to craft this particular gem

It would be best to delete this – and every other WP easter egg – now before it infects any 2.7 installations. Easter eggs are incompatible with secure software.

14 comments on “Decoding wp-admin/js/revisions-js.php easter egg

Leave a Reply

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