Inyección de SQL en la solicitud POST JSON

0

Tengo una aplicación web vulnerable a las inyecciones de SQL. Estoy usando BurpSuite para interceptar las solicitudes. Más específicamente, la siguiente variable de datos es vulnerable. Agregué mis propios datos a los agregados y filtros:

data=[{
   "params": {
     "dsreq": "{
         \"version\":1,
         \"type\":\"SQL\",
         \"limit\":500, 
         \"aggregates\":[
             {\"expr\":\"user()\"}
         ],
         \"partitions\":[],
         \"filters\":[\" 1=1 --\"],
         \"having\":[],
         \"dataset_id\":3}"
         }
     }
   ]

Esta carga útil devuelve la siguiente declaración SQL:

SELECT 'portal' user() FROM active_tab tab_0 WHERE (TRUE) AND ((TA_0.grp_id) = 'sqlgrp1')

La clave de agregados en JSON corresponde a la sección de columnas de la declaración SQL y los filtros corresponden a la condición.

Esto recupera algunos datos de la base de datos, pero solo devuelve datos de mi grupo. Observe cómo la cláusula where incluye 'TRUE' (mi declaración 1 = 1), pero luego la aplicación se agrega entre paréntesis y una instrucción AND adicional. Mi objetivo es evitar eso para poder obtener datos de todos los grupos. Mi ID de grupo es sqlgrp1.

¿Cómo puedo engañar al filtro para que detenga la ejecución de la cláusula WHERE después de la condición VERDADERA o no ejecuto la cláusula WHERE? Donde se agrega la condición si la clave de los filtros se deja vacía.

    
pregunta Hernan Duran 13.08.2018 - 17:20
fuente

3 respuestas

2

Realmente solo estoy reiterando lo que @YourCommonSense dijo en un comentario, pero de todos modos:

No hay nada aquí que sugiera que existe una vulnerabilidad de SQLi. He construido sistemas como este que funcionan de manera muy similar: tienen una entrada JSON muy expresiva que le permite al cliente tener un control más preciso sobre su consulta. Esto puede ser ventajoso porque le da al cliente más control sin tener que ajustar el servidor para cada caso de uso. Esto definitivamente no significa que hay una vulnerabilidad de SQLi. Por ejemplo, en mis sistemas, cada punto final de API (en este caso, dataset podría ser el equivalente) está vinculado explícitamente a una tabla y se agregan condiciones adicionales especificadas en el lado del servidor que siempre se agregan a la consulta. Todos los filtros adicionales pasados por el cliente se unen explícitamente con el operador AND mientras que el operador OR no se puede usar en absoluto. Además, todas las condiciones del lado del cliente están explícitamente en la lista blanca: al cliente solo se le permite filtrar por una lista predefinida de columnas y no se permite especificar el operador: solo se puede especificar el valor de búsqueda (la propia columna determina explícitamente qué operador se utiliza en la consulta real). Finalmente, todo está integrado en una consulta que utiliza consultas preparadas para la ejecución real. Todo esto hace que sea casi imposible tener una vulnerabilidad de SQLi, a la vez que permite al cliente un control más preciso sobre los resultados reales de la API. Menciono esto no para hablar de mi sistema, sino porque lo que construí se parece casi exactamente a lo que tienes, y los resultados que muestras son exactamente lo que verías con mi sistema también. En particular:

  1. Parece que has llegado a la conclusión de que la parte WHERE (true) de esa consulta es el resultado de tu inyección 1=1 . Probablemente este no sea el caso. Hacer que un analizador reconozca la condición 1=1 y traducirlo automáticamente a true sería un montón de trabajo y no tiene sentido, algo como 1=1 solo se mostraría debido a SQLi, así que no puedo imaginar que esto sea El comportamiento deseado de cualquier sistema. La mejor suposición es que la parte (verdadera) se agrega automáticamente a la consulta en todos los casos para facilitar la creación de la consulta (no tiene que realizar un seguimiento de si ya tenía una condición y, por lo tanto, si o no tengo que poner AND frente a la condición que está agregando) yb) MySQL lo ignorará de todos modos cuando construya el plan de consulta, por lo que tendrá un impacto casi nulo en el rendimiento.
  2. El hecho de que su comentario no se haya presentado en la consulta final sugiere que el sistema ha analizado su condición y la ha rechazado por completo. Nuevamente, su condición está siendo procesada por el sistema y no solo se agrega directamente al final (de ahí que su comentario no esté en la consulta final), y no habría ninguna razón para que un analizador reconozca su comentario y lo elimine. solo se muestran debido a las vulnerabilidades de SQLi, por lo que cualquier sistema lo suficientemente inteligente como para analizar y eliminar un comentario debería (teóricamente) ser lo suficientemente inteligente como para reconocer el peligro de SQLi y rechazar la solicitud por completo.
  3. La condición en grp_id está ahí aunque no la hayas especificado. Es probable que este sea un signo de que este punto final de la API en particular (o dataset_id ?) Agregue automáticamente las condiciones que no podrá eliminar.
  4. Se ve como si tuvieras user() en la selección, pero es difícil decir cuál es el significado de ese hecho (en todo caso).

Por lo tanto, diría que sin más detalles no hay mucho que seguir, pero esto no parece especialmente vulnerable desde aquí.

    
respondido por el Conor Mancone 13.08.2018 - 18:13
fuente
0

Suponiendo que el valor de filters se empalma directamente en la declaración SQL después de (TRUE , es decir, antes del corchete de cierre ....

\"filters\":[\" 1=1 --\ ) UNION SELECT 'portal' user() FROM active_tab tab_0 WHERE ("],

Revelaría a todos los grupos. Si se empalma en otro lugar, es posible que los soportes deban moverse un poco. Pero la ausencia del valor en su ejemplo JSON-in-JSON de su ejemplo SQL, y la falta de cualquier ejemplo adicional arroja muchas dudas sobre esto.

    
respondido por el symcbean 13.08.2018 - 18:38
fuente
0

Se debe evitar que la solicitud maliciosa llegue a la capa de persistencia de su aplicación web. Debe aplicar lo siguiente para proteger su aplicación de datos maliciosos provenientes de fuentes externas.

  • Saneamiento JSON a nivel de controlador.
  • Validación de entrada para cada objeto JSON.
  • Lista blanca para parámetros sensibles (¡especialmente el filtro! No puede hacer 1 = 1 para llegar a la capa de persistencia).

Los 3 enumerados son solo la protección mínima que DEBE aplicarse a cualquier aplicación web. Tenga en cuenta que no solo es vulnerable a la inyección de SQL, sino que también es vulnerable a los scripts entre sitios. Le sugiero que lea la hoja de trucos de OWASP y la guía de desarrolladores de OWASP para realizar la codificación adecuada con la seguridad implementada. Vea el siguiente enlace.

enlace enlace

    
respondido por el Winnnn 14.08.2018 - 02:34
fuente

Lea otras preguntas en las etiquetas