Primero lo primero
¿Incluso tienes permiso y autorización para probar y jugar con esto? Es posible que necesite una prueba escrita por su propio bien en caso de que se convierta en algo malo. Asegúrese de que no está haciendo esto en vivo en algún servidor de producción, use un servidor de prueba en su lugar.
Volver a lo básico
Una forma clásica de demostrar las inyecciones de SQL:
$id = isset($_GET['id']) ? $id : -1; // Set default value if id isn't set
$stmt = $db->query('SELECT * FROM articles WHERE id=' . $id);
$results = $stmt->fetchAll();
fancy_display($results);
Para obtener todas las filas, podríamos usar 0 OR 1=1
. La consulta final se verá así SELECT * FROM articles WHERE id=0 OR 1=1
. Como 1=1
siempre es verdadero, devolverá todas las filas de los artículos.
Por lo general, esto no es lo que queremos a menos que queramos estresar al servidor de alguna manera. Por lo tanto, tendemos a usar UNION
para llegar a otras tablas: 1 UNION SELECT ALL 1, 2, username, hash from users
.
¿Qué hay de inyectar un INSERT después de SELECT?
La inyección de SQL se trata realmente de modificar la consulta SQL original de manera no intencionada. La consulta debe ser válida para tener éxito. Siguiendo nuestro ejemplo anterior, no puede simplemente mezclar un INSERT con un SELECT en una consulta:
SELECT * FROM articles WHERE id=1 ALSO INSERT INTO articles (title, content) VALUES ("foo", "bar")
Tenga en cuenta que TAMBIÉN es solo una palabra clave imaginaria, bueno, ya que no es compatible. Otro intento sería utilizar para separar las consultas separándolas con ;
:
SELECT * FROM articles WHERE id=1; INSERT INTO articles (title, content) VALUES ("foo", "bar")
La mayoría de las veces esto no funciona. La segunda consulta se ignora, porque el código subyacente debe especificar que está utilizando "consultas múltiples", también conocidas como "consultas apiladas". En PHP, por ejemplo, es necesario usar mysqli::multi_query
en lugar de mysqli::query
. La mayoría de las aplicaciones utilizan el equivalente posterior. Es posible que desee leer una respuesta mía anterior .
Inyectando una declaración INSERT
Por lo tanto, la otra forma legítima es intentar encontrar un código vulnerable que use INSERT
:
// Registration page
// Got credentials via $_POST
$username = 'foo';
$password = 'bar'; // not hashed, so bad
$db->query('INSERT INTO users (username, password, admin) VALUES ("' . $username . '", "' . $password . '", 0)');
La consulta final se verá así:
INSERT INTO users (username, password, admin) VALUES ("foo", "bar", 0)
Cambiamos el flujo usando una contraseña diferente: bar", 0), ("haxors_admin", "easy", 1)--
. La consulta final se verá así:
INSERT INTO users (username, password, admin) VALUES ("foo", "bar", 0), ("haxors_admin", "easy", 1)--", 0)
Todo lo que aparece después de --
se comenta y, por lo tanto, se ignora. Acabamos de añadir un usuario administrador. Tenga en cuenta que este escenario es muy simple para demostrar el ataque.
sqlmap se une a la diversión
sqlmap es una herramienta de automatización para encontrar vulnerabilidades de SQL y explotarlas. Además de la exfiltración de datos, también tiene opciones para la toma de control del SO como --os-shell
o --os-cmd
.
Bajo el capó, comprobará si las consultas apiladas son compatibles. Si es así, utilizará sys_exec
o sys_eval
para ejecutar esos comandos. Si no es así, intentará usar una puerta trasera de la web (por ejemplo, una puerta trasera php) para ejecutar esos comandos. La puerta trasera se crea al inyectar INTO OUTFILE
: engañar a la consulta para escribir en una carpeta de escritura . Ahora, si MySQL no tiene los derechos para escribir en esa carpeta, no se creará. Así falla el ataque. Este vector de ataque se explica mejor en la wiki de uso de sqlmap . Más información sobre esto en Inyección avanzada de SQL al sistema operativo con control total (papel blanco) .
Conclusión
En su caso, las consultas apiladas no son compatibles y MySQL no tiene suficientes derechos. Lo que explica por qué el ataque falló. Aparte de los propósitos de aprendizaje, le aconsejaría que no se moleste más y empiece a corregir vulnerabilidades.