Para equipos de sistemas y seguridad. Desde agosto de 2025 se observa una campaña que encadena log poisoning vía phpMyAdmin/MariaDB, web shell tipo China Chopper, operación con AntSword, agente Nezha (monitorización/RMM open-source) y, como payload final, Ghost RAT con persistencia. El vector inicial típico: stacks XAMPP/WAMP o appliances con phpMyAdmin publicado sin autenticación (o mal segmentado), y servicios web/DB corriendo con el mismo usuario.
Este texto condensa el caso (Huntress / Hispasec) en procedimientos técnicos, comandos, IoCs y playbooks listos para producción.
1) Cadena de intrusión (resumen operativo)
- Acceso inicial
- phpMyAdmin expuesto; cambio de locale a zh_CN; uso de IP AWS HK.
- XAMPP con Apache y MariaDB bajo el mismo usuario, BD con SUPER por defecto.
- Log poisoning (MariaDB)
- Habilitan general query log y lo apuntan a
…/htdocs/123.php
:SET GLOBAL general_log_file='../../htdocs/123.php'; SET GLOBAL general_log='ON';
- Inyectan one-liner PHP con
eval($_REQUEST[1])
en el log → web shell ejecutable.
- Habilitan general query log y lo apuntan a
- Post-explotación con AntSword
- Desde el web shell, AntSword emite comandos (con stag/etag dinámicos) y cambia a
C:\Windows\Cursors\
.
- Desde el web shell, AntSword emite comandos (con stag/etag dinámicos) y cambia a
- Despliegue de Nezha
- Descargan
live.exe
(agente Nezha) +config.yml
desde Cloudflare Pages (rism.pages[.]dev
). - Agente llama a
c.mid[.]al
(HostPapa, Dublín). Panel mostraba >100 agentes.
- Descargan
- Evasión y payload final
- PowerShell elevado: exclusiones Defender (
Add-MpPreference -ExclusionPath 'C:\WINDOWS'
). - Ejecutan
x.exe
→ Ghost RAT; persistencia como servicioSQLlite
(sic) con binario enSystem32\SQLlite.exe
y DLL32138546.dll
. - C2 del stealer:
gd.bj2[.]xyz
→ 45.207.220[.]12 (misma IP operando AntSword).
- PowerShell elevado: exclusiones Defender (
2) Indicadores de compromiso (IoCs)
Ficheros y hashes
Ruta | Descripción | SHA256 |
---|---|---|
C:\xamp\htdocs\123.php | Web shell (PHP) | f3570bb6e0f9c6…d16 |
C:\Windows\Cursors\live.exe | Agente Nezha | 9f33095a24471b…7de6 |
C:\Windows\Cursors\x.exe | Loader Ghost RAT | 7b2599ed54b72d…c958 |
C:\Windows\System32\SQLlite.exe | Persistencia (renombrado rundll32 ) | 82611e60a2c5de…799 |
C:\Windows\System32\32138546.dll | DLL maliciosa | 35e0b22139fb27…10f3 |
Infraestructura
Tipo | Valor | Comentario |
---|---|---|
IP inicial | 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 | Resuelve a 45.207.220[.]12 |
Artefactos
Clave | Valor |
---|---|
Servicio persistente | SQLlite |
Mutex | gd.bj2[.]xyz:53762:SQLlite |
Ruta staging | C:\Windows\Cursors\ |
3) MITRE ATT&CK (alto nivel)
- Initial Access: T1190 (Exploited Web App).
- Execution: T1059.008 (SQL), T1059.001 (PowerShell), T1106 (API nativa).
- Persistence: T1543.003 (Create/Modify Service), T1053.005 (Scheduled Task, variantes).
- Defense Evasion: T1036 (Masquerade:
SQLlite.exe
), T1562.001 (Disable AV), T1112 (Modify Registry). - C2: T1071.001 (Web), T1573 (Encrypted Channel).
- Discovery: T1082, T1033.
4) Playbook de respuesta (servidor Windows con Apache/PHP)
Objetivo: aislar, preservar pruebas, erradicar backdoors y re-asegurar superficie web/DB.
4.1 Contención y forense
- Aislar el host de Internet (ACL/WAF/segmentación).
- Volcado de:
- Logs Apache (
access/error
), MariaDB general_log (si activo), event logs Windows. htdocs
,wp-content
,php.ini
,httpd.conf
,my.ini/my.cnf
.
- Logs Apache (
- EDR: congelar proceso árbol de
httpd.exe
hijo que lanzapowershell.exe
/curl.exe
.
4.2 Búsqueda y erradicación
- Localizar web shells y referencias remotas:
Get-ChildItem C:\xamp\htdocs -Recurse -Include *.php | Select-String -Pattern 'eval\(|base64_decode\(|assert\(|system\(|popen\(|shell_exec\(' -List
- Eliminar
C:\xamp\htdocs\123.php
y cualquier drop-in sospechoso. - Servicios: revisar
SQLlite
y binarios enSystem32
: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
- Tareas:
schtasks /Query /FO LIST /V | findstr /I "Cursors SQLlite rundll32"
- Defender re-enable:
Get-MpPreference | Select ExclusionPath Set-MpPreference -ExclusionPath @()
- Nezha agent: eliminar
live.exe
,config.yml
, servicios/tareas que lo llamen.
4.3 Re-aseguramiento
- Rotación de credenciales (Windows, Apache, DB).
- Reinstalar MariaDB/Apache/PHP a versiones soportadas; separar usuarios de servicio.
- Reglas AppLocker/Constrained Language:
- Bloquear
powershell.exe
en modo restringido para cuenta del servicio web. - Denegar ejecución en
C:\Windows\Cursors\
y otras rutas no ejecutables.
- Bloquear
5) Endurecimiento web/DB (Windows o Linux)
5.1 phpMyAdmin / XAMPP
- No exponer phpMyAdmin a Internet. Si imprescindible: VPN/Zero-Trust, allowlist IP, MFA.
- En Apache:
<Directory "C:/xamp/phpMyAdmin"> Require ip 10.0.0.0/8 192.168.0.0/16 Require not ip all </Directory>
- Eliminar alias público si no se usa (
Alias /phpmyadmin
).
5.2 MariaDB
- Deshabilitar general_log y evitar escritura fuera de
/var/log/mysql
(Linux) o directorio de logs (Windows). - Separar usuarios: cuenta de MariaDB ≠ cuenta de Apache/IIS; sin
SUPER
al usuario de app. - AppArmor/SELinux (Linux): denegar
mysqld
escribiendo enhtdocs
. my.cnf
endurecido:[mysqld] general_log=OFF log_error=/var/log/mysql/error.log secure-file-priv=/var/lib/mysql-files local_infile=0
- Revisar XAMPP: no producción. Migrar a despliegue soportado.
5.3 Apache/PHP
- Deshabilitar funciones peligrosas si la app lo permite:
; php.ini disable_functions = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec expose_php = Off
- CSP + SRI para JS externos; ModSecurity CRS con reglas para detección de shells y 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) Detección (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
Lenguaje del código: JavaScript (javascript)
Crear servicio SQLlite (masquerade)
title: Suspicious Service Creation SQLlite Masquerade
logsource: { product: windows, category: registry_event }
detection:
sel:
TargetObject|contains: '\System\CurrentControlSet\Services\SQLlite'
condition: sel
level: high
Lenguaje del código: JavaScript (javascript)
6.2 Suricata/Snort (boceto)
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;)
Lenguaje del código: CSS (css)
6.3 WAF/CDN
- Bloquear iframes 1×1 con cargas a
cdn-cgi/*
no originadas en Cloudflare real. - Rate limiting y bot management en
/wp-admin
,/phpmyadmin
.
7) Endurecimiento Windows (servicio web)
- Cuenta de servicio del web server sin SeDebugPrivilege ni permisos de escritura en
System32
,Windows
y perfiles. - Exploit Guard / ASR:
- Bloquear ejecuciones de scripts descendientes de
httpd.exe
/php-cgi.exe
. - Regla “Block Process Creations from PSExec/WMI” y “Block Office child processes” si aplica.
- Bloquear ejecuciones de scripts descendientes de
- PowerShell: Constrained Language + script block logging.
- AppLocker/WDAC: deny-by-default y solo firmados/allowlist.
8) Preguntas rápidas de guardia
¿Tengo phpMyAdmin accesible desde Internet?
→ Córtelo ya; ponga VPN o allowlist. Revise DNS que no haya subdominios de pruebas.
¿Veo httpd.exe
lanzando PowerShell/curl?
→ Aislar; revisar C:\Windows\Cursors\
, servicios SQLlite
, DLLs nuevas en System32
.
¿A dónde llama mi servidor?
→ Bloquee rism.pages[.]dev
, c.mid[.]al
, gd.bj2[.]xyz
, 45.207.220[.]12
, 54.46.50[.]255
y busque conexiones históricas.
¿Cómo detecto web shells en WordPress?
→ Grep/PS para eval(
, base64_decode(
en wp-content
, themes/*/functions.php
, mu-plugins
. Compare con checksums del tema original.
9) Lecciones para infra de sistemas
- Producción ≠ XAMPP. Si se queda, asuma brecha.
- Separación de poderes: web y DB con usuarios distintos, sin SUPER y con barreras MAC (AppArmor/SELinux).
- Visibilidad post-explotación: más allá del WAF; EDR que vea parent-child de procesos web y persistence.
- “Herramientas legítimas” (Nezha, RMM, Cloudflare Pages) se usan contra usted: listas de control y detección de abuso son obligatorias.
Referencias
- 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.
Mensaje final: el salto de “phpMyAdmin mal expuesto” a “RAT persistente” ocurre en minutos. Su mejor defensa es eliminación de exposición, separación de cuentas, monitorización de procesos hijo del web server y playbooks practicados.
Fuente: opensecurity