Paul Marrapese
4 min readApr 5, 2018

It’s no secret that content management systems such as WordPress and Joomla are favorite targets of malware authors. These platforms have earned a reputation of being notoriously bug-ridden, yet enjoy widespread popularity. Coupled with the fact that site owners rarely update their CMS, it becomes trivial for attackers to rapidly infect countless sites when new security vulnerabilities emerge. Infected sites are then often used to profit off of unsuspecting users by serving malicious content.

I was recently contacted to assist with scrubbing an infected site. Script-based malware intrigues me because it inherently includes the source code. I agreed to take a look.

Sealing the Entrances

The telltale signs of malware were obvious from the moment I logged onto the webserver. Dozens of PHP scripts — many masquerading as favicon.ico files — littered the filesystem. And although the underlying CMS had been updated to the latest version, some of these scripts were mere hours old, making it obvious that either an unpatched vulnerability was being exploited or a backdoor was in place.

I pulled the site’s access logs and looked for activity around the time of the scripts’ creation. A pattern of one specific IP address POSTing to obviously fake endpoints yet receiving a 200 HTTP status code became apparent. Other log entries showed all platform exploit attempts being rejected —confirming that a backdoor was most certainly present. Furthermore, the consistent style of communication to the malware hinted that the infection was registered with and managed by a central C&C server.

Malware of this nature typically latches onto a host site by means of an include statement within CMS components and/or the site's main entry point (e.g. index.php). I used the find command to locate files modified after the site’s initial deployment, and discovered multiple platform components that had been altered.

One could simply purge the inclusions and call it a day, but there’s hardly any fun in that.

Dissection

It’s rare to find interpreted malware that doesn’t employ obfuscation, and this was no exception to that rule. However, the technique employed was extremely basic, using only Base64-encoding with a substitution cipher. The underlying code was not obfuscated in any way — with function names and variable names fully intact — making it extremely easy to analyze.

The malware’s primary features included executing arbitrary code from an attacker, and storing arbitrary code to be executed when users accessed the site. Stored code was appended in the form of a comment at the end of the obfuscated script. Resilience features were also present, such as re-implementing restricted PHP functions if needed.

The malware distinguished requests from an attacker versus regular users by testing request parameters. On any request, the malware first attempts to decrypt data from the last cookie or POST parameter provided. If this succeeds, a provided authorization key is checked against a hard-coded authorization key. If this matches, the malware executes the attacker’s commands. Otherwise, all stored payloads are executed.

Crypto routines from the malware.

Encryption is utilized in attacker requests as well as for any stored code by means of a 2-pass repeating-key XOR cipher. The first pass uses the script’s hard-coded authorization key, and the second pass uses a key provided by the attacker in the case of attacker requests, or the script’s file path in the case of storing code. Moving the script would break its ability to decrypt any stored code.

Payload sample: TdsClient

Given the modular nature of this malware, its ultimate functionality could vary from host-to-host depending on which payloads the attacker has armed it with. The sample acquired from the infected host had only one stored payload named TdsClient. Here, TDS stands for Traffic Distribution System. A TDS is essentially a redirection service that targets users depending on various factors.

Upon a user request, the hardcoded URL of the TDS is queried with information such as the user’s IP address, user agent, language, and referrer. If the TDS determines the user is a good target, it responds with HTML/JavaScript or a URL. The client script then either injects the code into the response, or redirects the user elsewhere.

The TDS client also included stealth functionality to reduce its chances of being discovered. For example, if a requested URL contained the strings admin or wp-login.php, no content injection would occur, as modified content would reveal to an administrator that the site is infected. Additionally, requests with user agents containing strings such as google and bing would also not be altered, as search engines are known warning both users and webmasters about threats on sites.

After scrubbing the site, a honeypot was deployed using the malware’s authorization key and crypto routines to capture the attacker’s commands. While nothing profoundly interesting was observed, it did confirm that the malware was persisting via remote updates from the attacker.

One should assume that any modern malware ships with persistence and remote management features. If an attacker gains access to a host, they are going to do all they can to maintain even if the original attack vector is closed. Even if your site is not exhibiting aberrant behavior, it can be beneficial to periodically review access logs for any suspicious requests.

Paul Marrapese

Security engineer and music-maker living in the Bay Area.