Durante los análisis de infraestructura que realizamos en organizaciones de Jujuy y Salta, encontramos un patrón que se repitió en múltiples sitios: xmlrpc.php activo, sin restricciones, con decenas de métodos expuestos públicamente. No como excepción — como norma.

Este artículo explica qué es este endpoint, por qué existe, qué permite hacer a un atacante, y cómo deshabilitarlo en menos de cinco minutos.

01 / ¿Qué es xmlrpc.php?

XML-RPC es un protocolo de llamada a procedimientos remotos que usa XML como formato y HTTP como transporte. WordPress lo implementó en 2002 para permitir que aplicaciones externas — clientes de escritorio, apps móviles, servicios de publicación — interactuaran con el sitio sin usar la interfaz web.

El problema es que WordPress lo habilitó por defecto. Y aunque hoy la mayoría de esos casos de uso están cubiertos por la REST API moderna, xmlrpc.php sigue activo en instalaciones por defecto. Si no lo deshabilitaste explícitamente, está disponible.

// Contexto

WordPress representa aproximadamente el 43% de todos los sitios web del mundo. Si el 80% de esas instalaciones tiene xmlrpc.php activo, estamos hablando de cientos de millones de endpoints expuestos globalmente.

02 / Cómo verificarlo

La verificación es trivial. Un simple POST al endpoint devuelve la lista completa de métodos disponibles:

// detección — curl
$ curl -s -X POST https://target.com/xmlrpc.php \
  -H "Content-Type: text/xml" \
  -d '<methodCall>
    <methodName>system.listMethods</methodName>
    <params></params>
  </methodCall>'

# Si el endpoint está activo, la respuesta incluirá algo como:
<value><string>system.listMethods</string></value>
<value><string>wp.getUsersBlogs</string></value>
<value><string>wp.getUsers</string></value>
<value><string>system.multicall</string></value>
# ... hasta 80+ métodos

Si obtenés una respuesta XML con una lista de métodos, el endpoint está completamente funcional. Si recibís un 403 o el archivo no existe, estás protegido.

03 / Los vectores de ataque

Fuerza bruta amplificada via system.multicall

El método system.multicall permite ejecutar múltiples llamadas en una sola petición HTTP. Esto convierte un ataque de fuerza bruta estándar en algo mucho más eficiente: en lugar de hacer 1000 requests para probar 1000 contraseñas, podés hacer 10 requests con 100 intentos cada uno.

// fuerza bruta via multicall
# Cada request puede contener N intentos de login
$ cat multicall_payload.xml
<methodCall>
  <methodName>system.multicall</methodName>
  <params><param><value><array><data>
    <value><struct>
      <member><name>methodName</name>
              <value>wp.getUsersBlogs</value></member>
      <member><name>params</name>
              <value><array><data>
                <value>admin</value>
                <value>password123</value>
              </data></array></value></member>
    </struct></value>
    <!-- repetir N veces con distintas passwords -->
  </data></array></value></param>
</params>
</methodCall>

[!] 1 HTTP request = N intentos de login = bypassea rate limiting estándar
// Impacto

Los plugins de seguridad que limitan intentos de login (Wordfence, Limit Login Attempts) por lo general operan a nivel de wp-login.php — no interceptan las llamadas a xmlrpc.php. El rate limiting estándar no aplica.

Enumeración de usuarios

Sin necesidad de credenciales, es posible obtener el listado de usuarios del sitio:

// enumeración sin credenciales
$ curl -s -X POST https://target.com/xmlrpc.php \
  -d '<methodCall>
    <methodName>wp.getAuthors</methodName>
    <params>
      <param><value><int>1</int></value></param>
      <param><value><string></string></value></param>
      <param><value><string></string></value></param>
    </params>
  </methodCall>'

[!] Respuesta incluye: user_login, display_name, user_id
[+] adminvilla (ID: 1) — encontrado sin autenticación

Pingback como vector de DDoS y SSRF

El método pingback.ping permite enviar pingbacks a cualquier URL. Esto tiene dos implicancias: el sitio puede ser usado como amplificador en ataques DDoS dirigidos a terceros, y puede usarse para explorar servicios internos de la red (Server-Side Request Forgery).

04 / Lo que encontramos en la región

Durante nuestros análisis de infraestructura en Jujuy y Salta, identificamos xmlrpc.php activo y completamente funcional en múltiples organizaciones — medios de comunicación, empresas de servicios, instituciones de salud. En todos los casos el endpoint respondía a system.listMethods con más de 80 métodos disponibles.

// output real — identificación
$ ./xmlrpc_check.sh target-regional.com.ar

[+] Endpoint accesible: HTTP 200
[!] system.listMethods: 83 métodos expuestos
[!] system.multicall: disponible
[!] wp.getUsers: disponible sin auth
[✗] Fuerza bruta amplificada: posible
[✗] Enumeración de usuarios: confirmada

# Usuarios identificados sin credenciales:
[+] admin (ID: 1)
[+] editor (ID: 2)
[+] redaccion (ID: 3)

Notificamos a cada organización con los hallazgos específicos y los pasos para resolverlo. Este artículo es la versión pública de esa misma información.

05 / Cómo cerrarlo

Opción A — Plugin (sin tocar código)

La forma más simple si no tenés acceso al servidor. El plugin Disable XML-RPC (gratuito, +100.000 instalaciones activas) deshabilita el endpoint con un click.

// via WP-CLI
$ wp plugin install disable-xml-rpc --activate

Opción B — .htaccess (Apache)

// .htaccess — bloqueo total
# Bloquear acceso a xmlrpc.php
<Files xmlrpc.php>
  Order Deny,Allow
  Deny from all
</Files>

Opción C — nginx

// nginx.conf
location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}

Verificación post-cierre

// confirmar que está bloqueado
$ curl -s -o /dev/null -w "%{http_code}" \
  -X POST https://tu-sitio.com/xmlrpc.php

403  # correcto — acceso denegado
200  # todavía vulnerable
404  # correcto — archivo no existe
// Resultado esperado

Después de aplicar cualquiera de las tres opciones, el endpoint debe devolver 403 o 404. Si sigue devolviendo 200, el bloqueo no está aplicado correctamente.

06 / Conclusión

xmlrpc.php es un vector de ataque conocido desde hace más de una década. No es una vulnerabilidad nueva ni sofisticada — es infraestructura heredada que nadie deshabilitó porque nadie sabía que existía.

Si tenés un sitio WordPress, tomá 5 minutos para verificar si está activo. El comando curl de arriba tarda menos de 10 segundos. Si devuelve 200, usá cualquiera de las tres opciones de cierre.

Si tenés dudas o querés que revisemos tu infraestructura sin costo, podés escribirnos desde la página principal.

¿Querés saber qué más tiene expuesto tu infraestructura?

Hacemos una revisión inicial sin costo. Sin compromiso. Solo hallazgos reales.

Solicitar evaluación gratuita →