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 controllerman.php
– A disguised file interaction handlercount.txt
– A log file used to store visiting IPsupdate.bat
– A generated batch file that downloads and executes malwarepsps.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:
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:
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:
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.
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).
This malware establishes a covert connection back to the Command and Control (C2) server at 5.252.178.123 on port 443.
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
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.