PHParasites: WordPress Malware

Reconnaissance Tools

Reconnaissance tools collect and send back information about the
software available on a WordPress host.
That information ranges from sending an email to a well known address, to
scanning the host system for whatever other CMS (besides WordPress)
system(s) and database(s) it might execute.

The WSO web shell includes decent recon capability,
displaying operating system and version, PHP version, size of filesystem
and includes a "Sec. Info" action. This last action shows HTTP server
version, interesting executables available, including which databases
are installed. I examine WSO separately.

Self Destructing Probe - LijHgs3*.php

I encountered a "self destructing" reconnaissance program.
124 PHP files with names like LijHgs3_8878737.php
and LijHgs3_2791796.php got uploaded
between 2013-06-23T02:24:35-06 and 2013-06-23T04:18:27-06.
The uploads came from 114 different IP addresses, which p0f
identified as mostly Windows XP, Windows Vista, with a
couple of IP addresses identified as Linux.
All uploads were by WSO web shell file upload.
All 124 uploads called WSO as 502.php.
Each of the 124 uploads had a different substring of digits, indicating
some coordination between the 114 IP addresses.

In turn, 502.php was uploaded 3 times before
the "LijHgs3" PHP files were uploaded, and many times afterward,
always using the fake WordPress "plugin upload" feature.
2 unique IP addresses,
188.92.74.87 and 91.197.19.103, uploaded
502.php between 2013-06-16 and 2013-06-21.
Neither 188.92.74.87 nor 91.197.19.103 uploaded "LijHgs3" PHP files.
p0f said that 188.92.74.87 was Windows 2000 or Windows XP,
and that 91.197.19.103 ran Windows Vista.

Nothing ever actually invoked any of the "LijHgs3" PHP files,
perhaps because the honey pot's fake WSO
(at the time) did not confirm uploads correctly by
displaying the uploaded file name.
I later changed that aspect of the fake WSO.

The "LijHgs3" source code:

created a directory

created a file in that directory

wrote the string "np9i8gkli" to the file

used PHP's file_get_contents() to read the file

If "LijHgs3" read the same string that it wrote, it echoed "np9i8gkli"

otherwise it echoed "sdcoiwenldz33s"

It unlinked ("deleted") all files named "LijHgs3_*" in the current directory

It ran echo 'bbbpathsbbb'.'http://stratigery.com/'.'eeepathseee';

The output of the final "echo" is clearly machine-parseable, designed to be read by
some program. The strings for successful or error file write and read
are a bit less obvious, not even having the same string length.

The coding style of the final echo indicates that the "LijHgs3" programs
were all programmatically generated, as there is no reason to
concatenate 3 strings other than convenience in writing the program
that generated the "LijHgs3" programs.

Xgr0upvn Data Checker Tool vBeta

Downloaded via WSO 'uploadFile' by a Windows Vista machine at 117.0.42.185, and
invoked 39 seconds later by that same machine, this recon tool walks the user through
a password login and some other nonsense, to produce a list of files
in the directory it runs from, with MD5 checksums.
The program is unusual as it contains dual Vietnamese/English strings
in a primitive attempt at I18N coding. The IP address is in a Vietnamese
ISP's netblock.

The timing of the upload and invocation, as well as what else the IP
address asked for (/favicon.ico, for example) indicate that
this might have been a manual exploit attempt.
Either the uploader was a Windows user or silly, because the PHP code
was uploaded as "Shell.php", but attempted invocation was as "shell.php".
That would work for a Windows HTTP server (I think), but not a Linux
server.

Not the same as Xgr0upVN ShElL,
but may be from the same Vietnamese hacker collective.

The WSO shell URL used to upload the XgrOupVN Data Checker Tool was jm.php.
WSO had been uploaded as jm.php 10 times between 2013-06-19 and 2013-06-26,
by 6 different IP addresses
two months before 117.0.42.185 tried to invoke it.
That statement gives a bit of a false impression, as 20 different IP addresses
invoked jm.php between 2013-06-19 and 2013-09-11.
It appears that knowledge of a nominally successful WSO upload gets shared or
sold around.

connector_t.php got uploaded to a previously-installed WSO web shell
named info.php. Both times WSO would have named the uploaded code "connector_t.php".

Timestamp

From IP address

URL

2013-08-20T01:35:27-06

188.135.184.119

/wp-content/plugins/customize-admin/info.php

2013-08-22T14:07:52-06

117.253.203.39

/wp-content/plugins/customize-admin/info.php

connector_t.php got invoked 2 seconds after download with no
parameters. This shows how
hard it is to emulate malware on honey pots: automatic download and testing gives
the honey pot operator no time to check out the downloaded code.

Timestamp

From IP address

2013-08-20 01:35:29-06

188.135.184.119

2013-08-22 14:07:54-06

117.253.203.39

connector_t.php gives back a single line of text upon
invocation:
init::f6mnZP0cwKNo9q::5.2.14::ok.
That's the PHP version number, a hardcoded string that looks random, and "ok"
indicates that it can send SMTP email on the victim machine.

connector_t.php's code consists of a call to PHP's mail() function (address:
'noreply@google.com') 3 times in a loop, after getting the PHP version number.
If mail() succeeds any of the 3 times you get the 'ok' suffix on the output shown above.

Multiple attempts at calling mail('noreply@google.com', 'Noreply', '')
is emblematic. It appears that WordPress malware, or the hosts that WordPress
runs on, have reliability issues. Malware tries every important operation
at least two times without assuming an error condition.

A very subtle STMP testing program, url.php got uploaded
as just one PHP file out of many in a plugin named "Imailer". The
Imailer.zip file contained the usual "Tumblr Importer"
PHP files, but it also contained mod_system.php, a WSO v2.5
web shell, copyrights.php (which is "PostMan Full 3.5"
a spamming program), and url.php itself. The code is as follows:

It was uploaded by 95.57.60.115 at 2013-08-26T10:00:29-06, then invoked
at 2013-08-26T10:13:35-06. The uploader had a User-Agent string of
"Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0",
while the invoker sent "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36",
and also requested /favicon.ico right away.
This looks like someone had a guess-password-install-malware program
running. They got a notification that url.php was installed,
and then tried it interactively.

The really subtle part is that the message url.php sends
looks like spam, an ad for a stupid money mule job with some scammers,
perhaps. Note that the subject line of the email will have the URL
of the url.php program itself. Conveniently, that's almost
the URL of the "PostMan Full" spamming tool included in that plugin's
zip file. Once "izik.krg" gets an email, he can fire up his spam
command and control and start blasting out crap. In fact "izik" can
automate the whole thing based on the "Subject:" line of the email.

CMS installations Check

Sent to my honey pot's WSO web shell emulation 43 times by 27 different IP address between
2013-07-05T02:21:19-06 and 2013-08-21T07:43:30-06.

It amounts to a very long ASCII string, which gets eval'ed (inside WSO's PHP eval) like this:
eval(gzuncompress(base64_decode($eval_code)));

It looks for WordPress, Joomla, Drupal, TYPO3, phpBB, PunBB, e107, DataLife Engine
and Simple Machines Forum installations, by changing directory up to the root of
the file system. It then does a breadth-first recursive search up to 10 levels deep
for what it considers "core files" of each of the CMSes it knows about.
For instance, the "core files" of a WordPress installation amount to those named
"wp-content", "wp-admin" and "wp-includes".

The code handles Windows installations as well as Linux, mainly by substituting backslashes
for slashes in file paths, although a few other considerations get taken care of.
It looks like several people have worked on it: the original code appears neat and tidy,
uniformly indented,
and it has debug output using unadorned PHP echo commands.
Any lines of code generating debug output have been commented out using '//'-style comment leaders.
Some later debug output code additions break the uniform indentation, and got commented out using '#'-style
comment leaders. Oddly the later debug output is preceded by if($debug_mode),
so whether output appears or not depends on the value of the $debug_mode variable,
which is set to false at the very beginning of the code. Why bother commenting it out?

SRVC WebShell modul

I'm going into somewhat more depth for the "SRVC WebShell modul" because
I can't find it described anywhere.
The "SRVC WebShell modul" [sic], collects a lot of information about the system
it runs on, then returns a Base-64 encoded, serialized PHP associative arrary.
The data it collects looks like this before encoding:

SRVC WebShell modul often has multiple methods coded in it to find any of
the above parameters. The code prefers to use PHP builtins (php_uname())
to find a value, but it ultimately falls back to a Linux-specific method, like
shelling out to run uname -s. No Windows-specific fallbacks exist,
as near as I can tell. Shelling out to run a command is a study in alternatives,
starting by trying shell_exec(), trying 4 more PHP builtins, finally
using proc_open() if none of the other alternatives work.

SRVC WebShell modul tests if email works by sending email to a random, 32-character
"user ID" at the domain asdasd.ru. It waits 8 seconds, then checks
http://asdasd.ru?u=32-character random user ID to see
if the email arrived. The asdasd.ru service appears to be some weird Russian
semi-anonymous email dead drop, but the SRVC WebShell modul uses it to advantage.
If you send an email manually to asdasd.ru, it takes substantially longer than
8 seconds to percolate messages up to the web interface, so I doubt that the SRVC code
works correctly.

One of the tests, the value of "is_evalable" above, is interesting. The "1" value
indicates that an eval() worked. I can't really understand why you'd
bother to test for a working eval() when the code that does the
testing is executing courtesy of eval(gzuncompress(base64_decode($eval_code)));
itself. Further, the code doing the testing got run by the actionPHP action
of a WSO web shell. As it happens, WSO does an eval()
on PHP code sent to it in that action. So, SRVC WebShell modul checks to see if
eval() works inside of two layers of eval(). Either SRVC WebShell modul
sometimes runs outside of WSO, or SRVC WebShell modul isn't executed by the same folks
who wrote it. The attackers using it don't understand it, because the code just gets passed
around from one bad coder to the next.

The SRVC WebShell modul appears fairly unified, having a consistent variable
and function naming and consistent bracket placement styles.
The programmer(s) indented it uniformly, at 1 ASCII space per indentation level,
making for some dense code.
The code has only
a few comments, which appear to fall into 2 categories: commented-out debugging
code, and a few "TODO" notes, which indicate places where even more alternatives
could be implemented.