This code seems to have hijacked the comments, function names and style of WordPress plugin code, and reused it to hide a web shell.
Googling for the package ID that appears in the code ("64f722503297a845d239")
yields a few hits, all obviously this same file, or a related malware.
Googling for the function signature of pre_term_name
gets me a stack overflow
post about this malware.
Looks like it's been around for a while.
It seems to call itself "S.A.P. v2.1"
It might be a rewrite or distant descendant of a c99 web shell.
ring.php
arrives as part of the login_wall plugin.
ring.php
gets used to download gsptg.php, some kind of SEO campaign injector.
It's possible that antivirus companies call this webshell one of the following names:
- Backdoor:PHP/Fobushell.D (Microsoft);
- PHP/WebShell-M (Sophos);
- PHP.Backdoor.Trojan (Symantec);
- Trojan.PHP.Crypt.n (Kaspersky);
- PHP/Kryptik.AJ!tr (Fortinet);
- PHP/Kryptik.AJ (ESET-NOD32)
- PHP_WEBSHELL.YWG
192.154.105.154 → 192-154-105-154.static.gorillaservers.com.
192-154-105-154.static.gorillaservers.com does not have an IP address in DNS.
whois
agrees:
NetRange: 192.154.96.0 - 192.154.111.255
CIDR: 192.154.96.0/20
NetName: GSI-192-154-96-0
NetHandle: NET-192-154-96-0-1
OriginAS: AS53850
Organization: GorillaServers, Inc. (GORIL-3)
RegDate: 2012-11-28
Updated: 2013-01-31
network:Auth-Area:192.154.96.0/20
network:ID:NET-11548.192.154.105.152/29
network:Network-Name:192.154.105.154/29
network:IP-Network:192.154.105.152/29
network:IP-Network-Block:192.154.105.152 - 192.154.105.159
ring.php
arrives as one file of many in the login_wall plugin.
The attackers would believe that they downloaded a Zip file
(with whatever extra files a WordPress "plugin" would require)
via the "install a plugin" WordPress admin page.
Unfortunately, I run a WordPress honey pot that can emulate plugin download and install, so I captured the Zip file.
ring.php
doesn't appear particularly like an obfuscated web shell.
It looks like an ordinary, yet esoteric, piece of WordPress code.
It has a comment block that doesn't make sense,
yet references WordPress conventions like "default hooks" and "priority".
The coding style looks WordPress-like as well:
careful $snake_case
variable and function names,
"wp_" prefixes on variable names.
Some of the variables get what looks like HTML assigned to them.
One of those variables is named $wp_default_logo
.
It apparently contains one of those in-lined, Base64-encoded PNG images
that some web apps use, apparently to cut down on the large number of files necessary.
The Base64-encoded material is not a PNG format image,
but rather the PHP code for a web shell.
The web shell code is reasonably tightly integrated into the ring.php
obscuring PHP.
You need to invoke ring.php
with a special parameter or cookie value to actually
execute the web shell code.
ring.php
output without "_f_wp" set as a Cookie value or POST parameter is a small HTML form:
<form method= "post" action= ""> <input type= "input" name= "_f_wp" value= ""/><input type= "submit" value= ">"/></form>
It's possible that the _f_wp
name can be l__l_
in variants.
Entering "G0YgIaXqx" and clicking the button shows us ring.php
as a web shell:
Other passwords used for ring.php
appear to be:
- root
- pass
- avto
The web shell source code is compressed via gzip and Xor-encoded with the 9-byte key "G0YgIaXqx".
Gzipping the PHP is a pretty good way to conceal the Xor bytes,
and even makes it hard to guess the Xor byte key length,
since the Zip algorithm removes redundancy from the PHP code,
and only has small, 3-bit "header" values interspersed throughout the compress data.
I was not clever enough to guess the Xor key.
I had to wait until an attacker tried to invoke ring.php
.
My honey pot code caught the "_f_wp" parameter's value.
The code is about 1/3 the size of a WSO variant,
and it doesn't provide the same features.
This is a bare-bones web shell.
It does directory-tree exploration, complete with delete, rename, copy and download of files.
It can do immediate eval of pasted-in PHP code, as well as executing shell commands server-side on the compromised host.
It can do simple server recon, including a summary of server and HTTP server software versions, and phpinfo()
output.
It does not do the "string tools" string format encoding and decoding that WSO does,
nor does it offer as extensive reconnaissance features.
Coding style is very terse with short function and variable names. I'm going to guess that the author is either a native English speaker, or someone who learned to write programs only in English. You can almost always guess what the terse function names mean from the source code:
function ssa
- strip slashes from an arrayfunction bname
- return the "basename" from a file pathfunction mt
- return the "microtime" as single, floating point number. This is something a Linux C programmer might write.function ctf
- create temporary file
This brevity extends into the JavaScript code that the PHP ultimatel emits intermixed with HTML.
The code has 3 PHP class declarations.
class zc
creates PKZip Zip archives in pure PHP.
class sc
provides a database-independent interface for MySQL, Postgres and MSSql databases.
Uses mssql_
and mysql_
prefixed functions which were removed from PHP 7.0.
It does use a couple of define()
.
IW for "is windows?", ST, PE if posix_geteuid()
exists as function.
IW does effect whether it uses '/' or '' to compose file names.
It will only offer to "bruteforce" passwords on non-Windows machines.
Uses cmd.exe
in back connect and bind shells on Windows,
/bin/sh
on non-Windows
Looks for PHP versions less than 5.4,
but it only does set_magic_quotes_runtime(0)
for those lower versions.
Keeps a PHP "session", containing about 5 variables, some of which have purposes that aren't easily determined.
- CP - working directory on compromised machine, initially
dirname($_SERVER['SCRIPT_FILENAME'])
- CS - character set, UTF-8
- MO - array, but can't tell of what
- CO - array, but can't tell of what
- DB - probably type of database (Postgres, MySQL, MSSql)
ring.php
uses about 40 HTTP parameters,
most of which end up in HTML as "hidden" <input>
tags,
and therefore are just used to communicate state from one HTTP request
to another.
- bg
- br
- brp
- cd
- cs
- ct
- el
- ep
- er
- es
- ev
- ex
- fbc
- fbp
- fc
- fca
- fcf
- fda
- fdw
- fdwa
- fe
- fef
- fefc
- fefd
- fefg
- fm
- fma
- fn
- fn
- fp
- fpr
- frd
- frs
- fs
- fsn
- fsp
- fsr
- fss
- fst
- gh
- h
- ha
- hbc
- hs
- nt
- nt
- pb
- pb
- pbc
- pf
- pl
- sc
- sc
- sd
- se
- si
- so
- sp
- sq
- st
- t
There is no way a programmer can keep all that straight.
I'm not going to bother trying to decipher a mess like that.
This is terrible design, and will contribute to less evolution of ring.php
.
Contrast this with WSO-family web shells, which communicates state
between invocations in PHP sessions (pre-2.4) or cookies (2.5 and descendents)
and uses a maximum of 4 HTTP parameters to accomplish more than ring.php
does.
The ring.php
author used the "HTML and JavaScript mixed-in with PHP"
style of coding - lots of <?php
and ?>
tags interspersed in the HTML.
Other web shells like fx29
, c99
and r57
use this same style.
The code does output a "DOCTYPE" line:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"/>
It seems like this could be used to bracket how old ring.php
is,
but I couldn't find anything that put a date on when that sort of doctype appeared.
This line just might be in the HTML to put browsers in "quirks mode",
becuase ring.php
generates goofy HTML, and the author(s)
didn't know how to fix it, or didn't care to fix it.
ring.php
offers back-connect and bind-port shells.
A bind-port shell is a program that listens for connections on a TCP port,
and arranges for a shell program to run locally when something connects to that port.
A back-connect shell immediately tries to connect to a TCP port on
some other IP address, then runs a shell program locally when
the connection occurs.
It's easier to get a bind-port program to work,
but attackers won't have the ability to attach to it if the computer
on which the bind-port program runs is behind a firewall,
or even using NAT.
The back-connect shell will usually make it through a firewall,
and always make it through a NAT server,
but an attacker has to have a server of sorts running on a computer
before hand, else the TCP connection won't work.
Both shells are written in Perl,
and exec'ed without a fully qualified path on both Windows and non-Windows.
The shells share most of the code,
and neither appears to be related to the back-connect and bind-shells
from WSO web shells.
Both shells have a major defect.
In an apperant attempt to cover the activities performed with these shells,
the Perl codes calls system("unset HISTFILE; unset SAVEHIST;");
.
Immediately after, the code starts a shell with system('/bin/sh -i');
The problem is that the two system()
calls use seperate invocations /bin/sh
.
Only the first invocation will have its command history reset.
The second invocation, which starts the actuall shell process used by an attacker,
will record commands invoked by the attacker as usual.
This seems like a strange mistake to make when rewriting the rest of the code so carefully.
This code has some similarities to c99 web shells.
c99's function microtime
is almost identical to ring.php's function mt
.
c99's function strips
has a subset in ring.php's function ssa
.
c99 defines "starttime", ring.php defines "ST".
It's possible ring.php
constitutes a drastic rewrite of some c99 variant,
or that ring.php
author(s) re-used some c99 code fragments.
IP address 192.154.105.154 has used ring.php
to download
gsptg.php, some kind of SEO code injector
to my honey pot many, many times.