¿Es posible la inyección de SQL con LIMIT?

37

Un amigo mío construyó una aplicación web que estoy probando por diversión. Noté que le permite a un usuario establecer el límite de una consulta determinada, y ese límite no está saneado.

Por ejemplo, puedo elegir cualquier número o cadena que me guste como límite. Me doy cuenta de que esto es inyección SQL , y puedo inyectar fácilmente comandos SQL, pero ¿es realmente posible extraer cualquier información o ¿Algún daño con un LIMIT ?

Ejemplo de la consulta:

SELECT * FROM messages WHERE unread = 1 LIMIT **USER INPUT HERE**

Entiendo que si la inyección estuviera en la cláusula WHERE , podría haber hecho fácilmente un UNION SELECT para extraer cualquier información, pero ¿es realmente posible si la entrada del usuario fue después del límite?

Para obtener más información, mi amigo está utilizando el DBMS MySQL , por lo que realmente no puede ejecutar dos consultas como :

SELECT * FROM messages WHERE unread = 1 LIMIT 10;DROP TABLE messages-- 

No es posible.

    
pregunta Ali 23.12.2014 - 12:04
fuente

6 respuestas

73

Puedes hacer un UNION SELECT aquí. El único problema es hacer coincidir las columnas de los mensajes, pero puede adivinarlas agregando columnas hasta que encajen:

SELECT * FROM messages WHERE unread = 1 LIMIT 
    1 UNION SELECT mail,password,1,1,1 FROM users

Solo sigue agregando ,1 hasta que obtengas el recuento de columnas correcto. Además, debe coincidir con el tipo de columna. Pruebe null en lugar de 1 .

Si puede ver los errores de MySQL que podrían ser de gran ayuda aquí. De lo contrario tienes un montón de intentos.

También vea Pruebas de inyección de SQL en owasp.org para algunos detalles.

    
respondido por el PiTheNumber 23.12.2014 - 14:11
fuente
4

O casi no hay restricciones, y puedes hacerlo de la manera habitual (UNION o '; XXX ---')

A veces no es posible, y tendrás que recurrir para poner una expresión booleana en el LÍMITE. Eso es una inyección ciega de SQL y le permitirá volcar toda la base de datos poco a poco.

    
respondido por el Dillinur 23.12.2014 - 15:35
fuente
3

MySQL soporta múltiples declaraciones y desde entonces Menos 4.1 hace diez años. Por ejemplo, puede activarlo en el mysql de Perl módulo utilizando mysql_multi_statements .

Si bien es posible que la biblioteca del cliente no admita varias declaraciones en este momento, solo es un cambio de actualización o configuración lejos de un agujero de seguridad.

    
respondido por el Schwern 24.12.2014 - 05:27
fuente
1

Establecer un límite de 1 UNION SELECT ... permitirá al atacante extraer información de cualquier otra tabla, siempre que las columnas tengan (o puedan ser CAST ) el mismo número y tipo que las columnas en la primera %código%. Al establecer un límite como un valor producido a partir de un sub SELECT , el atacante podrá leer cualquier otra información en la base de datos del número de filas devueltas. Por ejemplo, el hash de la contraseña de otro usuario se puede extraer 4 bits a la vez haciendo repetidamente una subconsulta devolviendo un número entre 0 y 15 en diferentes compensaciones de subcadenas y luego contando filas en cada resultado.

Pero ambos ataques pueden ser frustrados. Muchos controladores de base de datos permiten un parametrizado SELECT . Si un controlador en particular interfiere con un LIMIT parametrizado, puede desinfectar la entrada convirtiendo la entrada en un entero antes de sustituirla por cadena en la consulta. Esto también lo ayudará a asegurarse de no devolver más registros de los que su aplicación puede manejar desde una consulta (como LIMIT ). En PHP, podría verse así:

<?php
//...
$limit = intval($_REQUEST['numresults']);
$limit = min(max($limit, 10), 100);
$stmt = $dbh->prepare("SELECT ... FROM ... WHERE ... LIMIT $limit");
    
respondido por el Damian Yerrick 23.12.2014 - 20:30
fuente
1

Este es un buen momento para usar declaraciones preparadas con DOP y bindParam esa variable como una entrada de solo enteros. Eso debería anular cualquier intento de lo que intenta hacer inyectando SQL.

También consideraría permitir al usuario elegir entre una lista de números predefinidos en un menú desplegable. A menos que la página de resultados esté configurada para paginar, puedes tener un buen lío en tus manos tratando de cargar 100,000 registros en una página.

    
respondido por el Rick 25.12.2014 - 04:42
fuente
1

La consulta de su amigo no sería de mucha utilidad en la actualidad, pero puede ser posterior, pero a medida que las tecnologías evolucionen, y el DBMS de MySQL se encuentra bajo mejoras constantes como muchas otras tecnologías, su amigo debe desinfectar la información en el caso de% La declaración de LIMIT se cambiaría para que sea posible utilizar UNION justo después. Su amigo también puede considerar el caso en el que la arquitectura de DBMS de MySQL se modificará de tal manera que sería posible ejecutar varias declaraciones SQL a diferencia de como es ahora.

Lo que quiero decir es que tu amigo debe desinfectar la información: es la mejor práctica: quizás no lo veas demasiado importante hoy, pero en el futuro nunca lo sepas, y recuerda que siempre hay personas que pueden serlo. más experimentado que tu amigo.

    
respondido por el user45139 23.12.2014 - 12:41
fuente

Lea otras preguntas en las etiquetas