De phpMyAdmin expuesto a control total del servidor: anatomía (y defensa) de la cadena Nezha → Ghost RAT usada por actores China-nexus

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)

  1. 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.
  2. 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.
  3. Post-explotación con AntSword
    • Desde el web shell, AntSword emite comandos (con stag/etag dinámicos) y cambia a C:\Windows\Cursors\.
  4. 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.
  5. Evasión y payload final
    • PowerShell elevado: exclusiones Defender (Add-MpPreference -ExclusionPath 'C:\WINDOWS').
    • Ejecutan x.exeGhost RAT; persistencia como servicio SQLlite (sic) con binario en System32\SQLlite.exe y DLL 32138546.dll.
    • C2 del stealer: gd.bj2[.]xyz45.207.220[.]12 (misma IP operando AntSword).

2) Indicadores de compromiso (IoCs)

Ficheros y hashes

RutaDescripciónSHA256
C:\xamp\htdocs\123.phpWeb shell (PHP)f3570bb6e0f9c6…d16
C:\Windows\Cursors\live.exeAgente Nezha9f33095a24471b…7de6
C:\Windows\Cursors\x.exeLoader Ghost RAT7b2599ed54b72d…c958
C:\Windows\System32\SQLlite.exePersistencia (renombrado rundll32)82611e60a2c5de…799
C:\Windows\System32\32138546.dllDLL maliciosa35e0b22139fb27…10f3

Infraestructura

TipoValorComentario
IP inicial54.46.50[.]255AWS Hong Kong (ASN 16509)
Web shell/C245.207.220[.]12ASN 53808 (MoeDove)
Nezha downloadrism.pages[.]dev/microsoft.exeCloudflare Pages
Nezha C2c.mid[.]al172.245.52[.]169HostPapa (IE)
Ghost RAT C2gd.bj2[.]xyzResuelve a 45.207.220[.]12

Artefactos

ClaveValor
Servicio persistenteSQLlite
Mutexgd.bj2[.]xyz:53762:SQLlite
Ruta stagingC:\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

  1. Aislar el host de Internet (ACL/WAF/segmentación).
  2. 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.
  3. EDR: congelar proceso árbol de httpd.exe hijo que lanza powershell.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 en System32: 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.

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 en htdocs.
  • 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.
  • 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

Suscríbete al boletín SysAdmin

Este es tu recurso para las últimas noticias y consejos sobre administración de sistemas, Linux, Windows, cloud computing, seguridad de la nube, etc. Lo enviamos 2 días a la semana.

¡Apúntate a nuestro newsletter!


– patrocinadores –

Noticias destacadas

– patrocinadores –

¡SUSCRÍBETE AL BOLETÍN
DE LOS SYSADMINS!

Scroll al inicio
×