Digamos que tienes una consulta como esta:
$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";
Ahora imagine que controla $search
a través de un parámetro. Por lo general, haríamos que devuelva las contraseñas de usuario en el campo joindate
de esta manera:
$search="' UNION SELECT username, password FROM users; -- -";
Como tal, la consulta se convierte en:
SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20
La parte posterior al guión doble es un comentario, por lo que se ignora, y todas las combinaciones de nombre de usuario y contraseña se adjuntan como nuevos registros al final del conjunto de datos, después de los registros legítimos. Impresionante!
Pero ahora queremos adaptar esto para que podamos encontrar el nombre de la base de datos, para una mayor investigación de su base de datos. En MySQL, podemos usar la función DATABASE()
:
$search="' UNION SELECT DATABASE(), 1; -- -";
El uso de 1
aquí es rellenar el campo joindate
, que no estamos usando.
En MSSQL podemos hacer exactamente lo mismo, pero con DB_NAME()
:
$search="' UNION SELECT DB_NAME(), 1; -- -";
Ambos de estos trucos agregarán una sola fila al final del conjunto de resultados, que contiene el nombre de la base de datos.
Luego podemos expandir este truco para usar VERSION()
en MySQL o @@VERSION
en MSSQL, que devuelve la versión actual de la base de datos. Para Oracle y PL / SQL puede verificar la existencia de la tabla v$version
, simplemente haciendo una consulta en ella y buscando un error.