Skip to content

Latest commit

 

History

History

campaignA

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Web shell installation into WordPress

Here's a short, 3.993 second WSO (Web Shell by oRb, a.k.a. "FilesMan") installation. It includes only eight HTTP requests, including a cold WordPress login. The attacking IP address, 77.72.82.12, has probably never accessed my web server before.

The username/password used was first "discovered" by 5.39.27.194, which apparently only does WordPress password guessing. There's a hidden (to me) connection between 5.39.27.194 and 77.72.82.12.

Origin

IP Address 77.72.82.12

77.72.82.12 reverse lookups as hostby.ups-gb.co.uk

hostby.ups-gb.co.uk does not have an A record

whois says 77.72.82.12 is owned by a UK company:

organisation:   ORG-UPSL4-RIPE
org-name:       United Protection (UK) Security LIMITED
address:        141-149 Lower Bryan Street, Hanley, Stoke On Trent, Staffordshire, England, ST1 5AT
address:        United Kingdom
mnt-by:         UPUKS-MNT
created:        2017-01-24T19:50:55Z
last-modified:  2017-10-30T14:45:58Z

The routing is a little odd:

descr:          NFOrce Entertainment BV - route 77.72.82.0/24
origin:         AS43350
mnt-by:         MNT-NFORCE
created:        2017-02-01T14:01:04Z
last-modified:  2017-02-01T14:01:04Z

traceroute goes through cogent1-gsa.r2.dbc.nl.as43350.com, which geoiplookup says is in Netherlands, but geoiplookup has 77.72.82.12 as in the UK. It appears that some trans-Atlantic cables go from USA to Netherlands directly, but many more go directly to Great Britain.

p0f3 identifies 77.72.82.12 as "Windows 7 or 8"

[2018/08/30 14:58:19] mod=syn|cli=77.72.82.12/53502|srv=162.246.45.144/80|subj=cli|os=Windows 7 or 8|dist=12|params=fuzzy|raw_sig=4:116+12:0:1460:8192,8:mss,nop,ws,nop,nop,sok:df,id+,ecn:0

Deobfuscation

Fairly easy to deobfuscate, it only required changing "eval" to "print", then running the program to get the next level of obfuscated code. I did that several times to get a copy of WSO 2.5.

Everything else is unobfuscated at the level that my WordPress honey pot sees things.

Analysis

Timestamp of request Action requested of WordPress
2018-08-30T03:39:13.440-0600 Cold call to WordPress login page. No cookies, no HTTP parameters.
2018-08-30T03:39:13.835-0600 Attacker sends WordPress "cookie check" cookie back, no WordPress user or password.
2018-08-30T03:39:14.171-0600 Attacker sends WordPress login as admin/1234qwer, proper WordPress HTTP parameters
2018-08-30T03:39:14.444-0600 Attacker sends request for WordPress admin dashboard. WordPress logged-in-cookies set correctly
2018-08-30T03:39:15.036-0600 Sends request for theme editor page
2018-08-30T03:39:15.668-0600 Request to edit 404.php file from theme twentytwelve in browser.
2018-08-30T03:39:16.171-0600 Compromised 404.php file contents sent to theme editor to save.
2018-08-30T03:39:16.977-0600 Invocation of /blog/wp-content/themes/twentytwelve/404.php, which should get a WSO login page
2018-08-30T03:39:17.434-0600 Invocation of /blog/wp-content/themes/twentytwelve/404.php with HTTP "pass" parameter set incorrectly

This isn't the most direct way of compromising a file on a WordPress site, but it also isn't exactly the sequence of calls that a human-driven browser would make, either. For example, wp-login.php has links to JavaScript and CSS files that this attacker did not ask for, but a real browser would. I don't think a human-driven browser could jump in to editing a file in a theme without some intermediate pages getting displayed, either. There's also no real need to make a "cold call" of wp-login.php: it's entirely possible to set login name/password and the required cookies in a single invocation of wp-login.php.

The final HTTP request called 404.php directly, as opposed to asking for a nonexistent URL and letting Apache or WordPress invoke 404.php. Unfortunately, the attacker put an ASCII carriage return (control-M, "\r") at the beginning of the HTTP parameter name: "\rpass" instead of "pass". This seems like some kind of Windows-text-editor problem that leaked through. It also kept the attacker from logging in to my WSO honey pot. The WSO password it sent: "ryfgddj".

Unfortunately, entities access URLs with "twentytwelve/404.php" quite often, 29133 times between 2014-03-10 15:04:20-06 and 2018-09-01 23:40:43-06. I don't think that looking at accesses of "twentytwelve/404.php" would bear fruit.

WordPress User Name and Password

Since the attacker logged in on it's first try, examining the user ID and password seems important.

admin/1234qwer first logged in to my WordPress honey pot:

2017-11-24T21:55:39-07:00   5.39.27.194 admin   1234qwer

This may not be first successful login with this password. I've lost some data along the way, due to running a honey pot off-and-on for some years. Disks fill up, I forget to load Apache log files, etc etc.

"1234qwer" as a WordPress password guess is pretty common. It got tried 221 times between 2017-11-21T02:05:19.42-07:00 and 2018-08-31T09:21:52.347-06:00, by 92 different IP addresses, in combination with 127 different user names. Some of the user names are obviously mistakes ("{domain}" probably constitutes a failed template expansion). "admin" got used 75 of the 221 times. My WordPress honey pot allows user name enumeration through the "see all posts by this author" misfeature. Many, but not all ("paul-mureithi", "stratigery") are the result of random user IDs composed by the user name enumeration misfeature emulation.

Password guessing

Four "cycles" of guessing passwords:

  • cycle 1: 101 passwords, stopping at "adminadmin", a successful login
  • cycle 2: same sequence of passwords, but stops at "1234qwer", also a successful login
  • cycle 3: same sequence of passwords, but stops at "1234qwer"
  • cycle 3: different sequence of 22 passwords, stops at "adminadmin"

The mean time between login attempts is 0.231 seconds, median is 0.219 seconds. The distribution of inter-login-intervals doesn't look meaningful. The short inter-attempt interval confirms this was completely automated.

The cycles begin and end with an HTTP GET method request. All other requests use the HTTP POST method.

My WordPress honey pot accepts any password as legitmate with a probability of 0.00050 (1 in 2000). It also keeps track of any passwords it has deemed legitmate in the past. Previously, on 2017-11-21T16:26:28-07:00, the WordPress honey pot had granted 91.200.12.75 access with user name "admin", password "adminadmin". So 5.39.27.194 got to "adminadmin" in its list of passwords to try, and the honey pot let it in.

Cycle 2 took place about 3.5 hours later. During that cycle of guessing, the WordPress honey pot got the random number that means "allow this password", and let 5.39.27.194 in on "1234qwer". At a guess, Cycle 3 is double-checking the odd results (to bottom feeding WordPress password guesser) that Cycles 1 and 2 gave. 5.39.27.194 got to "1234qwer" before "adminadmin", and got logged in on that. Cycle 4 got to "adminadmin" before it tried "1234qwer".

This looks like another unfortunate interaction between WordPress honey pot design, and real life. It might be better to have a specific password for a honey pot. Potentially, nobody will guess it unless it's something really lame like "1234", so that's a drawback. Also, the honey pot wouldn't harvest as many potential passwords. Perhaps a WordPress honey pot that doesn't accept any password, merely logs guessing IP address, from port, time and password would be in order just to capture password guessing lists.

IP Address 5.39.27.194

This IP address seems to be doing only WordPress password guessing. 5.39.27.194 only used 110 distinct candidate passwords. A few got tried 4 times, but many only got tried a single time. "1234qwer" got tried 4 different times. I put 5.39.27.194's password guessing history in a file.

The IP address 5.39.27.194 has performed at least 209 accesses between 2017-11-24T18:28:51-07 and 2017-11-30T11:57:15-07 All of the accesses asked for /wp-login.php URIs, except the following.

Timestamp URI
2017-11-24 18:29:14-07 /wp-admin/
2017-11-24 21:55:39-07 /wp-admin/
2017-11-28 08:49:31-07 /wp-admin/
2017-11-30 11:57:15-07 /wp-admin/

Each of those corresponds to a successful WordPress "login" to my honey pot.

User agent string: " Mozilla/5.0 (Linux; U; Android 2.2) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" which disagrees with p0f3 assessement of "Windows 7 or 8"

Password guessing cycle timings:

  1. 2017-11-24T18:28:52.018-0700 to 2017-11-24T18:29:14.445-0700
  2. 2017-11-24T21:55:30.406-0700 to 2017-11-24T21:55:39.005-0700
  3. 2017-11-28T08:49:23.093-0700 to 2017-11-28T08:49:31.748-0700
  4. 2017-11-30T11:57:09.182-0700 to 2017-11-30T11:57:15.101-0700

p0f3 recorded these TCP SYN packets from 5.39.27.194:

Timestamp From port distance (hops) Guessing cycle
2017-11-24 18:28:51-07 58756 17 Cycle 1
2017-11-24 18:29:14-07 61183 17 ???
2017-11-24 21:55:29-07 64280 17 Cycle 2
2017-11-28 08:49:22-07 62903 17 Cycle 3
2017-11-30 11:57:08-07 62547 17 Cycle 4

Ephemeral port numbers for Windows 7 and up are supposedly 49152 to 65535. Linux supposedly uses 32768 to 61000 by default. The 4 TCP "from" port numbers greater than 61000 would support a Windows 7 or 8 OS, as opposed to Linux.

It isn't out of the question to see only 5 TCP port numbers for 200+ HTTP requests. The attacker used HTTP/1.1 on all requests.

I unfortunately don't log from port in my attempted logins file, so I can't tell what the port 61183 comes from.