Inyección de SQL Server: ¿cuánto daño en 26 caracteres?

21

Estoy probando la resistencia contra ataques de inyección en una base de datos de SQL Server.

Todos los nombres de tablas en la base de datos son minúsculas y la intercalación distingue entre mayúsculas y minúsculas, Latin1_General_CS_AS .

La cadena que puedo enviar se fuerza a mayúsculas y puede tener un máximo de 26 caracteres de longitud. Por lo tanto, no puedo enviar una TABLA DE GOTAS porque el nombre de la tabla estaría en mayúsculas y, por lo tanto, la declaración fallará debido a la intercalación.

Entonces, ¿cuál es el daño máximo que podría hacer en 26 caracteres?

EDITAR

Sé todo sobre consultas parametrizadas, etc., imaginemos que la persona que desarrolló el front-end que construye la consulta para enviar no utilizó parámetros en este caso.

Tampoco estoy tratando de hacer nada nefasto, este es un sistema construido por alguien más en la misma organización.

Alan B
fuente
1
¿Estamos imaginando o realmente está realizando pruebas de pluma y tiene requisitos que le impiden evitar la inyección? ¿Estás buscando una manera de romper su falta de seguridad?
LowlyDBA
41
¿Por qué es incluso una opción que la puerta se deje abierta? Parece que ya ha pasado más tiempo contemplando esto de lo que costaría cerrar la puerta. Considero que esto es un ejercicio infructuoso: si se presentan 10 vulnerabilidades, dirán que las conectaremos, y ciertamente no habrá un undécimo. Aquí es donde nos llegaron las cuerdas de "limpieza". / facepalm
Aaron Bertrand
55
Esta es una pregunta increíblemente vaga y arbitraria, y ni siquiera teóricamente puede abordarse. Existen otras características de mitigación nativas de la inyección SQL (permisos, sandbox, firewalls, etc.), y tendría que tener en cuenta todas esas cosas para responder a esta pregunta.
Evan Carroll
2
¿Qué impone el límite de 26 caracteres? ¿La aplicación?
Jonathan Fite
77
Para. Sólo detenerlo. Si las consultas parametrizadas son una opción remota , úselas . Si alguien más no sabe cómo usarlos, busque un recurso decente y haga que lo lean. Si no escuchan, notifique a un gerente o supervisor que están produciendo vulnerabilidades de seguridad críticas (una demostración no destructiva no dañaría) y rehúse ser educado.
jpmc26

Respuestas:

38

Fácil:

GRANT EXECUTE TO LowlyDBA

O, supongo que en este caso sería

grant execute to lowlydba 

Elija su selección de variaciones sobre esto.

Con toda probabilidad, puede probar esto ahora en su sistema actual, pero cualquier cantidad de pequeños cambios en la base de datos a lo largo del tiempo podría invalidar su prueba. La cadena de caracteres podría cambiar, alguien podría crear un procedimiento almacenado en minúsculas que tenga potencial destructivo, cualquier cosa. Nunca se puede decir con un 100% de confianza que no hay un ataque destructivo de 26 personajes que alguien pueda construir.

Le sugiero que encuentre una manera de hacer que el desarrollador siga las mejores prácticas de seguridad estándar de la industria básica , aunque solo sea por su propio bien, ya que supongo que es al menos parcialmente responsable en caso de que se produzcan violaciones de seguridad.

Editar:

Y por malicia / diversión, puede intentar habilitar cada indicador de rastreo. Esto sería interesante de observar. Se siente como una publicación de blog que Brent Ozar haría ...

DBCC TRACEON(xxxx, -1)
LowlyDBA
fuente
1
Además de permitir los indicadores de traza: cambiar varios ajustes al azar: SET LOCK_TIMEOUT 0;, SET LANGUAGE Malaysian;, SET ANSI_NULLS OFF:...
ypercubeᵀᴹ
2
@ ypercubeᵀᴹ solo afectarían a su propia sesión.
Martin Smith
2
@MartinSmith thnx. Si SET(sólo afecta a la configuración de sesión, cómo se cambian los ajustes satabase y servidor ALTER DATABASE ...;?) DROP DATABASE ..;Sería infligir más daño, entonces, si tenía éxito;)
ypercubeᵀᴹ
1
Modifique la base de datos y sp_configure principalmente para la configuración de nivel de DB y servidor. Aunque podrías alcanzar el límite de 26 caracteres con estos. Además, estas configuraciones específicas a nivel de base de datos solo se usan si la conexión del cliente no las establece. Y por defecto la mayoría o todos lo hacen.
Martin Smith
77
Me parezco a ese comentario.
Brent Ozar
22

El SHUTDOWNcomando o KILLComando (elija un número aleatorio de más de 50) toman significativamente menos de 26 caracteres, aunque es de esperar que la cuenta que ejecuta las consultas de la aplicación no tenga permisos suficientes para ejecutarlos.

Martin Smith
fuente
Por lo general, la cuenta no necesitaría drop table tampoco ...
Greg
3
@Greg sí. Aunque puede suponer un entorno que está considerando permitir la inyección de SQL siempre y cuando la longitud sea corta, no se siguen las mejores prácticas de seguridad y es posible que las cuentas no se configuren con permisos mínimos.
Martin Smith
14

Puede crear una tabla que luego llene hasta el final del tiempo o se agote el espacio en disco, lo que ocurra primero.

declare @S char(26);

set @S = 'create table t(c char(99))';
exec (@S);

set @S = 'insert t values('''')'
exec (@S);

set @S = 'insert t select c from t'
exec (@S);
exec (@S);
exec (@S);
exec (@S);
-- etc
Mikael Eriksson
fuente
19
@AlanB Bueno, entonces necesitarías algo que me impida explotar la debilidad más de una vez.
Mikael Eriksson
1
tarnations ... while 1=1 insert t values('')es 30 ... create table x(i int)=> while 1=1 insert t select 0es 27
WernerCD
1
¿Podría usar esto para construir un comando más largo que el límite de caracteres y luego ejecutarlo?
Lawtonfogle
1
@ MartinSmith Pensé que me iría así, pero ahora solo tengo que probarlo :). Te lo haré saber si lo resuelvo.
Mikael Eriksson
77
Sin x:insert t select 0 GOTO xembargo, @WernerCD tiene exactamente 26 años.
Martin Smith
4

Dependiendo de su definición de daño, podría ejecutar esto: WAITFOR DELAY '23: 59 'Para ser verdaderamente malvado, podría usar una herramienta de prueba de carga para ejecutar eso desde 32,768 clientes.

usuario143642
fuente
1
Si la cadena se inyecta en un lote ad-hoc que contiene bloqueos, podría proporcionar una denegación de servicio viable como una sola llamada sin necesidad de provocar el hambre de subprocesos.
David Spillett
3

Variación basada en la respuesta de @ MikaelEriksson y la respuesta de @ MartinSmith a mi comentario inicial:

declare @S char(26);

set @S = 'create table x(i int)';
exec (@S);

Inicialmente intenté hacer una declaración WHILE, pero lo mejor que pude hacer fue 27 caracteres:

set @S = 'while 1=1 insert t select 0'; -- fails at 27 characters
exec (@S);

Pero Martin señaló GOTO:

set @S = 'x:insert t select 0 GOTO x';
exec (@S);

GOTO ... la raíz de todo mal y creador de una declaración de inserción de bucle infinito en 26 caracteres.

Dicho esto ... podría ser ventajoso quedarse con CHAR (99) en lugar de int ya que eso usaría más espacio. Otras opciones usan nombres más largos y romperían el límite de 26 caracteres ... o usarían menos espacio de almacenamiento por fila.

Código de prueba completo:

declare @S char(26);
set @S = 'drop table t;';
exec (@S);
GO

declare @S char(26);

set @S = 'create table t(c CHAR(99))';
exec (@S);

set @S = 'x:insert t select 0 GOTO x';
exec (@S);
GO
WernerCD
fuente
1
set @S = 'x:insert t;select 0;GOTO x';para compatibilidad futura de su ataque de inyección;)
ypercubeᵀᴹ
@ ypercubeᵀᴹ Agregaste dos ;s ... la segunda está bien - reemplaza un espacio y es funcional si no es necesario. El primero interrumpe la consulta: separa la instrucción INSERT de la instrucción SELECT.
WernerCD
Ah, sí. ¡Eso es lo que sucede cuando uno no usa separadores! ¡No sabemos dónde termina cada consulta y cuándo comienza la siguiente!
ypercubeᵀᴹ
1
@WarnerCD lo sé. Fue más una broma sobre el procedimiento de depreciación en SQL Server. Parece tomar para siempre. Aún así, es una buena práctica usar punto y coma entre las declaraciones y no solo donde se requiere.
ypercubeᵀᴹ
2
@yper Dudo que alguna vez se haga cumplir. Probablemente hay una tonelada de código heredado que necesitaría agregar puntos y coma faltantes sin ningún valor comercial particular para hacerlo. Y podría estar integrado en aplicaciones difíciles o imposibles de actualizar.
Martin Smith
0
XP_CMDSHELL 'SHUTDOWN -PF'

Dependiendo de cuán dañino considere que es un apagado. :-)

Esto requiere que xp_cmdshell esté habilitado en el servidor, algo que no es el caso para las últimas versiones de SQL Server. También requiere que la cuenta de servicio tenga el derecho de cierre correcto, que puede o no tener.

Habilitar xp_cmdshell probablemente va más allá de tu límite de 26 caracteres. ¿Permitirías múltiples inyecciones?

SP_CONFIGURE 'SHOW ADV',1

RECONFIGURE

SP_CONFIGURE 'XP', 1

RECONFIGURE
Caminante de piedra verde
fuente
1
El EXEC solo es opcional si esta es la primera instrucción del lote. Lo cual probablemente no será el caso aquí.
Martin Smith
@ Martin Smith, buen comentario. EXEC agrega 5 caracteres a cada línea de llamada de procedimiento, lo que lleva a la mayoría de ellos a más de 26 caracteres. Me pregunto si CREAR ALIAS ayudaría aquí.
Greenstone Walker