Exploiting SQL Injection in ORDER BY on Oracle

Consider the following piece of code:


$sql = "SELECT something FROM some_table WHERE id=? ORDER BY $column_name";

The WHERE clause is parametrized, but the ORDER BY isn't. This happens often enough. Assuming that $column_name comes from user input, this code is vulnerable to SQL injection.

The way to exploit such SQL injection on MySQL backend is described by Sumit Siddharth here and by Jacco van Tuijl here

I couldn't find any clues for Oracle though, so now that I have figured it out, here is how.

This is a blind SQL injection technique - we'll have to extract one bit of info per query, using the order in which the data is returned by the application. Let's assume that the vulnerable script is called as vulnerable.php?sortcolumn=id . In this case it returns the following data:

  • foo
  • bar
  • baz

We can try sorting by other columns and see if the data gets returned in different order. Say, if we try vulnerable.php?sortcolumn=something, we get back:

  • bar
  • baz
  • foo

Now all we need to do is to get the query to sort the data by different column depending on the value of a given expression. In Oracle the following syntax works:


ORDER BY (case when ((boolean_expression)) then id else something end)

If boolean_expression is true the result will be sorted by id, otherwise by something.

So, the vulnerable script may be called like this:

vulnerable.php?sortcolumn=(case+when+((ASCII(SUBSTR((select+table_name+from+all_tables+where+rownum%3d1),1))>%3D128))+then+id+else+something+end)

This will extract the most significant bit of the first character of the first row returned by "select table_name from all_tables" query. Actually fetching significant amounts of data obviously requires automation.