ince August 2025, researchers have tracked a campaign chaining phpMyAdmin/MariaDB log poisoning, a China Chopper–style web shell, AntSword for post-exploitation, deployment of a Nezha (open-source RMM/monitoring) agent, and finally Ghost RAT persistence. The typical entry point: XAMPP/WAMP stacks or appliances where phpMyAdmin is exposed without authentication (or poorly segmented) and both the web and DB services run under the same OS account.
This brief distills the Huntress / Hispasec case into operator-grade steps, commands, IoCs, and ready-to-use playbooks.
1) Intrusion Chain (Operator’s View)
- Initial Access
- Exposed phpMyAdmin; actor switches locale to zh_CN; initial IP from AWS Hong Kong.
- XAMPP defaults: Apache + MariaDB under same user, DB account with SUPER privileges.
- Log Poisoning (MariaDB)
- Enable general query logging and redirect output to a web-served file with
.php
extension:SET GLOBAL general_log_file='../../htdocs/123.php'; SET GLOBAL general_log='ON';
- Inject a PHP one-liner (
eval($_REQUEST[1])
) via a query; it lands in the log, now executable as a web shell.
- Enable general query logging and redirect output to a web-served file with
- Post-Exploitation with AntSword
- Through the shell, AntSword sends commands (with rotating stag/etag) and cd’s to
C:\Windows\Cursors\
.
- Through the shell, AntSword sends commands (with rotating stag/etag) and cd’s to
- Nezha Deployment
- Download
live.exe
(Nezha agent) +config.yml
from Cloudflare Pages (rism.pages[.]dev
). - The agent checks in to
c.mid[.]al
(HostPapa, Dublin). The Nezha dashboard showed >100 agents.
- Download
- Evasion & Final Payload
- Elevated PowerShell: Defender exclusions (
Add-MpPreference -ExclusionPath 'C:\WINDOWS'
). - Run
x.exe
→ Ghost RAT; persistence via serviceSQLlite
(sic) atSystem32\SQLlite.exe
and DLL32138546.dll
. - RAT C2:
gd[.]bj2[.]xyz
→ 45.207.220[.]12 (same IP operating AntSword).
- Elevated PowerShell: Defender exclusions (
Huntress isolated and remediated by removing the web shell, Nezha agent, and Ghost RAT before further objectives executed.
2) Indicators of Compromise (IoCs)
Files & Hashes
Path | Description | SHA256 |
---|---|---|
C:\xamp\htdocs\123.php | Web shell (PHP) | f3570bb6e0f9c6…d16 |
C:\Windows\Cursors\live.exe | Nezha agent | 9f33095a24471b…7de6 |
C:\Windows\Cursors\x.exe | Ghost RAT loader | 7b2599ed54b72d…c958 |
C:\Windows\System32\SQLlite.exe | Persistence (renamed rundll32 ) | 82611e60a2c5de…799 |
C:\Windows\System32\32138546.dll | Malicious DLL | 35e0b22139fb27…10f3 |
Infrastructure
Type | Value | Note |
---|---|---|
Initial access IP | 54.46.50[.]255 | AWS Hong Kong (ASN 16509) |
Web shell/C2 | 45.207.220[.]12 | ASN 53808 (MoeDove) |
Nezha download | rism.pages[.]dev/microsoft.exe | Cloudflare Pages |
Nezha C2 | c.mid[.]al → 172.245.52[.]169 | HostPapa (IE) |
Ghost RAT C2 | gd[.]bj2[.]xyz | A record → 45.207.220[.]12 |
Artifacts
Key | Value |
---|---|
Persistence service | SQLlite |
Mutex | gd.bj2[.]xyz:53762:SQLlite |
Staging path | C:\Windows\Cursors\ |
3) MITRE ATT&CK (High Level)
- Initial Access: T1190 (Exploited Web App).
- Execution: T1059.008 (SQL), T1059.001 (PowerShell), T1106 (Native API).
- Persistence: T1543.003 (Create/Modify Service), T1053.005 (Scheduled Task variants).
- Defense Evasion: T1036 (Masquerade:
SQLlite.exe
), T1562.001 (Disable AV), T1112 (Modify Registry). - C2: T1071.001 (Web), T1573 (Encrypted Channel).
- Discovery: T1082 (System), T1033 (Account).
4) Response Playbook (Windows + Apache/PHP)
Goal: isolate, preserve evidence, eradicate backdoors, and re-secure web/DB surface.
4.1 Containment & Forensics
- Isolate host from Internet (ACL/WAF/segmentation).
- Collect:
- Apache
access/error
, MariaDB general_log (if enabled), Windows Event Logs. htdocs
,wp-content
,php.ini
,httpd.conf
,my.ini/my.cnf
.
- Apache
- EDR: freeze any
httpd.exe
child spawningpowershell.exe
/curl.exe
.
4.2 Hunt & Eradication
- Find web shells & remote refs:
Get-ChildItem C:\xamp\htdocs -Recurse -Include *.php | Select-String -Pattern 'eval\(|base64_decode\(|assert\(|system\(|popen\(|shell_exec\(' -List
- Delete
C:\xamp\htdocs\123.php
and any suspicious drop-ins. - Services: inspect
SQLlite
and binaries inSystem32
:Get-Service | Where {$_.Name -match 'SQLlite|sqlite'} sc.exe qc SQLlite Get-ChildItem C:\Windows\System32\SQLlite.exe, C:\Windows\System32\32138546.dll | Get-FileHash -Algorithm SHA256
- Tasks:
schtasks /Query /FO LIST /V | findstr /I "Cursors SQLlite rundll32"
- Re-enable Defender:
Get-MpPreference | Select ExclusionPath Set-MpPreference -ExclusionPath @()
- Nezha: remove
live.exe
,config.yml
, and any related service/task.
4.3 Re-secure
- Rotate creds (Windows, Apache, DB).
- Reinstall MariaDB/Apache/PHP on supported versions; split service accounts.
- AppLocker/WDAC / Constrained Language:
- Force Constrained Language for PowerShell under the web service account.
- Deny execution in
C:\Windows\Cursors\
and other non-exec paths.
5) Web/DB Hardening (Windows or Linux)
5.1 phpMyAdmin / XAMPP
- Do not expose phpMyAdmin to the Internet. If unavoidable: VPN/Zero-Trust, IP allowlist, MFA.
- Apache example:
<Directory "C:/xamp/phpMyAdmin"> Require ip 10.0.0.0/8 192.168.0.0/16 Require not ip all </Directory>
- Remove public alias if unused (
Alias /phpmyadmin
).
5.2 MariaDB
- Disable general_log by default; restrict writes outside of proper log dirs.
- Split identities: MariaDB svc ≠ Apache/IIS svc; app account without
SUPER
. - AppArmor/SELinux (Linux): prevent
mysqld
from writing intohtdocs
. - Harden
my.cnf
:[mysqld] general_log=OFF log_error=/var/log/mysql/error.log secure-file-priv=/var/lib/mysql-files local_infile=0
- Treat XAMPP as dev only; migrate production to supported deployments.
5.3 Apache/PHP
- Disable dangerous functions where feasible:
; php.ini disable_functions = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec expose_php = Off
- Enforce CSP + SRI; enable ModSecurity CRS and add rules for shells and file-write:
SecRule REQUEST_URI "@contains functions.php" "id:100010,phase:2,deny,msg:'Suspicious theme edit attempt'" SecRule ARGS "(base64_decode|eval\()" "id:100011,phase:2,deny,msg:'PHP eval/base64 in request'"
6) Detection (EDR, SIEM, WAF)
6.1 SIGMA (ideas)
Apache parent → PowerShell
title: Apache/Php-CGI Spawns PowerShell
logsource: { product: windows, category: process_creation }
detection:
sel:
ParentImage|endswith:
- '\httpd.exe'
- '\php-cgi.exe'
Image|endswith: '\powershell.exe'
condition: sel
level: high
Code language: JavaScript (javascript)
Suspicious service creation (SQLlite)
title: Suspicious Service Creation SQLlite Masquerade
logsource: { product: windows, category: registry_event }
detection:
sel:
TargetObject|contains: '\System\CurrentControlSet\Services\SQLlite'
condition: sel
level: high
Code language: JavaScript (javascript)
6.2 Suricata/Snort (sketch)
alert http any any -> any any (msg:"C2 porsasystem"; content:"porsasystem.com"; http_host; sid:400001;)
alert http any any -> any any (msg:"Nezha Cloudflare Pages"; content:"rism.pages.dev"; http_host; sid:400002;)
alert http any any -> any any (msg:"GhostRAT C2 bj2.xyz"; content:"bj2.xyz"; http_host; sid:400003;)
Code language: CSS (css)
6.3 WAF/CDN
- Block 1×1 iframes sourcing fake
cdn-cgi/*
from non-Cloudflare origins. - Bot-management / rate-limit on
/wp-admin
,/phpmyadmin
.
7) Windows Hardening for the Web Server
- Web service account without SeDebugPrivilege and no write to
System32
,Windows
, or user profiles. - Exploit Guard / ASR:
- Block script/child process spawns from
httpd.exe
/php-cgi.exe
. - Enable “Block process creations from PSExec/WMI” and other relevant rules.
- Block script/child process spawns from
- PowerShell: enable Constrained Language + script block logging.
- AppLocker/WDAC: default-deny + signed/allowlisted binaries only.
8) On-Call Quick Questions
Is phpMyAdmin reachable from the Internet?
→ Cut it now; put behind VPN or allowlist. Check DNS for stray dev subdomains.
Do I see httpd.exe
spawning PowerShell/curl?
→ Isolate; inspect C:\Windows\Cursors\
, service SQLlite
, new DLLs in System32
.
Where is my server calling out to?
→ Block rism.pages[.]dev
, c.mid[.]al
, gd.bj2[.]xyz
, 45.207.220[.]12
, 54.46.50[.]255
and review historical traffic.
How do I hunt WordPress shells?
→ Grep/PowerShell for eval(
, base64_decode(
in wp-content
, themes/*/functions.php
, mu-plugins
; verify against known checksums.
9) Lessons for Infra & Operations
- Production ≠ XAMPP. If it lingers, assume breach.
- Separation of duties: distinct OS accounts for web/DB, no SUPER for app accounts, MAC controls (AppArmor/SELinux).
- Post-exploitation visibility: beyond WAF; EDR for web-parent process trees and persistence.
- Legitimate tools abused (Nezha, RMM, Cloudflare Pages): implement abuse-aware controls and detections.
References
- Huntress — The Crown Prince, Nezha: A New Tool Favored by China-Nexus Threat Actors.
- Hispasec — Nezha: De herramienta open-source a nueva arma en ataques a servidores web.
Bottom line: the jump from “exposed phpMyAdmin” to “persistent RAT” can take minutes. Your best defense is removing exposure, splitting identities, monitoring web-spawned child processes, and practiced playbooks.