maitret

wp-malware-remediation

"Analizar, detectar y limpiar malware PHP en sitios WordPress alojados en servidores Linux (CWP/cPanel). Cubre el ciclo completo: triage, backup, escaneo heurístico, clasificación de hallazgos, limpieza quirúrgica de código inyectado, eliminación de archivos 100% maliciosos, restauración de WordPress core, validación post-limpieza y hardening. WHEN: malware en WordPress, limpiar sitio hackeado, código ofuscado PHP, webshell, backdoor, hacklink, archivos sospechosos en uploads, eval base64_decode, archivo PHP inyectado, limpiar servidor comprometido, cuarentena malware, restaurar WordPress core."

maitret 2 Updated 2mo ago

Resources

19
GitHub

Install

npx skillscat add maitret/wordpress-malwarescanner

Install via the SkillsCat registry.

SKILL.md

WordPress Malware Remediation

GUÍA OPERATIVA — Ciclo completo de detección y limpieza de malware PHP en WordPress sobre servidores Linux (CWP/cPanel).

Triggers

Activar este skill cuando el usuario necesite:

  • Analizar un servidor o sitio WordPress comprometido con malware
  • Limpiar archivos PHP con código inyectado (hacklinks, webshells, backdoors)
  • Eliminar archivos completamente maliciosos (droppers, loaders, shells)
  • Clasificar hallazgos del scanner (MALWARE / LIKELY_MALWARE / SUSPICIOUS)
  • Crear o actualizar firmas/reglas de detección
  • Restaurar WordPress core desde copia limpia
  • Validar que la limpieza fue efectiva
  • Investigar código PHP ofuscado (base64, hex, goto spaghetti, char-index)

Reglas Fundamentales

  1. NUNCA limpiar sin backup previo — Respaldar BD y archivos antes de cualquier acción destructiva.
  2. Escaneo inicial siempre en modo solo-reporte — Usar --no-quarantine en la primera pasada.
  3. Revisar falsos positivos — Plugins legítimos (Wordfence, Guzzle, wp-migrate-db) pueden disparar firmas.
  4. Dos tipos de limpieza — Distinguir entre archivos que se limpian (extraer líneas maliciosas) vs. archivos que se eliminan completos.
  5. Documentar cada IOC confirmado — Agregar a signatures/local_iocs.json para futuras detecciones.
  6. Re-escanear después de limpiar — Validar que no queden remanentes.

Herramientas del Toolkit

Cada fase del flujo operativo se apoya en herramientas específicas ya implementadas. La columna Estado indica el nivel de madurez.

Herramienta Función principal Estado
malware_scanner.py Motor heurístico: 6 capas de firmas, scoring, entropía, análisis ZIP, reportes (JSON/texto/rm scripts), cuarentena, --clean, --disable, --validate-wp ✅ Producción
wp_backup_db.sh Autodescubre wp-config.php, extrae credenciales DB, dump MySQL + gzip. Lock anti-ejecución simultánea. ✅ Producción
wp_reemplaza.sh Restaura wp-admin/wp-includes vía rsync desde copia limpia. Backup previo de BD + core (tar.gz). Detecta versión WP y Multisite. Restaura permisos y ownership. ✅ Producción
fix_permissions.sh Corrección recursiva: dirs 755, archivos 644, wp-config.php 600, home 711, public_html 750. Modo --dry-run, --verbose, por usuario o --all. Compatible CWP/cPanel. ✅ Producción
malware_scan.sh Triage rápido por grep/find: firmas básicas, PHP en uploads, archivos recientes, nombres sospechosos, permisos 777. ✅ Triage
wp_security_scan.sh Cuarentena básica: mueve archivos sospechosos a quarantine/, valida WP core con diff, detecta archivos recientes. ✅ Triage
signatures/*.json Firmas externas: internal_knowledge (6), community (6), local_iocs (9), yara_fallback (5). ✅ Extensible
signatures/yara/*.yar Reglas YARA curadas (5 reglas). Requiere yara-python o yara-x opcional. ✅ Opcional
malware_refs/ Muestras de referencia de malware conocido para pruebas. ✅ Referencia

Flujo Operativo Completo

Fase 1 — Preparación y Backup

Herramienta: wp_backup_db.sh | Estado: ✅ Implementado

# 1. Crear estructura de directorios
mkdir -p /home_D0/fixes/{logs,quarantine,backups,wordpress}

# 2. Respaldar todas las bases de datos WordPress
./wp_backup_db.sh /home
# Solo un sitio:
./wp_backup_db.sh /home/user/public_html

# 3. Verificar que los dumps se crearon
ls -lh /home_D0/fixes/backups/*.sql.gz

Lo que hace wp_backup_db.sh:

  • Busca todos los wp-config.php bajo el directorio indicado
  • Extrae DB_NAME, DB_USER, DB_PASSWORD, DB_HOST con regex
  • Prueba conexión MySQL antes del dump (timeout 10s)
  • mysqldump --single-transaction --quick + gzip (timeout 120s)
  • Genera archivo temporal de credenciales con chmod 600, lo elimina después
  • Lock con flock para evitar ejecuciones simultáneas
  • Log detallado en /home_D0/fixes/logs/backup_db_*.log
  • Output: /home_D0/fixes/backups/db_{slug}_{timestamp}.sql.gz

Punto de decisión: Si el backup de BD falla, NO continuar hasta resolverlo.

Fase 2 — Escaneo y Triage

Herramienta: malware_scanner.py | Estado: ✅ Implementado

# Escaneo completo, solo reporte (sin mover archivos)
python3 malware_scanner.py --scan /home --no-quarantine --report both

# Más sensible (más hallazgos, más falsos positivos)
python3 malware_scanner.py --scan /home --no-quarantine --threshold 40

# Solo un sitio específico
python3 malware_scanner.py --scan /home/user/public_html --no-quarantine --report both

Lo que hace malware_scanner.py en modo escaneo:

  • Recorre recursivamente buscando archivos PHP (.php, .phtml, .php3-7, .phar, .inc)
  • Ignora archivos > 5MB y rutas whitelisted (/proc, /sys, .git, node_modules)
  • Aplica 6 capas de detección en orden:
    1. 70 firmas core embebidas (regex compilados)
    2. 6 firmas internas curadas (signatures/internal_knowledge.json)
    3. 6 firmas comunidad (signatures/community.json)
    4. 9 IOC locales (signatures/local_iocs.json)
    5. 5 reglas YARA (signatures/yara/*.yar) — requiere yara-python o yara-x
    6. 5 regex fallback (signatures/yara_fallback.json) — si YARA no está disponible
  • Calcula entropía Shannon (0-8) y suma puntos si > 5.2
  • Analiza estructura PHP: gotos excesivos, líneas largas, funciones peligrosas, base64→PHP
  • Detecta y extrae PHP embebido dentro de archivos ZIP (magic bytes PK\x03\x04)
  • Aplica deducción de falsos positivos (hasta -80pts para wp-core, vendors, plugins conocidos)
  • Calcula SHA256 de cada archivo

Archivos de salida generados:

Archivo Contenido
scan_*_files.txt Triage rápido: [VERDICT][SCORE][SOURCES] /path/to/file
scan_*.json JSON estructurado: score, entropy, SHA256, matches con línea y snippet
scan_*.log Log legible con contexto completo de cada hallazgo
scan_*.rm_ALL.txt Script bash con rm -f para TODOS los archivos detectados
scan_*.rm_FIRMA.txt Un script rm por cada tipo de firma (ej: rm_BACKDOOR_HEX_ENCODED_CURL_FETCH.txt)

Para triage rápido preliminar (antes del scanner completo):

./malware_scan.sh    # grep rápido: firmas, PHP en uploads, recientes, nombres, permisos 777

Clasificación de veredictos:

Veredicto Score Acción
MALWARE ≥90 Actuar de inmediato — alta confianza
LIKELY_MALWARE 80-89 Revisar manualmente, confirmar y actuar
SUSPICIOUS 60-79 Investigar contexto antes de decidir
CLEAN <60 Sin acción (no se reporta)

Fase 3 — Análisis y Clasificación de Hallazgos

Herramienta: malware_scanner.py (campo cleanable en JSON) | Estado: ⚠️ Parcial

El scanner ya marca cada hallazgo con "cleanable": true/false en el JSON, pero el criterio actual es limitado: solo considera "limpiable" las firmas de hacklink (HACKLINK_KNOWN_DOMAIN, HACKLINK_WP_HOOK_FOOTER, HACKLINK_STATIC_GUARD, IOC_TELEGRAM_COMMENT) con score < 90.

Para cada archivo detectado, aplicar criterio humano adicional:

3a. Archivos a ELIMINAR completamente

Criterios para eliminación total:

  • El archivo entero es malware (webshell, dropper, loader)
  • Archivos PHP en /uploads/ (no deberían existir) — el scanner ya suma +70pts por LOCATION_PHP_IN_UPLOADS
  • Archivos con nombres sospechosos (wp-developer.php, about.php suelto) — firma SUSPICIOUS_FILENAME +50pts
  • Entropy > 6.5 + score ≥ 90 (archivo cifrado/comprimido) — firma ENTROPY_HIGH +50pts
  • Binarios disfrazados de PHP (header %PDF-) — firma OBFUSC_PDF_HEADER_SPOOF +85pts

Patrones que el scanner detecta como 100% maliciosos (≥90pts):

  • ZIP droppers: LOADER_ZIP_WRAPPER_INCLUDE (97pts)
  • GLOBALS hex dispatch: OBFUSC_GLOBALS_HEX_DISPATCH (90pts)
  • Malware conocido: MALWARE1_MONARX_FAKE y MALWARE1_ICWDOMAIN (99pts)
  • PHP embebido en ZIP: CONTAINER_ZIP_EMBEDDED_PHP (90pts)

3b. Archivos a LIMPIAR (remover solo líneas inyectadas)

Criterios para limpieza parcial:

  • Archivos legítimos de WordPress con código inyectado al inicio o final
  • wp-settings.php, wp-config.php, index.php del tema con líneas extra
  • Inyecciones de hacklinks (bloques add_action('wp_footer', ...) maliciosos)
  • Prepend/Append de @include o require apuntando a archivos maliciosos
  • Comentarios tipo Telegram (// t.me/...) seguidos de código malicioso

Patrones que --clean puede remover automáticamente (3 CLEAN_PATTERNS):

/* Telegram : ... */ if(!function_exists('wp_core_check')){...}  ← hacklink Telegram
if(!function_exists(...)){...hacklinkmarket...}                   ← hacklink market
<?php [1-5 líneas] <?php                                         ← bloque PHP prepend

✅ Patrones ahora cubiertos por --clean automático (v1.2.0):

@include "\x2f...";                    ← include ofuscado al inicio del archivo
eval(base64_decode("..."));            ← eval inyectado como primera línea
Inyecciones append al final (después del ?> de cierre)
@include desde /tmp/, /var/tmp/, /dev/shm/

🔧 Patrones que aún requieren limpieza MANUAL:

Bloques eval/base64 insertados en medio de archivos core de temas
Inyecciones multi-línea complejas intercaladas con código legítimo

Procedimiento de limpieza quirúrgica (manual):

  1. Abrir el archivo y localizar las líneas inyectadas
  2. Verificar que el código restante es WordPress legítimo
  3. Remover SOLO las líneas maliciosas
  4. Validar que el archivo funciona: php -l archivo.php

Fase 4 — Ejecución de Limpieza

Herramienta: malware_scanner.py | Estado: ✅ Implementado (3 modos)

# Opción A: Cuarentenar (mover a /home_D0/fixes/quarantine/)
python3 malware_scanner.py --scan /home --report both

# Opción B: Auto-limpieza de hacklinks + cuarentena del resto
python3 malware_scanner.py --scan /home --clean --report both

# Opción C: Deshabilitar in-situ (chmod 000 + renombrar .DISABLED)
python3 malware_scanner.py --scan /home --disable --report both

Lo que hace cada modo:

Modo Flag Acción Backup previo Log
Cuarentena (default) Mueve archivo a quarantine/{timestamp}_{filename} No (se mueve completo) scan_*.log
Auto-limpieza --clean Aplica 3 regex CLEAN_PATTERNS, si match → reescribe archivo limpio; si no → cuarentena quarantine/backup_{ts}_{file} scan_*.log
Deshabilitar --disable chmod 000 + renombra a .DISABLED No (archivo queda in-situ) scan_*.log + /home/{user}/malware_disabled_log.txt

Limitación de --clean: Solo cubre 3 patrones de hacklink. El resto de inyecciones (eval/base64 prepend, includes ofuscados) requieren limpieza manual o restauración de core (Fase 5).

Para eliminación selectiva por tipo de firma:

# Revisar un grupo antes de ejecutar
cat logs/scan_*.rm_BACKDOOR_HEX_ENCODED_CURL_FETCH.txt

# Ejecutar solo si confirmado (PRECAUCIÓN: verificar falsos positivos)
bash logs/scan_*.rm_LOCATION_PHP_IN_UPLOADS.txt

Fase 5 — Restauración de WordPress Core

Herramientas: wp_reemplaza.sh + malware_scanner.py --validate-wp | Estado: ✅ Implementado

# 1. Asegurar copia limpia en /home_D0/fixes/wordpress/
#    (descargada de wordpress.org, versión correcta)

# 2. Restaurar todos los sitios WP encontrados
./wp_reemplaza.sh

# 3. Validar integridad post-restauración
python3 malware_scanner.py --scan /home --validate-wp --report both

Lo que hace wp_reemplaza.sh:

  • Busca todos los wp-config.php bajo /home
  • Por cada sitio encontrado:
    1. Valida estructura WP (requiere wp-admin/ y wp-includes/)
    2. Detecta versión WP instalada vs versión de la copia limpia (advierte si mismatch)
    3. Detecta Multisite (advierte pero continúa)
    4. Lee credenciales DB del wp-config.php
    5. Backup de BD (mysqldump + gzip) — aborta si falla
    6. Backup de core (tar.gz de wp-admin, wp-includes, *.php raíz)
    7. Rsync desde copia limpia con --delete --checksum
    8. Excluye wp-content/ y wp-config.php del rsync
    9. Restaura permisos (755 dirs, 644 files) y ownership original
  • Lock con flock anti-ejecución simultánea
  • Log: /home_D0/fixes/logs/repair_wp_*.log

Lo que hace --validate-wp en el scanner:

  • Compara MD5 de cada archivo en wp-admin/ y wp-includes/ contra la copia limpia
  • Reporta [MISSING] (archivo no existe) y [MODIFIED] (hash diferente)
  • Solo compara, NO restaura — para restaurar usar wp_reemplaza.sh

La restauración preserva:

  • wp-config.php (credenciales del sitio)
  • wp-content/ completo (plugins, temas, uploads)
  • Ownership original del usuario de hosting

Fase 6 — Validación Post-Limpieza

Herramienta: malware_scanner.py (re-ejecución manual) | Estado: ⚠️ Manual

# Re-escanear para confirmar limpieza
python3 malware_scanner.py --scan /home --no-quarantine --report both

# Comparar con escaneo anterior
diff <(grep '^\[MALWARE\]' logs/scan_ANTERIOR_files.txt) \
     <(grep '^\[MALWARE\]' logs/scan_NUEVO_files.txt)

✅ Implementado: Flag --verify re-escanea automáticamente post-limpieza y reporta remanentes.

Checklist de validación:

  • Cero hallazgos MALWARE en re-escaneo
  • LIKELY_MALWARE restantes son falsos positivos confirmados
  • Sitios WordPress cargan correctamente en navegador
  • Login de admin funciona
  • No hay archivos PHP en /uploads/
  • Permisos restaurados correctamente

Fase 7 — Hardening y Permisos

Herramienta: fix_permissions.sh | Estado: ✅ Implementado

# Corregir todos los usuarios
./fix_permissions.sh --all

# Solo usuarios específicos
./fix_permissions.sh -u juan -u pedro

# Simular sin cambios
./fix_permissions.sh --dry-run --all

# Con salida detallada
./fix_permissions.sh --verbose --all

Lo que hace fix_permissions.sh:

  • Recorre cada usuario en /home/
  • Ignora directorios del sistema (lost+found, fixes, clamav)
Recurso Permisos aplicados
Propietario user:user recursivo
Directorios 755
Archivos regulares 644
wp-config.php 600
.htaccess 644
/home/user (base) 711
public_html 750

Motor de Detección — Arquitectura

6 capas de firmas (implementadas en malware_scanner.py)

Capa Fuente Archivo Cantidad Confianza
1 Core embebidas malware_scanner.py (SIGNATURES[]) 70 regex Muy alta
2 Internas curadas signatures/internal_knowledge.json 6 Alta
3 Comunidad signatures/community.json 6 Media-Alta
4 IOC locales signatures/local_iocs.json 9 Variable
5 YARA nativas signatures/yara/*.yar 5 reglas Alta
6 YARA fallback signatures/yara_fallback.json 5 regex Media

Motor YARA (prioridad de backends)

  1. yara-x (Rust, Python ≥ 3.9) — preferido
  2. yara-python (clásico) — fallback
  3. Sin YARA — usa regex de yara_fallback.json

Entropía Shannon (implementada)

Entropía Puntos Interpretación
> 6.5 +50 Casi seguro cifrado/comprimido
5.8 – 6.5 +30 Probable ofuscación
5.2 – 5.8 +10 Moderadamente sospechoso
≤ 5.2 0 Normal

Solo se aplica si el archivo ya tiene ≥20pts por firmas (evita FP en datos aleatorios legítimos).

Análisis estructural (implementado)

Bonos dinámicos que el scanner agrega automáticamente:

Patrón Firma generada Puntos
≥10 gotos consecutivos STRUCT_GOTO_EXCESSIVE Variable
Línea > 5000 chars STRUCT_LONG_LINE Variable
base64 que decodifica a PHP STRUCT_B64_PHP_PAYLOAD Variable
≥8 funciones peligrosas distintas STRUCT_MANY_DANGEROUS_FUNCS Variable

Deducción de falsos positivos (implementada)

El scanner reduce automáticamente el score cuando detecta contextos legítimos:

Contexto Deducción Condición
WordPress core (wp-includes/, wp-admin/) -30pts Siempre
Plugins/temas con ≥50 líneas -15pts Siempre
Archivos test/debug/example/sample -10pts Por nombre
vendor/ o node_modules/ -40pts Siempre
Plugins FP conocidos (Guzzle, Wordfence, SimplePie, PHPMailer, AWS SDK) -50pts Sin firmas graves
Archivos .l10n.php (traducciones) -60pts Siempre
WP core labeled goto (html-api parser) -80pts Archivo específico
Solo HEX_STRING match (constante criptográfica) -70pts Única firma
Solo SUSPICIOUS_FILENAME -50pts Única firma
Solo LARGE_BASE64_STRING en archivo >100KB -70pts Única firma
index.php en uploads/ <100 bytes sin código peligroso -70pts Archivo específico

Extracción de PHP en ZIPs (implementada)

El scanner detecta archivos con magic bytes ZIP (PK\x03\x04), extrae cualquier archivo .php contenido y lo escanea contra todas las firmas. Agrega CONTAINER_ZIP_EMBEDDED_PHP (90pts).


Reconocimiento de Código Ofuscado

Técnicas de ofuscación detectadas por el scanner

Técnica Ejemplo Firma Score
Base64 largo eval(base64_decode("aWYoaX...")) OBFUSC_LARGE_BASE64_STRING 65
Hex strings "\x65\x76\x61\x6c" (≥20 escapes) OBFUSC_HEX_STRING 70
Char-index ("create_function")[0].("eval")[2]... OBFUSC_CHAR_INDEX_FUNCTIONS 80
Comment+Char-index /*\x00\x01*/("ab")[0]. combo OBFUSC_COMMENT_FUNC 85
Goto spaghetti goto a; b: ... goto c; a: ... (≥10) OBFUSC_GOTO_SPAGHETTI 70
URL decode alphabet urldecode("%65%76%61%6c") OBFUSC_URLDECODE_ALPHABET 80
Curly brace index $var{0}.$var{1}.$var{2} OBFUSC_CURLY_BRACE_CHARINDEX 75
GLOBALS hex $GLOBALS["\x00\x01"]["\x02"]() OBFUSC_GLOBALS_HEX_DISPATCH 90
PDF spoof %PDF-1.0 <?php eval(...) OBFUSC_PDF_HEADER_SPOOF 85
Noop camouflage Bloques de código muerto alrededor del payload OBFUSC_NOOP_CAMOUFLAGE Variable
Single-line packed Todo el código en una línea enorme OBFUSC_SINGLELINE_PACKED Variable
Eval anidado eval($var($var(...))) EVAL_NESTED_VAR_CALL 85
Junk variable padding Variables sin uso intercaladas OBFUSC_JUNK_VARIABLE_PADDING Variable
Variable function call $var = "eval"; $var(...) OBFUSC_VARIABLE_FUNCTION Variable
String split construct $a="ev"."al"; $a(...) OBFUSC_STR_SPLIT_CONSTRUCT Variable

Decodificación manual de payloads

Para investigar código ofuscado específico:

  1. Base64: echo "payload" | base64 -d
  2. Hex: echo -e "\x65\x76\x61\x6c" o php -r 'echo "\x65\x76\x61\x6c";'
  3. URL encode: php -r 'echo urldecode("%65%76%61%6c");'
  4. Anidado: Decodificar capa por capa, desde la más externa hacia adentro
  5. ZIP embebido: unzip -l archivo.php si tiene header PK

Gestión de Firmas

Agregar un nuevo IOC observado

Editar signatures/local_iocs.json:

{
  "name": "NOMBRE_DESCRIPTIVO_MAYUSCULAS",
  "pattern": "regex_del_patron",
  "score": 80,
  "description": "Descripción breve del comportamiento malicioso"
}

Guía de scoring:

  • 40-59: Sospechoso pero ambiguo (podría ser legítimo)
  • 60-79: Probablemente malicioso, requiere contexto
  • 80-89: Malware probable, limpieza automática activable (score ≥ AUTO_CLEAN_THRESHOLD)
  • 90-99: Malware confirmado, alta confianza

Umbrales configurados en el scanner:

  • SCORE_THRESHOLD = 60 — Puntuación mínima para reportar
  • AUTO_CLEAN_THRESHOLD = 80 — Para limpieza automática con --clean
  • MAX_FILE_SIZE = 5MB — Archivos más grandes se ignoran

Falsos Positivos Conocidos

Componentes legítimos que disparan firmas frecuentemente (el scanner ya aplica deducción automática para la mayoría):

Componente Firma disparada Razón Deducción automática
Guzzle HTTP BACKDOOR_HEX_ENCODED_CURL_FETCH cURL con opciones hex legítimas -50pts (KNOWN_FP_PLUGIN_PATHS)
Wordfence COMMUNITY_AUTO_PREPEND_BACKDOOR auto_prepend_file para WAF -50pts (plugin conocido)
wp-migrate-db OBFUSC_LARGE_BASE64_STRING Serializa datos en base64 -70pts si >100KB y es la única firma
Starter Templates STRUCT_LONG_LINE Inline CSS/JS genera líneas largas -15pts (plugin legítimo)
WP Rocket BACKDOOR_HEX_ENCODED_CURL_FETCH Código deprecated con patrones cURL -50pts
WP HTML Processor OBFUSC_GOTO_SPAGHETTI Usa goto legitimamente en parser -80pts (WP_CORE_LABELED_GOTO_FILES)
Google API Client Varias firmas cURL SDK legítimo -50pts (KNOWN_FP_PLUGIN_PATHS)
AWS SDK PHP BACKDOOR_HEX_ENCODED_CURL_FETCH HTTP client legítimo -50pts
SimplePie / PHPMailer Patrones de funciones peligrosas Uso legítimo de funciones PHP -50pts

Regla práctica: Si un archivo está en un plugin conocido (wp-content/plugins/[nombre-oficial]/) Y tiene score < 90 después de deducciones, probablemente es falso positivo.

Paths whitelisted en el scanner (KNOWN_FP_PLUGIN_PATHS):
/wp-mail-smtp, /vendor_prefixed/, /vendor/, /guzzlehttp/, /google/auth/, /google/apiclient/, /aws/aws-sdk-php/, /psr/log/, /symfony/polyfill, /SimplePie/, /PHPMailer/, /all-in-one-wp-migration/


Comandos de Referencia Rápida

# ── BACKUP ──
./wp_backup_db.sh /home                    # Backup de todas las BD
./wp_backup_db.sh /home/user/public_html   # Backup de un sitio

# ── TRIAGE RÁPIDO (grep, antes del scanner) ──
./malware_scan.sh                          # Firmas grep, PHP uploads, recientes, permisos 777
./wp_security_scan.sh                      # Cuarentena básica + diff WP core

# ── ESCANEO HEURÍSTICO ──
python3 malware_scanner.py --scan /home --no-quarantine --report both    # Solo reporte
python3 malware_scanner.py --scan /home/user/public_html --threshold 40  # Más sensible
python3 malware_scanner.py --scan /home --validate-wp --report both      # Con validación WP

# ── LIMPIEZA ──
python3 malware_scanner.py --scan /home --report both                    # Cuarentena
python3 malware_scanner.py --scan /home --clean --report both            # Auto-limpieza (3 patterns)
python3 malware_scanner.py --scan /home --disable --report both          # chmod 000 + .DISABLED

# ── RESTAURACIÓN ──
./wp_reemplaza.sh                          # Restaurar WordPress core (con backup previo)
./fix_permissions.sh --all                 # Restaurar permisos (todos los usuarios)
./fix_permissions.sh --dry-run --all       # Simular sin cambios
./fix_permissions.sh -u juan -u pedro      # Solo usuarios específicos

Estructura del Proyecto

Componente Rol Líneas/Tamaño
malware_scanner.py Motor principal: 6 capas, scoring, entropía, ZIP, reportes, cuarentena, clean, disable, validate-wp ~1300 líneas Python
signatures/internal_knowledge.json 6 firmas internas de alta confianza (incidentes reales) JSON
signatures/community.json 6 firmas comunitarias (ZIP dropper, cookie exec, auto_prepend) JSON
signatures/local_iocs.json 9 IOC locales observados (volovot.ru, fire2013, charindex) JSON
signatures/yara_fallback.json 5 regex fallback cuando YARA no está disponible JSON
signatures/yara/php_webshells_curated.yar 5 reglas YARA curadas YARA
wp_backup_db.sh Backup BD MySQL: autodescubre wp-config, dump+gzip, lock, logs Bash
wp_reemplaza.sh Restauración WP core: backup BD+core, rsync, permisos, detección versión Bash
fix_permissions.sh Permisos: 755/644/600/711/750, dry-run, verbose, por usuario, CWP/cPanel Bash
malware_scan.sh Triage rápido: grep firmas, PHP uploads, recientes, nombres, permisos 777 Bash
wp_security_scan.sh Cuarentena básica: mueve sospechosos, diff WP core, archivos recientes Bash
wp_db_scan.sh Escaneo BD: inyecciones wp_options, SEO spam wp_posts, admins maliciosos, transients Bash
cron_check.sh Detección crontabs maliciosos: wget/curl reinstalación, 16 patrones, --fix Bash
remediate.sh Orquestador pipeline: 7 fases backup→scan→db→cron→clean→restore→verify→permisos Bash
malware_refs/ Muestras de referencia (archive.php, index.php) para testing PHP
logs/ Output de escaneos: JSON, texto, scripts rm Generado

Mejoras Pendientes (Roadmap)

v1.2.0 — Completadas

Mejora Impacto Estado
Ampliar CLEAN_PATTERNS para inyecciones prepend/append genéricas Alto ✅ Implementado
Flag --verify para re-escaneo automático post-limpieza Medio ✅ Implementado
Procesamiento paralelo (concurrent.futures) Alto ✅ Implementado
Base de hashes oficiales WP core (KNOWN_GOOD_HASHES) Medio ✅ Implementado
Descarga automática de WP limpio desde wordpress.org Bajo ✅ Implementado
Validación de magic bytes vs extensión (MIME mismatch) Medio ✅ Implementado

v1.3.0 — Prioridad Alta

# Mejora Impacto Estado
1 Escaneo BD WordPresswp_db_scan.sh: detectar inyecciones en wp_options (siteurl/home), SEO spam/iframes en wp_posts, usuarios admin maliciosos, transients sospechosos Alto ✅ Implementado
2 Análisis .htaccess maliciosos — detectar redirecciones condicionales (User-Agent/referer spam), php_value auto_prepend_file, ErrorDocument 404 a scripts maliciosos Alto ✅ Implementado
3 Detección crontabs maliciosos — escanear crontab -l -u $user, /var/spool/cron/, /etc/cron.d/ buscando wget/curl de reinstalación Alto ✅ Implementado
4 Orquestador pipelineremediate.sh: encadena backup→scan→classify→clean→restore→verify→permissions en un solo comando Alto ✅ Implementado

v1.4.0 — Prioridad Media

# Mejora Impacto Estado
5 Reporte HTML cliente — resumen ejecutivo, gráficas de severidad, lista de acciones tomadas Medio — comunicación al cliente 🔲 Pendiente
6 Test suite automatizado — pytest contra malware_refs/ + archivos limpios, validar firmas y FP Medio — evitar regresiones 🔲 Pendiente
7 Notificaciones — email/webhook cuando escaneo programado detecta malware nuevo Medio — monitoreo periódico 🔲 Pendiente
8 Rotación credenciales — regenerar salts wp-config.php, forzar password reset admins, rotar MySQL Medio — post-brecha obligatorio 🔲 Pendiente
9 Historial SQLite — persistir hallazgos, tendencias, reinfecciones recurrentes por servidor Medio — análisis longitudinal 🔲 Pendiente

v1.5.0 — Prioridad Baja

# Mejora Impacto Estado
10 Escaneo plugins/temas vulnerables — comparar versiones vs API WPScan/Wordfence CVEs Bajo — vector de reinfección 🔲 Pendiente
11 Modo watch (inotify) — monitoreo en tiempo real de cambios filesystem post-limpieza Bajo — daemon temporal 🔲 Pendiente
12 Integración ClamAV — complementar con detección de binarios/malware no-PHP Bajo — complementario 🔲 Pendiente

Anti-Patrones (NO hacer)

  • NO ejecutar --clean en la primera pasada sin revisar hallazgos
  • NO eliminar archivos sin backup de BD previo (wp_backup_db.sh primero)
  • NO confiar ciegamente en scan_*.rm_ALL.txt — revisar falsos positivos antes
  • NO ignorar hallazgos SUSPICIOUS — podrían ser malware sofisticado con baja firma
  • NO restaurar WP core sin verificar la versión correcta del sitio (el script advierte mismatch)
  • NO olvidar re-escanear después de la limpieza
  • NO dejar permisos 777 después de la remediación (fix_permissions.sh --all)
  • NO ejecutar wp_reemplaza.sh sin confirmar que la copia limpia existe en /home_D0/fixes/wordpress/