Exploiting SQL Injection in ORDER BY on Oracle-ora

Consider the following piece of code:

  1. $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 FROM DUAL)

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

So, the vulnerable script may be called like this:

  1. vulnerable.php?sortcolumn=(case+when+((ASCII(SUBSTR((select+table_name+from+all_tables+where+rownum%3d1),1))>%3D128))+then+id+else+something+end FROM DUAL)
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.

类似于基于内容、或者条件的注入,匹配查询的条件,就返回不同的结果

例子:当条件不同时,按照不同的表名来排序