Skip to content

Latest commit

 

History

History

settings.php

WSO 2.5 webshell download via apikey.php

An instance of Web Shell by oRb version 2.5, uniquely-obfuscated, and downloaded via apikey.php.

Origin

IP Address 185.39.199.9

185.39.199.9 → Kolomiec-gw.solomenskaya3-sw.kv.wnet.ua

185.39.199.9 belongs to:

inetnum:        185.39.199.0 - 185.39.199.255
netname:        WNET-KYIV
address:        Wnet LLC
address:        Bohdana Khmelnitskoho 48A
address:        Kyiv, 01030
address:        Ukraine

Looks like wnet.ua is a high end ISP that can provide network consulting and services, and maybe even write a little software.

p0f3 is convinced that "Windows 7 or 8" drives this IP address.

Download

Looks like the attacker(s) thought that someone had installed a working apikey.php file downloader. I added apikey.php emulation to my honey pot on 2019-04-05, added emulation of apikey.php access test, and 2019-05-27, added file download capability.

The file downloaded would have ended up named settings.php

The download user agent says:

Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3198.0 Safari/537.36 OPR/49.0.2711.0

The "Accept" and "Accept-Encoding" are "/" and "identity" respectively. This seems to be something that Chrome browsers send, which lines up with the user agent string.

Deobfuscation

The downloaded code can be made into a decoder by changing "eval" to "print", and cleaning up some of the "<?" PHP short tags. Since a lot of PHP installations no longer allow short tags, their use seems self-limiting.

The next stage is a visual dog's breakfast. PHP comments interspersed through PHP code obscured by calls to function eltelt(), with a number as the argument. The eltelt() base64-decodes a string from an array based on the numerical argument.

The obfuscation is simpler than it immediately appears. All string literals in the original code got replaced by calls to function eltelt(). The numeric argument to eltelt() constitutes a count: the first string literal gets replaced by eltelt(1), the second by eltelt(2), the hundreth by eltelt(100) and so forth. Each string literal got base64-encoded, and the resulting string becomes an array element in eltelt(). The obfuscators made no attempt to re-use strings already in the eltelt() internal array.

Analysis

The obfuscation seems odd. It does encode strings like "FilesMAn" and "WSO_VERSION" which are probably widely used in malware signatures. The obfuscation doesn't keep a human from looking at the code for a few seconds and recognizing that the obfuscated code is probably a version of WSO. Typical WSO function names ("WSOsetcookie", "wsoEx", "actionPhp") are still present, as they aren't string literals. Signatures based on function names will not get fooled by this obfuscation. If you've gone to the work of extracting all string literals and replacing them with a function call, why not "compact" the string literal data by keeping track of strings? This would minimize the data needed by the string-literal-recovery function, and possibly make the code even less visually appealing.

It's just another WSO web shell. I've already seen it used to download extendable back door malware. The unique aspects are:

  • Download via apikey.php
  • Encoding of string literals