[ToC] # Detecting SQL injection vulnerable :::info :bulb: SQL injection can be detected manually by using systematic set of tests against **every entry point** in the application ::: This typically involves: - Submitting the **single quote character `'`** and looking for errors or other anomalies - Submitting some **SQL-specific syntax** that *evaluates to the base* (original), and to a different value, and *looking for systematic differences* in the resulting application responses - Submitting **Boolean conditions such as `OR 1=1` and `OR 1=2`**, and looking for differences in the application's responses - Submiting **payloads designed to trigger time delays** when execute within a SQL query, and looking for differences in the time taken to respond. - Submitting OAST payloads designed to trigger an out-of-band # SQL injection in different parts of the query :::info :bulb: Most SQL injection vulnerabilities aries within the WHERE clause of a SELECT query. ::: But SQLi vulnerabilities can in priciple occur at any location within the query, and within different query types. The most common other locations where SQLi arises are: - In `UPDATE` statements, within the updated values or the `WHERE` clause. - In `INSERT` statements, within the inserted values. - In `SELECT` statements, within the table or column name. - In `SELECT` statements, within the `ORDER BY` clause # Examples :::success Some common SQLi examples include: - **Retriveing hidden data**, where you can modify a SQL query to return additional results. - **Subverting application logic**, where you can change a query to interfere with the application's logic. - **UNION attacks**, where you can retrieve data from different database tables. - **Blind SQL injection**, where the results of a query you control are not returned in the application's responses. ::: ## Retrveing hiddendata ### APPRENTICE Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data In this exercise, we have a shopping websites. By default, the website will list all products, but we can use **Refine your search** function to show product by category. ![](https://hackmd.io/_uploads/ryQArMuun.png) Example, if we click on **Pets**, our web browser will send a request to path `/filter` with query parameter `category=Pets` ![](https://hackmd.io/_uploads/SyWvLGOuh.png) Then the server will return products in the Pets category ![](https://hackmd.io/_uploads/HJjMtG_dh.png) Now, we can predict the sql query will be: ```sql SELECT ... FROM ... WHERE category = 'Pets' ...; ``` So if the programmer does not apply protections to the code we can manipuplate the param to list all rows in this table. We will replace `Pets` with `'OR 1 = 1 --` and the sql query will look like this: ```sql SELECT ... FROM ... WHERE category = '' OR 1 = 1 --' ...; ``` I use decode tab in Burp to URL encode the payload ![](https://hackmd.io/_uploads/r1TZQXOOh.png) Then send it to the server and bingo we solved the lab ![](https://hackmd.io/_uploads/SkPd7QO_3.png) **Warning:** :::danger Take care when injecting the condition `OR 1=1` into SQL query. Althought this may be harmless in the initial context your're injecting into, it's common for applications to use data from a single request in multiple different queries. If your condition reaches an UPDATE or DELETE statemetn, this can result in an accidental loss of data ::: ## Subverting application logic ### APPRENTICE Lab: SQL injection vulnerability allowing login bypass This exercise give us a login site ![](https://hackmd.io/_uploads/HJmArmuO2.png) As we know about the program flow of a login page, it will usually take the input that user enters from the login page and then use that information to query data from the database If we enter username=admin&password=admin, it may try to do this sql query: ```sql ... WHERE username = 'admin' AND password = 'admin' ...; ``` This query will be TRUE if the username and the password exists in database, if not, the query will return FALSE To make the query return even we don't know the username or password, we can manipulate the input, replace username input from `admin` to `' OR 1 = 1--`. And the query will look like this ```sql ... WHERE username = '' OR 1 = 1 --' AND password = 'admin' ...; ``` Bingo, exercise solved ![](https://hackmd.io/_uploads/Bk0VsQuu3.png) # SQL injection in different contexts :::info :bulb: You can perform SQL injection attacks using any cotrollable input that is processed as a SQL query by the application ::: For example, some websites take input in JSON or XML format and use this to query the database These different formats may provide alternative ways for you to obfuscate attacks that are otherwise blocked due to WAFs and other defense mechanisms ## What is XML ? XML (Extensible Markup Language) is a markup language designed to store and transport data in a structured format. It provides a way to describe and organize data in a hierarchical manner using tags and elements. XML is widely used for data interchange between different systems and platforms. Example: ```xml= <person> <name>John Doe</name> <age>30</age> <email>john@example.com</email> </person> ``` :::spoiler In this example, `<person>` is the root element, and it contains nested elements such as `<name>`,`<age>`, and `<email`. Each element represents a piece of data, and the values are enclosed within the opening and closing tags ::: ## Representing Characters in HTML, XML Because HTML, XML syntax uses some charaters for tags and attributes it is not posible to diectly use those characters inside tags or attribute values. To include special charaters inside HTML, XML you can use **Representing Characters** There are several ways to represent a character in HTML, XML, some right, some wrong =))) 1. Direct Character Entry 2. Numeric Character Reference (NCR) - **`&#nn;`** decimal form - **`&#xhh;`** hexadecimal form 3. Character Entinity References HTML also defines Character Entity References, i.e. **short length text names** that can be used to identify a charater. To use the name as a Character Entinty Reference, prepend the ampersand "**&**" and append the semi-colon "**;**". | Entity Character Reference | NCR Hex | NCR Dec | Character Name | Character | | -------------------------- | ------- | ------- | -------------- | --------- | | `&quot;` | `&#x22;`| `&#34;` | double-quote | " | | `&apos;` | `&#x27;`| `&#39;` | apostrophe | ' | | `&lt;` | `&#x3C;`| `&#60;` | less-than | < | | `&gt;` | `&#x3E;`| `&#62;` | greater-than | > | | `&amp;` | `&#x26;`| `&#38;` | ampersand | & | **Reference:** http://www.i18nguy.com/markup/ncrs.html https://en.wikipedia.org/wiki/Numeric_character_reference ### PRACTITIONER Lab: SQL injection with filter bypass via XML encoding Here is the POST request when we click on function `Check stock` ![](https://hackmd.io/_uploads/rJIhBOn6h.png) We can see that `Check stock` feature sends the `productId` and `storeId` to the application in XML format Remember that **we can perform SQL injection attacks using any cotrollable input that is processed as a SQL query by the application** So I try to check the vulnerable by using single quote symbol ![](https://hackmd.io/_uploads/BkJD_O262.png) ![](https://hackmd.io/_uploads/SJqicOhan.png) ![](https://hackmd.io/_uploads/BJoXju3p3.png) Seem like our request has been blocked due to being flagged as a pontential attack by using a predefined blocklist We know that we can represent character in XML, so what if the represent character are not in the blocklist :smiley: 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`. ![](https://hackmd.io/_uploads/HJE7TOna3.png) Successfully bypassing WAF ![](https://hackmd.io/_uploads/Byu66O2ah.png) Here is the actual request was sent. All character was replaced by Numeric Character Reference in decimal form **1. Comfirm the SQL injection vulnerable** :heavy_check_mark: ![](https://hackmd.io/_uploads/rkQSxohah.png) **2. Determine how many columns a being return and what it's type** :heavy_check_mark: ![](https://hackmd.io/_uploads/H1Edxsha2.png) **3. Figure out the database type and version** :heavy_check_mark: ![](https://hackmd.io/_uploads/Sko0ejn6h.png) **4. Listing the contents of the database** Find out interesting table `users` ![](https://hackmd.io/_uploads/B1H0-jh6n.png) Find out the column name of table `users` ![](https://hackmd.io/_uploads/ryFVzo3pn.png) Use string concatenation to get username and password in one column ![](https://hackmd.io/_uploads/Hk3eQin62.png) Add some symbols between username and password for easy viewing ![](https://hackmd.io/_uploads/rkDhXihp2.png) **5. Login to administrator account** ![](https://hackmd.io/_uploads/SkDZ4snTh.png) :::success **Solved** :thumbsup: :::