Decoding wp-admin/js/revisions-js.php easter egg

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.

Comments

16 responses to “Decoding wp-admin/js/revisions-js.php easter egg”

  1. […] I noted a few weeks ago, WordPress has had an obfuscated easter egg in it for some […]

  2. wondering Avatar
    wondering

    Am trying to figure out if the “crap deleted” is the same “crap” I have in mine, or if mine is actually malware. Can you please advise? Here’s the code where your “crap deleted” is. Thanks!

    function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!”.replace(/^/,String)){while(c–)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return’\\\\w+’};c=1};while(c–)if(k[c])p=p.replace(new RegExp(‘\\\\b’+e(c)+’\\\\b’,’g’),k[c]);return p}(‘6(4(){2 e=6(\\’#Q\\’).v();2 i=\\’\\\\\\’,.R/=\\\\\\\\S-;T”U?+|V:W[]X{}\\’.u(\\’\\’);2 o=\\’Y[]\\\\\\\\Z;\\\\\\’10,./11{}|12:”13?-=14+\\’.u(\\’\\’);2 5=4(s){r=\\’\\’;6.15(s.u(\\’\\’),4(){2 t=16.D();2 c=6.17(t,i);r+=\\’\$\\’==t?n:(-1==c?t:o[c])});j r};2 a=[\\’O.E[18 e.y.19.1a\\’,\\’1b 1c. 1d .1e.,1f 1g\\’,\\’O.E e.1h 1i 8\\’,\\’9\\’,\\’0\\’];2 b=[\\’0;g–){7(3==f.q[g-1].1W||\\’1X\\’==f.q[g-1].1Y.1Z()){f.20(f.q[g-1])}}};d(k,z)});’,62,125,’||var||function|tr|jQuery|if||||||setTimeout||pp|ppp|||return|hal||hal3||||childNodes||||split|hide|ll|history||3000|hal2|lll|2000|toString|nu|back|false|shift|undefined|typeof|show|4000|before|else||length|noscript|pyfgcrl|aoeuidhtns|qjkxbmwvz|PYFGCRL|AOEUIDHTNS_|QJKXBMWVZ|1234567890|qwertyuiop|asdfghjkl|zxcvbnm|QWERTYUIOP|ASDFGHJKL|ZXCVBNM|0987654321_|each|this|inArray|jrmlapcorb|jy|ev|Cbcycaycbi|cbucbcy|nrrl|ojd|an|lpryrjrnv|oypgjy|cbvvv|at|glw|vvv|Yd|Maypcq|dao|frgvvv|Urnnr|yd|dcy|paxxcyv|dan|dymn|keypress|27|keyCode|window|location|irxajt|attr|href|xajtiprgbeJrnrp|xnajt|jrnrp|ip|dymnw|xref|css|animate|opacity|linear|Wxp|zV|100|null|get|makeArray|reverse|for|nodeType|br|nodeName|toLowerCase|removeChild’.

  3. vanderaj Avatar

    Yes, this is the obfuscated crap I was talking about.

  4. Bill Platt Avatar
    Bill Platt

    Will deleting the easter egg cause an unnecessary error in WordPress?

    These guys should have been a little smarter about this. I never find the easter egg until I am trying to clean a WordPress install that had been compromised already.

  5. vanderaj Avatar

    It has no function in Word Press other than vanity

  6. Josh Rusev Avatar
    Josh Rusev

    This is really maddening for those of us that are serious about security on our websites. Maybe WP will get serious about security someday

  7. Uncle Demotivator Avatar

    I don’t know which f*ckhead thought that it would be a could idea to put a obfuscated JS into WP core files, but thanks to him/her searching for malware on my hacked hosting become even more frustrating.

  8. Uncle Demotivator Avatar

    *could = good obviously – You can edit it if You want.

  9. vanderaj Avatar

    I hadn’t even thought of that angle. My problem with it is that it’s dumb and unnecessary, but you’re absolutely right!

  10. dammit Avatar
    dammit

    Another sysadmin, also thinking this was an exploit, ticked off to find out about this.

  11. Glen Boonzaier Avatar
    Glen Boonzaier

    This is heart attack material. our box has infact been hacked. Inserting base64_decode shit everywhere in every possible corner. To come across this and waste my time trying to figure out if it is part of the attack just wastes more of my time and more of my companies money.

    I have in fact just sent out an email to all my clients warning them that WordPress is no longer supported. I am also going to segment the wordpress sites under their own user and lock them the f**k down to their own little hole.

  12. vanderaj Avatar

    This is exactly the reason why I want it gone.

    The just released 3.8 has more base64_decode() for other reasons, including delivering fonts and SSO support. The good news is that it appears that the Caesar cipher / packed JS is gone in 3.8.

  13. online discounts Avatar
    online discounts

    Hey there, I think your website might be having browser compatibility issues.
    When I look at your blog in Firefox, it looks fine but when opening in Internet Explorer, it has some overlapping.
    I just wanted to give you a quick heads up! Other then that,
    superb blog!

  14. vanderaj Avatar

    I just use the default WP theme. If there’s overlapping, it’s IE’s fault, and should be chased up between them and Word Press.

  15. Urmas Avatar
    Urmas

    Having spent hours for cleaning after hacking… updated with clean code, searched “eval” and WTF.. found this file. AGAIN HACKED??? .. and then, turns out, that someone made a joke. Jesus Crist..

  16. machin chouette Avatar
    machin chouette

    because it’s in the clean archive

Leave a Reply

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