2024-03-18

Blind SQL Injection in update query for OSWE - PostgreSQL Database

Pranaam to all 🙏

In this blog post we are gonna explore the approach to exploit an SQL Injection in update query. 

Following are the assumptions:

👉 Injection point - Where clause in Update query. 

👉 Use of stack query is not allowed.

👉 The web application is not showing DB error message.

👉 Blind injection is possible

Just one meme before proceeding to the explanation 😅



Update Query injection - Integer based 

The vulnerable SQL query is as follow:

Upon successful execution of Update query, API responds with success message. 
If something goes wrong, response is something like this:

How to solve this puzzle 

To exploit such SQL injection vulnerable endpoint, we are going to use following type of payload:


Why this approach:

Well, when we are performing Blind SQL Injection exploitation:

👉 If condition/comparison specified by us is correct, it allows SQL query to perform update operation and user see a generic "success" message
else 
👉 force SQL query to execute the payload which causes an error and hence no update operation is performed. When update query encounters an error, web API code shows a generic error message.

Here is our sample payload: 

Let's breakdown the payload to understand it's different parts.
👉 Data extraction/Comparison part of the payload: 
To perform blind SQL Injection exploitation, we need to perform comparison using this part. 
If comparison returns true, in that case web API will return "Success" message.
👉 Exception causing part: 
This part of payload will come into action when the condition specified in Data extraction/comparison part does not return true. 
This payload will always cause an exception due to the fact that the second argument to function has_database_privilege() needs a valid DB privilege name whereas we have specified sting 'b0x' which is not a valid DB privilege name.

Exploitation time 🤘😎🤘
First of all, let's verify if our payload is working as expected or not:
True condition:

False condition:

Extracting the database name
The below mentioned payload will extract first character from the database name and will convert int into ASCII value
Now, put it into our payload and start comparing it. Final payload will be like this:
The name of current database is "box" and the ASCII value of first character of the Database name is 98 (b).
Let's ask to DB if the ASCII value is greater then 90 or not using below mentioned payload:


The web API response shows that the condition evaluated successfully which means the ASCII value of first character of DB name is greater then 90.
Let's check if ASCII value 100 is greater then the ASCII value of first character of the Database name using below mentioned payload:


No, API response shows that the update query could not perform operation. Because ASCII value of database name first character is 98 which is not greater then 100 and condition specified in OR operator i.e. has_database_privilege(1337,'b0x') evaluated and caused an exception. 
Now, instead of performing less/greater then operator, try with equal operator and mention 98 and see the API response if we are going in right direction. Use below mentioned payload:
To extract the ASCII value of next character, we need to make a small change in payload i.e. we need to increment the value of substring() second argument by one.
Means, we need to change it from 
ascii(substring(current_database(),1,1)) 
to 
ascii(substring(current_database(),2,1)) 
And payload will be like this:

There we go!
Now, to extract the value of second character, we need to repeat the same process which we followed to figure out the first character
Extracting tables name for current DB
To extract the tables name, we need to consider following things:
Step 1👉 Run SQL query which extract name of only one table at a time. Let's say name of first table. 
Step 2👉 After extraction of table name, get the first character using substring( )
Step 3👉 Convert that extracted character into ASCII value
Step 4👉 Perform comparison against ASCII values to figure out the ASCII value of first char 
Step 5👉 Once we get to know the first character, go to step 2 and change the value in substring( ) to extract the next character
Step 6👉 Follow step 3 and 4 to figure out the second character.
Step 7👉 To extract next table name, go to step 1 and change the value of offset from 0 to 1.
Step 8👉 Follow step 2 to step 6 to find out the name of second table.

Payload to extract the name of first table from information schema:
If we want go for another table, make a change in the value of offset. 
For example, 
for second table it will become offset 1
In case of third table, it will become offset 2
When we go for forth table, make it offset 3 
and so on....
To extract a character and conversion of it will be done using substring( ) and ASCII( ) respectively.
Our final payload will look something like this:
 
First table name is admins and hence the ASCII value of it first character which will be extracted by the payload is 97 (a value greater then 90).
When request was sent to the API, following response confirmed our theory:
Let's try with ASCII value 100 and see the response:

It's working!
Go for equal operator and see if it is working or not:

Done 😎Now try to extract next character of the first table name.
Here, payload needs a modification in second argument of substring( ) i.e.  substring(table_name,1,1) will become substring(table_name,2,1)
Payload to extract second character will be:
 
In order to extract second character of the first table name, we need to repeat same steps which we followed to extract the first character.
Payload to extract the name of second table from information schema:
As I mentioned earlier, if we performing blind SQL Injection, we need to specify which table we want to extract. To do this, limit and offset will help us.
Sample payload which will extract the name of second table of current database:
To extract the name of third table, payload will be:
As we are interested in extraction of first character of the second table name, we need to pass the table name to substring( ) and ASCII( ) to get it.
Payload will be like this:

Just keep changing ASCII value to perform the comparison and observe the API response.
For now, we are done and I will be back with some new stuff. 
Thanks for your time. 

With Love from 
❤️ --==[[ Indishell Lab ]]==-- ❤️

Share this post

0 comments

:) :-) :)) =)) :( :-( :(( :d :-d @-) :p :o :>) (o) [-( :-? (p) :-s (m) 8-) :-t :-b b-( :-# =p~ :-$ (b) (f) x-) (k) (h) (c) cheer

© 2009 Start With Linux | Mannu Linux
Designed by cyb3r.gladiat0r
Posts RSSComments RSS
Back to top