SQL injection with filter bypass via XML encoding

Description

This lab contains a SQL injection vulnerability in its stock check feature. The results from the query are returned in the application’s response, so you can use a UNION attack to retrieve data from other tables.

The database contains a users table, which contains the usernames and passwords of registered users.

Reproduction and proof of concept

Identify the vulnerability

  1. Observe that the stock check feature sends the productId and storeId to the application in XML format.

SQLi

  1. Send the POST /product/stock request to Burp Repeater.

  2. In Burp Repeater, probe the storeId to see whether the input is evaluated. For example, try replacing the ID with mathematical expressions that evaluate to other potential IDs, for example:

<storeId>1+1</storeId>
  1. Observe that the input appears to be evaluated by the application, returning the stock for different stores.

  2. Try determining the number of columns returned by the original query by appending a UNION SELECT statement to the original store ID:

<storeId>1 UNION SELECT NULL</storeId>
  1. Observe that your request has been blocked due to being flagged as a potential attack.

SQLi

Bypass the WAF

  1. As you’re injecting into XML, try obfuscating your payload using XML entities. One way to do this is using the Hackvertor extension. Just highlight your input, right-click, then select Extensions -> Hackvertor -> Encode -> dec_entities/hex_entities.

SQLi

  1. Resend the request and notice that you now receive a normal response from the application. This suggests that you have successfully bypassed the WAF.

SQLi

Craft an exploit

  1. Pick up where you left off, and deduce that the query returns a single column. When you try to return more than one column, the application returns 0 units, implying an error.

  2. As you can only return one column, you need to concatenate the returned usernames and passwords, for example:

<storeId><@hex_entities>1 UNION SELECT username || '~' || password FROM users<@/hex_entities></storeId>
  1. Send this query and observe that you’ve successfully fetched the usernames and passwords from the database, separated by a ~ character.

SQLi

  1. Use the administrator’s credentials to log in and solve the lab.