Thursday, February 23, 2023

 

Interesting Blind Boolean SQL Injection in a Private Bug Bounty Program

The application is vulnerable to Blind Boolean SQL Injection vulnerability which relies on sending a SQL query to the database which forces the application to return a different result depending on whether the query returns a TRUE or FALSE result. Depending on the result, the content within the HTTP response will change, or remain the same. This allows an attacker to infer if the payload used returned true or false, even though no data from the database is returned.

Impact:

An attacker may execute arbitrary SQL statements on the application databases. This may compromise the integrity of the database and expose sensitive information.

Root-Cause:

The SQL injection occurs because the application accepts user input that is directly placed into SQL statements and doesn't properly filter out dangerous characters. SQL injection can lead to disclosing data stored in the database tables. All URLs containing the requestID, flowId and timesheetID URI parameters are vulnerable. 

Examples as below: 

Examples of Vulnerable APIs

/medicalcards/requests/{requestID}

/medicalcards/requests/flowids/{flowId}

/phoneprograms/requests/{requestId}

/installments/requests/{requestID}

/pensions/requests/{requestId}

/timesheets/requests/{timeSheetId}



 

Manual Detection and Verification:

All vulnerable parameters are allowing only numeric values and some Boolean keywords ex: AND/OR which is evaluated in the server-side database queries and in the end it should return numeric value to retrieve the existing request from the database so, this allowed us to know if the payload used returned true or false even though no data from the database is returned.

·        AND/OR Detection:








·        URL-Encoding Detection:

At this stage we detected and confirmed that the application is vulnerable to SQLi and the back-end database is ORACLE because the concat operator (||) but the problem was that the only allowed keywords was only AND/OR and as mentioned before it should return only numeric value. So, we managed to bypass these limitations by URL-Encoding our payload using other keywords and built-in functions that should return only numeric values such as SUBSTR,USERENV('SID'),USERENV('SESSIONID'), UID.  So, these numeric values will be placed as a number in the requestID sql query in the back-end.

Injected Payload:

%31%20%4f%52%20%34%34%34%34%3d%53%55%42%53%54%52%28%27%34%34%34%34%34%27%2c%20%31%2c%20%34%29

The payload is 1 OR 4444=SUBSTR('44444', 1, 4) and shown in the  screenshot below:



USERENV and built-in functions return information about the current session:



·        Building Strings:

At this stage we were able to inject string values in the vulnerable parameters using (URL-Encoding). So, we have to build our payloads using other SQL keywords to able to retrieve information from the database. Each DBMS provides its functions for doing this such as ASCII,UNHEX,CHAR,HEX,ORD are useful to translate strings to numbers or numbers to strings.

We used the ASCII() function to return the ASCII value for the specific character as shown below. Our payload executed successfully and returned the ASCII value and then retrieved the request id with this value. ASCII('t') is equal to 116.


Here is an example to know if the current database user is DBA or not by using USERENV('ISDBA') built-in function which returns TRUE or FALSE, so we have to convert the first character to its ASCII number value to detect the result:

Injected Payload:

%31%20%41%4e%44%20%30%37%30%3d%41%53%43%49%49%28%53%55%42%53%54%52%43%28%28%55%53%45%52%45%4e%56%28%27%49%53%44%42%41%27%29%29%2c%31%2c%31%29%29

Which is: 1 AND 070=ASCII(SUBSTRC((USERENV('ISDBA')),1,1)) -> 070 is the first letter and equal (F)


·        Exploit Automation With SQLMap:

In order to exploit the vulnerability, we had to modify SQLMap to obfuscate the payload with aggressive URL-Encoding to encode every character.

We have modified the "between" tamper script that (replaces greater than operator (>) with NOT BETWEEN 0 AND # and equals operator (=) with BETWEEN # AND #) and to encode all the payload by adding the following two line of codes:



Then, we used SQLMap tamper option in order to have it use our custom script on its payload pre-injection. The vulnerability allowed us to gain access to the applications database. Below is a sample of the data we retrieved:

SQLMap Command and Explanation: python.exe sqlmap.py -r vodafoner.txt --auth-type="Digest" --auth-cred="redacted:redacted" --proxy=https://192.168.1.13:443 --timeout=600 --technique=b --tamper="between2" -v 5 --dbms=Oracle --string="requestID" --risk=3 --level=5 --current-user



1.      Get Current-User:


2.      Get Oracle Version:


3.      Get Current Database Name:


4.      ISDBA:



No comments:

Post a Comment