Cómo encontrar puertas traseras ocultas en WordPress con WP-CLI y SQL
2026년 7월 30일
0
Internet TechnologyComments (0)
Log in to leave a comment
No posts yet
Log in to leave a comment
No posts yet
Hacer clic en el botón de actualización del núcleo en un sitio de WordPress desarrollado por terceros da bastante reparo. Si lo pospones por miedo a que el tema o los plugins personalizados se rompan y la pantalla se quede en blanco, tu sitio terminará lleno de vulnerabilidades en un abrir y cerrar de ojos. Cuando te asalta la paranoia de que ya te han pirateado, este es el procedimiento de inspección práctica más rápido para auditar la base de datos y el servidor.
Los atacantes suelen entrar sin hacer ruido. Modifican directamente la tabla wp_usermeta de la base de datos para otorgar sigilosamente permisos de administrador a una cuenta existente. Esto no suele verse a simple vista en la lista general de usuarios, pero salta inmediatamente al consultar la base de datos.
`sql
SELECT
u.ID,
u.user_login,
u.user_email,
u.user_registered,
m.meta_value AS capabilities
FROM
wp_users u
INNER JOIN
wp_usermeta m ON u.ID = m.user_id
WHERE
m.meta_key = 'wp_capabilities'
AND (
m.meta_value LIKE '%"administrator"%'
OR m.meta_value LIKE '%"administrator":true%'
)
ORDER BY
u.user_registered DESC;
`
El siguiente paso es el sistema de archivos. Si hay archivos PHP rondando en el directorio wp-content/uploads, donde solo debería haber imágenes o documentos, lo más probable es que se trate de una puerta trasera. Abre una terminal SSH y rastrea si hay archivos peligrosos.
`bash
find wp-content/uploads/ -type f -name "*.php" -ls
find . -type f -name "*.php" -exec grep -HnE "(eval(|base64_decode(|gzinflate(|passthru(|shell_exec()" {} ;
wp core verify-checksums --include-root
`
También hay que revisar los registros. Los ataques dirigidos a la API REST suelen enviar una ráfaga de peticiones POST en poco tiempo para obtener respuestas 200 o 201. Extrae en el archivo access.log de Nginx las peticiones que hayan mostrado un comportamiento sospechoso.
`bash
grep -E "POST|PUT" /var/log/nginx/access.log | grep -E "/wp-json/|rest_route=" | awk '/ {print $1, $4, $6, $7, $9}' | sort | uniq -c | sort -nr | head -n 30
`
Aplicar parches directamente en el sitio en producción no es valentía, es casi una imprudencia. Crea primero un entorno de staging duplicando la base de datos y el sistema de archivos al completo.
`bash
wp db export production_backup.sql --add-drop-table
rsync -avz --exclude='wp-content/cache' /var/www/html/ staging:/var/www/staging/
wp db import production_backup.sql
wp search-replace 'https://example.com' 'https://staging.example.com' --skip-columns=guid
wp plugin list --update=available --fields=name,version,update_version,requires_php --format=table
`
Una vez terminada la duplicación, ejecuta la actualización y prueba manualmente las funciones principales durante al menos 5 minutos. Te quedarás más tranquilo si verificas personalmente el registro de usuarios, el inicio de sesión, la cesta de la compra, la pasarela de pago y el envío de formularios de contacto.
Hay situaciones frustrantes en las que no puedes actualizar el núcleo porque el desarrollador de un plugin no ha lanzado una actualización. En esos casos, debes ganar tiempo bloqueando el acceso a rutas específicas a nivel de servidor o WAF. Si usas Nginx, bloquea en el archivo nginx.conf los endpoints de creación de usuarios y procesamiento por lotes de la API REST para todas las IP excepto la tuya.
`nginx
location ~* ^/wp-json/(batch/v1|wp/v2/users) {
limit_except GET {
allow 192.0.2.1;
deny all;
}
try_files $uri args;
}
`
Por si acaso ocurre algo imprevisto, añade de paso un script de copia de seguridad que suba la base de datos y la carpeta de subidas a S3.
`bash
#!/bin/bash
WP_PATH="/var/www/html"
BACKUP_DIR="/tmp/wp_backups"
DATE=$(date +%Y%m%d_%H%M%S)
S3_BUCKET="s3://my-wordpress-secure-backups"
mkdir -p $BACKUP_DIR
wp db export BACKUP_DIR/db_DATE.sql --path=$WP_PATH --quiet
tar -czf BACKUP_DIR/files_DATE.tar.gz -C $WP_PATH wp-content/uploads/
aws s3 cp BACKUP_DIR/db_DATE.sql S3_BUCKET/db_DATE.sql
aws s3 cp BACKUP_DIR/files_DATE.tar.gz S3_BUCKET/files_DATE.tar.gz
find $BACKUP_DIR -type f -mtime +7 -delete
`
Eliminar el código malicioso y aplicar los parches de seguridad no es el final de la historia. El atacante podría volver a entrar usando las cookies de sesión robadas. Destruye las sesiones existentes y renueva todas las claves Salt en wp-config.php.
`bash
wp user list --field=ID | xargs -n 1 wp user session destroy --all
wp config shuffle-salts
`
Desactiva también la función que permite editar archivos de temas o plugins directamente desde el panel de administración. Es un mecanismo de seguridad mínimo para evitar que el atacante inyecte código aun si consigue permisos. Añade estas dos líneas a wp-config.php:
`php
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', true );
`
Por último, para evitar que los usuarios no autenticados espíen la lista de usuarios a través de la API REST, añade un filtro dedicado en el directorio mu-plugins.
`php
<?php
/**
`