Esto es una inyección de SQL que funciona. ¿Cómo podría ser la cadena de consulta del lado del servidor?

4

Esta pregunta es sobre un pequeño detalle en una tarea escolar más grande. He estado luchando con este pequeño problema durante demasiado tiempo.

ABCTF organizó una competencia de captura de bandera que se llevó a cabo a principios de este año. Uno de los problemas en esta competencia, fue una inyección de SQL. Esta es una URL para la descripción de la tarea, y esta es una URL al formulario de inicio de sesión que se iba a inyectar. Hay una solución publicada para este problema, y se parece a esto:

Nombre de usuario: -1 'union select 1,1,1,1 #

Contraseña: 1

Necesito averiguar cómo se verá la cadena de consulta de back-end. La suposición más simple e ingenua sería

String query = "SELECT FROM user WHERE username = '" + inputA + "' AND password = '" + inputB + "';";
execute(query);

Pero esto produciría

String query = "SELECT FROM users WHERE username = '-1' union select 1,1,1,1 #' AND password = '1';";
execute(query);

El problema más evidente con esto, es que las comillas están desequilibradas. Además, no entiendo qué salida produciría la instrucción SELECT. Como lo he entendido, el carácter "#" se usa para denotar tablas temporales en MS SQL Server, como "#temporary_table". He jugado con otras declaraciones simples también, pero nada que tenga sentido.

¿Alguien tiene una idea de cómo se vería la consulta de backend ? Cualquier sugerencia es apreciada.

    
pregunta Magnus 02.11.2016 - 18:47
fuente

2 respuestas

2

El enlace indica que la solución consiste en agregar una línea falsa completamente nueva a través de la unión, donde cada valor es un 1. El -1 como nombre de usuario intenta asegurarse de que la consulta no devuelva ningún dato válido como idioma del servidor, generalmente solo compara la primera fila. Un ejemplo sería el siguiente código.

password = execute("SELECT password FROM users WHERE username = '{$username}'");
if( password != $password ) fail();
pass();

Lo que resulta en

password = execute("SELECT password FROM users WHERE username = '-1' union select 1,1,1,1 #'");
// no username called -1 means that the only row returned is the artificial row, so password = 1
if( password != 1 ) fail();
pass();

Tenga en cuenta que existen millones de formas en que este código funcionaría, desde solo SQL hasta vulnerabilidades en la aplicación web. Sin embargo, encontré este enfoque más realista.

    
respondido por el James Cameron 02.11.2016 - 21:23
fuente
7

En MySQL, el símbolo # se puede usar como . Las comillas en los comentarios no tienen que equilibrarse.

No todas las instancias de SQL se ejecutan en bases de datos de Microsoft.

    
respondido por el John Deters 02.11.2016 - 19:37
fuente

Lea otras preguntas en las etiquetas