SQLi a través xPath

Explotando inyecciones SQL basadas en error a través de funciones de xPath.

Se añade una comilla simple (para probar si existe inyección SQL), el carácter más común para inyecciones de este tipo.

identificando una inyección SQL

El servidor responde con un error visible no controlado.

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '''' ORDER BY fecha DESC' at line 1

error no controlado mostrado en la página web

Esto ocurre porque no se ha parametrizado la consulta en BBDD y posteriormente no se ha capturado el error en el servidor backend.

Hasta aqui todo claro. Identificada la inyección SQL toca validar si se pueda explotar.

Una manera también común es ir sacando el número de columnas de la consulta actual.

sacando el número de columnas de la consulta original

Tomando el número de columnas descubierto, 9 en este caso, se van a usar para crear una nueva consulta anidada a traves de un union. Gracias a está nueva consulta se conseguirá tener el control para realizar las llamadas que se quiera a la BBDD.

anidando una nueva consulta a la original

Sin embargo se recibe una respuesta 403 Forbidden. En caso de seguir intentado ya sea ofuscando/codificando caracteres lo siguiente será un bloqueo.

Imunify360 bloquea las peticiones

Aunque hasta de un bloqueo se puede sacar información. Y se observa que se usa Imunify360 como protección WAF.

Sabiendo la tecnología usada, se podría intentar buscar métodos específicos de bypass. Con una busqueda rapida salen múltiples resultados, como por ejemplo:

Inyección SQL por ahmetumitbayrm

Pero nada funciona. Y por mucha ofuscación o codificación de caracteres el WAF se habrá actualizado desde el pasado 2020.

Como todo en está dirección se está complicando o falla es buen momento de cambiar y buscar una via alternativa que el WAF Imunify360 no se espere.

Hace tiempo leí una manera de explotación cuando se tiene un error no controlado en el lado del cliente. La idea era controlar el mensaje del error. Es decir tener la capacidad de decidir que datos mostrar en la traza.

Y aqui entra en juego XML Path Language (XPath). Mas información sobre que es XPath.

Definición xPath

Es un lenguaje originalmente construido para realizar búsquedas y encontrar elementos en un XML. Posteriormente fue introducido también en SQL para recuperar datos de una base de datos.

XPath fue implementado en MySQL a partir de la version 5.1. De todas las funciones la interesante para este caso es ExtractValue(), porque permite leer desde un XML y devolver el atributo que se quiera.

ExtractValue(xml_frag, xpath_expr) recibe como primer parametro xml_frag que será el nombre del atributo y como segundo parametro xpath_expr que será una expresión XPath.

ExtractValue -> Imagen tomada del post Nairuz Abulhul. Original post: Peter Wood

Entendido el funcionamiento, toca validar si funciona. Pero cuidado, no hay que usar la función ExtractValue de manera correcta, si no hacer que falle para producir un nuevo mensaje de error “controlado” por nosotros.

Para entender mejor está parte voy hacer unas pruebas en local simulando la explotación.

probando previamente en local la inyección original

El error generado de la segunda consulta es el que NO se puede controlar. Asi que se introduce ExtractValue, en el parametro xml_frag vamos a buscar un atributo = una columna QUE NO EXISTE, por ejemplo una columna llamada punto y coma ‘ ; ‘ y en xpath_expr se usará una función MySQL. De está manera cuando la consulta SQL falle al buscar el atributo ‘ ; ‘ se va a ejecutar la función.

probando previamente en local la inyección XPath

0x3b es la representación en hexadecimal del punto y coma. La inyección XPath funciona, pero no del todo. ¿Qué hay raro? Parece que no se observa todo el output que se esperaba. El usuario es root@localhost y no únicamente @localhost.

Esto ocurre porque las funciones en XPath tienen una limitación de caracteres. Por tanto para poder visualizar todo el output se tiene que concatenar multiples funciones a la vez.

solucionando en local la limitación de caracteres de XPath

Se prueba ahora la inyección XPath en la web

noticia'+and+extractvalue(0x3b,+concat(0x3b,current_user()));--+-

inyección XPath

Se prueba a leer la primera tabla de la BBDD

noticia'+and+extractvalue(0x3b,+concat(0x3b,+(select+concat (0x3b,table_name)+from+infromation_schema.tables+where+table_schema= 'dbXXXXrod'+limit+0,1)));--+-

inyección XPath II

Esto se podría ahora automatizar y filtrar la BBDD entera.

El reporte que lei hace tiempo y me ayudo para está explotación es:

https://medium.com/r3d-buck3t/error-based-xpath-sql-injection-in-openemr-2abbc0379ac5

%27