AJAX, LA DEBILIDAD DE WORDPRESS

Categorías: ,
Etiquetas: , , ,

Quiero comenzar aclarando que ni soy “experto” ni soy “hacker”. Prefiero presentarme/sentirme así para evitar malos entendidos. No me gusta la actitud de cientos de superhackers expertos en todo que aparecen de debajo de las piedras, no busco fama ni reconocimiento, sólo busco aprender, divertirme y aportar lo que pueda. No estoy en la onda de crear ni siquiera usar superaplicaciones automáticas que “descubren” y/o “explotan” supuestas vulnerabilidades en WordPress y sus plugins, de hecho, las pocas que he probado, no dan más que falsos positivos.

Me presento, quienes me conocen ya saben mi nombre, para los demás, con Hackpintero ya os vale, JAJAJAJA…

cerrajeria lockpicking

No en serio, soy un simple Carpintero de Pamplona, Navarra,  ahora dedicado al mundo de la cerrajería. Amante de la seguridad informática por el placer de aprender cómo funcionan las cosas y por las grandes personas que conoces en el camino. No he estudiado nada relacionado con la informática, todo ha sido a base de horas y tutoriales, prueba y error y mucho mucho café.

Quien quiera saber más, podrá encontrarme en Twitter como @MikelGorraiz ( https://twitter.com/mikelgorraiz )

Dicho esto, comenzamos el post con un poco de teoría para comprender este método de ataque, o más bien este método para encontrar vulnerabilidades a través del código fuente.

WordPress es uno de los CMS más extendidos, sino el que más, por ello es al que más se intenta vulnerar. Por suerte, el código de WordPress es muy robusto (hay un gran equipo de profesionales dedicados a ello de forma silenciosa) y casi todo lo que se encuentra son fallos en los “plugins” de empresas externas ajenas a WordPress.

Estos “plugins” o complementos, se utilizan para ampliar las funcionalidades primarias de WordPress o para añadir funcionalidades que no existen “de serie”.

Voy a dar por sentado, que los lectores de éste post tienen un mínimo de conocimientos en programación PHP y algo de MySQL, ambos imprescindibles puesto que es la base de todo WordPress. Si no es así, os recomiendo que leáis un poco sobre el tema antes de seguir con el post, de lo contrario os será difícil de comprender en su totalidad. También os recomiendo que para las prácticas tengáis instalado en vuestro “localhost” una versión de WordPress, configurada y funcionando.

Un poco de teoría

Vamos a repasar cómo utiliza WordPress la función AJAX, tanto en su método privado como en su metodo publico. Para esto vamos a abrir y leer el código fuente del archivo “admin-ajax.php” que se encuentra en la carpeta “wp-admin”.

Como podemos ver, en la línea 31 tenemos el primer “filtro” el cual, si el archivo al ser llamado no recibe un “$_REQUEST[‘action’];”, responderá con un código HTTP 400 Bad Request imprimiendo un 0 en la pantalla del navegador:

400-bad-request - WordPress vulnerabilidad

Para utilizar AJAX en WordPress, debemos enviarle una petición REQUEST llamada “action” con un valor determinado, que un poco más adelante explicaré, ya que es parte fundamental  en esto.

Algo más abajo, es donde WordPress registra éstas acciones para poder ser llamadas, dando dos métodos diferentes, uno privado y otro público.

priv-y-nopriv - WordPress vulnerabilidad

Método privado

El método privado se usa en wordpress sólo cuando quien hace la petición está logueado en el CMS, creando la acción ‘wp_ajax_’, que es comprobado por la función “is_user_logged_in()” y que generará la misma respuesta  HTTP 400 Bad Request como anteriormente si no estamos logueados o disponemos de una cookie de usuario. Decir que esta función, no comprueba, para nada, los privilegios de dicho usuario y cualquiera que sea el usuario podría ejecutarla sin necesidad de ser un administrador.

Método público

Este es mi favorito, el que más interesa y el que mejores ratos me ha hecho pasar, ya que es una acción que crea, ‘wp_ajax_nopriv_’, para poder utilizarse sin necesidad de estar logueado, lo que quiere decir que es una acción remota sin autenticar.

nopriv - WordPress vulnerabilidad

Para que me vayáis entendiendo, vamos a generar una consulta remota en nuestro WordPress con este método, que sólo se utiliza internamente dentro del CMS pero que nos ayudará a comprender un poco el tema al que vamos.

Vamos a enviarle por GET un “action”, ya que el script ‘admin-ajax.php’ nos pide un REQUEST, llamado “heartbeat”.

Heartbeat es una función interna de WordPress que solo se utiliza por el CMS para generar una especie de pulso y poder obtener información periódica del servidor.

heartbeat - WordPress vulnerabilidad

Como podéis ver, el servidor al recibir el “action”, ya no responde con un 400, sino que lo hace con un JSON. Esto quiere decir que hemos generado una consulta AJAX válida y hemos ejecutado una función de WordPress.

Os estaréis preguntando que para qué explico esto, pero seguir leyendo que pronto lo entenderéis.

Para los que aún no sepáis por dónde voy, el resumen es que, si encontramos una función que es llamada mediante el AJAX de WordPress, podremos ejecutarla a nuestro gusto remotamente. Por lo que si encontramos dicha función y por ejemplo, esa función fuese vulnerable a, digamos una SQLInjection, podríamos obtener los datos de la DB de WordPress pues tendríamos un “Ejecución de sentencias SQL Remota”.

Una vez explicada parte de la teoría, voy a comenzar con la práctica y como éste es mi primer post dedicado al tema de la seguridad informática, quiero empezar a lo grande.

Empieza lo bueno

Voy a hacer las prácticas con un “plugin” de código libre al que, por éste método, vamos a buscar, encontrar y explotar una vulnerabilidad de ejecución de código remoto o en términos más simples, un RCE como una casa de grande.

Quadmenu Mega Menu - WordPress vulnerabilidad

El plugin en concreto se llama “Quadmenu Mega Menu”. A la hora de escribir éste post se encuentra en su versión 2.0.6. Esta vulnerabilidad la encontré en la versión 1.8.2 aunque a día de hoy ahí sigue.

Una vez instalado en nuestro servidor local, empezamos con el concierto …

Para encontrar vulnerabilidades de éste tipo, lo primero que debemos hacer es buscar, en el código fuente del “plugin”, todas y cada una de las llamadas al AJAX que se hacen desde él. Lo haremos buscando por texto todas las referencias a “wp_ajax_nopriv”.

Decir que yo sólo suelo buscar las NOPRIV ya que son las vulnerabilidades de ejecución remota SIN PRIVILEGIOS pero, siendo un usuario autenticado, podríamos ejecutar las que son privadas del mismo modo.

En el caso que nos ocupa, el plugin “Quadmenu” tiene actualmente 9 entradas con llamadas al AJAX de WordPress con funciones públicas:

add_action( "wp_ajax_nopriv_redux_p", array( $this, 'proxy' ) );
add_action( "wp_ajax_nopriv_redux_link_options-" . $this→parent→args['opt_name'] …
add_action( "wp_ajax_nopriv_redux_download_options-" . $this→parent→args['opt_ …
add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'tracking_arg' ) );
add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'support_args' ) );
add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'tracking_arg' ) );
add_action( 'wp_ajax_nopriv_' . $hash, array( $this, 'support_args' ) );
add_action('wp_ajax_nopriv_ajax_quadmenu_divi_module', array($this, 'ajax_quad …
add_action('wp_ajax_nopriv_quadmenu_compiler_save', array($this, 'compiler_save'));

Si nos fijamos bien, hay una que llama la atención al primer vistazo, ya que sólo por el nombre que le dan, nos encamina hacia nuestro objetivo, que sería buscar algo que comprometa el sistema.

¿Aún no lo veis? Me refiero a la última llamada, la que nos deja entrever que ¡podemos compilar algo!

add_action('wp_ajax_nopriv_quadmenu_compiler_save', array($this, 'compiler_save'));

Se trata de la función ‘compiler_save’ a la que vamos a localizar y revisar más detenidamente.

La podremos localizar en el archivo PHP:
“/wordpress/wp-content/plugins/quadmenu/includes/compiler.php”

compiler-save-quadmenu - WordPress vulnerabilidad

Analicemos la función detenidamente para ver de qué se trata.

A simple vista, vemos que se trata de una función que recibe ciertos parámetros para poder generar o editar archivos CSS.

Buscando un poco de información sobre ésta función en la página web del autor, llegamos a la conclusión de que se utiliza para editar o crear CSS desde el panel de administración del plugin.

quadmenu-customize - WordPress vulnerabilidad

Esto nos indica que vamos por el buen camino ya que podremos ejecutar una función interna del plugin a la que no deberíamos tener acceso.

Veamos un poco el código a ver si encontramos la forma de explotarlo.

Wordpress vulnerabilidad - compiler_save_1

En la línea 93 nos encontramos con el primer y gran problema, la función de comprobación “check_ajax_referer(‘quadmenu’,’nonce’,false) que recibe un parámetro llamado “nonce” con el cual, de no tenerlo, nos tira un Please reload page y no nos deja continuar.

Voy a enviar una petición POST y veamos el resultado:

http://localhost/wordpress/wp-admin/admin-ajax.php

POST:

action=quadmenu_compiler_save
Wordpress vulnerabilidad - compiler_save_2

Llegados a este punto, la gran mayoría de “researchers” desistiría y lo daría por imposible. Pues yo que soy tan cabezón, continúo y eso me permite seguir con el post.

Vamos a imaginar que por algún casual, hemos obtenido el NONCE en cuestión que necesitamos y que, al final de éste post, os diré cómo obtener!

Generamos la consulta y ahora sí, la respuesta ya es otra.

http://localhost/wordpress/wp-admin/admin-ajax.php

POST:

action=quadmenu_compiler_save&nonce=ca0ce20378
Wordpress vulnerabilidad - compiler_save_3

Ya no da error sino que muestra una pantalla en blanco, lo que quiere decir que el nonce es correcto y continúa ejecutando el script. Pero, ¿por qué no muestra nada?, pues porque si seguimos analizando el script, nos pide más parámetros que aún no le hemos mandado. Tenéis que daros cuenta que estamos haciendo las pruebas conforme vamos avanzando sobre el script y que nos irá mostrando o ejecutando cosas según le vayamos enviando parámetros hasta llegar a lo que nos interesa.

Wordpress vulnerabilidad - compiler_save_4

Un poco más adelante, en la línea 99, tenemos nuestra siguiente parada, nos pide un parámetro Array “$_REQUEST[‘output’][‘imports’][0]”  que utiliza en la línea 112 la función “save_file” para generar un nombre de archivo.

Wordpress vulnerabilidad - compiler_save_5

Podemos ver en el código que la función “save_file” recibe 3 parámetros, $name, $dir y $content, y su ejecución final, si todo sale bien, genera o actualiza un archivo llamado “$name” en el directorio “$dir” con el contenido “$content”.

Wordpress vulnerabilidad - compiler_save_6

Pues vamos a darle un nombre de archivo quedando la consulta así:

http://localhost/wordpress/wp-admin/admin-ajax.php

POST:

action=quadmenu_compiler_save&nonce=ca0ce20378&output[imports][0]=archivonuevo.css

En la línea 104 nos pide otro parámetro, “$_REQUEST[‘output’][‘css’]” que también se utiliza en la función “save_file” llamada en la línea 112. Ya podréis adivinar, por el nombre del parámetro, de que se trata, es del código “CSS” que queremos generar, quedando la consulta algo así:

http://localhost/wordpress/wp-admin/admin-ajax.php

POST:

action=quadmenu_compiler_save&nonce=ca0ce20378&output[imports][0]=archivonuevo.css&output[css]=.prueba{color:black}

El tercer parámetro que nos faltaría sería “$dir” que es el directorio donde se va a crear nuestro archivo, pero si os fijáis en la línea 112, ese parámetro nos lo da directamente el plugin insertando el directorio por defecto “QUADMENU_UPLOAD_DIR”. Con todo esto tendríamos nuestra consulta completa y solo nos queda ejecutarla.

Wordpress vulnerabilidad - compiler_save_7

¡¡BOOM!! … Por lo que se ve, hemos generado un archivo en:

/var/www/html/wordpress/wp-content/uploads/twentytwenty/archivonuevo.css

Vamos a ver:

Wordpress vulnerabilidad - compiler_save_8
Wordpress vulnerabilidad - compiler_save_9

Hemos generado un archivo CSS en el que hemos incrustado nuestro código. Pero, ¿qué pasaría si en vez de crear un CSS creamos un archivo PHP con comandos? … Pues vamos a probar con un simple PHPINFO que, logrando eso, todos sabemos a qué se puede llegar, podríamos generar una webshell y controlar todo WordPress.

Probemos:

Wordpress vulnerabilidad - compiler_save_10
Wordpress vulnerabilidad - compiler_save_11

Y como dicen los franceses … “Et voilà”

Wordpress vulnerabilidad - compiler_save_12

Mediante éste método hemos conseguido crear un archivo PHP y ejecutar la función phpinfo(), a partir de aquí, cada uno es libre de probar su funcionalidad y lo que se puede lograr hacer con ésta vulnerabilidad.

Hasta aquí ha llegado mi primer post, creado para este gran congreso y asociación que tantas noches de diversión me han generado.

Un fuerte abrazo a todos y no dejéis de leer el blog, pronto escribiré más vulnerabilidades….. Un momento…. Pensabais que me había olvidado ese nonce… peroooo….

A buen entendedor, pocas palabras bastan y si aun viendo la siguiente imagen tienes dudas, estoy en redes sociales para contestarlas.

Wordpress vulnerabilidad - compiler_save_13

Remediación: 

Como hemos podido ver en el artículo, el “nonce” utilizado en el ejemplo es el mismo para todas las funciones AJAX y éste se puede localizar en el código fuente.

Esta vulnerabilidad que acabamos de explicar se podría solventar por parte de los programadores si se filtrara el nombre del archivo a crear, sólo dejara crearlo desde el backend y con extensión controlada, .css, .js . combinado con crear un “nonce” diferente por cada función AJAX y dicho “nonce” no es visible en el código fuente. La importancia de filtrar las funciones aún siendo internas es muy importante.

Happy Hacking!!!!!

Firmado: @MikelGorraiz

La imagen de cabecera se ha compuesto con una foto cortesía de Pixabay

Sh3llCON no se hace responsable de las opiniones vertidas por sus colaboradores ni por las actuaciones que, fruto del conocimiento transmitido, puedan realizar terceras personas.

Todo lo que se publica en este post es con fines lúdicos y/o educativos.
En ningún caso debe usarse el conocimiento para causar daños a terceros.