当前位置: 首页 > news >正文

SQLMap Tamper脚本实战:从原理到定制化WAF绕过

1. 项目概述:为什么我们需要深入理解Tamper脚本?

如果你用过SQLMap,大概率遇到过这种情况:对着一个看起来有注入点的URL跑了大半天,结果要么是“所有参数似乎都不注入”,要么是payload发出去就石沉大海,连个错误回显都没有。新手这时候可能就放弃了,但老手会心一笑,默默加上--tamper参数。Tamper脚本,就是SQLMap这套自动化“大杀器”里的“特种兵”,专门负责在payload送上前线之前,对其进行伪装、变形、编码,以绕过各种WAF(Web应用防火墙)、IDS(入侵检测系统)甚至是应用层自己写的蹩脚过滤逻辑。

很多人把Tamper脚本当成一个黑盒魔法,只知道“这个站用space2comment能过”,却不知道背后的原理。这就像你只会按配方做菜,却不懂火候和调味,一旦遇到新奇的防御手段,立马抓瞎。这篇指南的目的,就是带你从“会用”到“懂原理”,再到能根据实际情况“自己改”甚至“自己写”。我们将从最基础的绕过场景开始,拆解经典Tamper脚本的每一行代码,理解其设计思路,最后探讨如何组合使用乃至定制开发高级绕过脚本。无论你是安全测试人员、渗透测试学习者,还是对Web安全防御机制感兴趣的研究者,掌握Tamper脚本的实战精髓,都能让你对SQL注入攻防的理解提升一个维度。

2. Tamper脚本核心原理与工作机制拆解

2.1 SQLMap的Payload生成与处理流水线

要理解Tamper,首先得明白SQLMap是如何工作的。它不是简单地把一堆预定义的payload扔出去。其内部有一个完整的引擎,工作流程大致如下:

  1. 逻辑判断与指纹识别:SQLMap首先会发送一些无害的探测请求,判断参数是否动态、数据库类型(通过报错信息、特有函数等),并尝试识别WAF。
  2. Payload库选取:根据数据库类型(MySQL, PostgreSQL, SQL Server, Oracle等)和注入类型(布尔盲注、时间盲注、报错注入、联合查询等),从庞大的内置payload库中选取基础模板。
  3. Payload渲染:将模板中的占位符(如[INFERENCE],[SLEEP],[COLUMN])替换为具体的逻辑(如比较子句、延时函数、列名)。
  4. Tamper处理这是关键一步。渲染后的原始payload会依次通过用户指定的Tamper脚本(如--tamper “space2comment,randomcase”)。每个脚本都是一个Python函数,接收原始payload,返回修改后的payload。多个脚本按顺序执行,前一个的输出是后一个的输入。
  5. 请求发送与结果分析:处理后的payload被嵌入到HTTP请求中发送,SQLMap再根据响应内容(如页面差异、时间延迟、报错信息)来判断注入是否成功,并提取数据。

所以,Tamper脚本的本质是一个Payload变形过滤器。它不关心注入逻辑,只负责对payload的“外观”进行手术,使其能够逃逸防御系统的检测规则。

2.2 常见过滤与绕过思路分类

WAF和过滤逻辑千变万化,但核心思路无非几种,对应的Tamper脚本也围绕这些思路展开:

  1. 关键字过滤:直接拦截union,select,from,where,or,and等SQL关键字。
    • 绕过思路:大小写变形(UnIoN)、内联注释分割(uni/**/on)、编码(URL编码、HTML实体、十六进制)、等价替换(||替代or)、注释混淆(union/*random*/select)。
  2. 特殊字符过滤:过滤空格、单引号'、双引号"、等号=、注释符--#等。
    • 绕过思路
      • 空格:用/**/(多行注释)、+%0a(换行)、%0d(回车)、%09(制表符)甚至多个空格替代。
      • 单引号:用\'(转义)、%bf%27(宽字节)、chr(39)(字符函数)、0x27(十六进制)替代。
      • 等号:用likebetween...and...>0 and <2等逻辑替代。
  3. 语义分析:高级WAF会尝试解析SQL语句结构,拦截拼接后形成威胁的语句,而不仅仅是匹配关键字。
    • 绕过思路:通过注释、换行、无效括号等方式破坏WAF的语法解析,例如union(select(1),2)union/*!50000select*/ 1,2。MySQL特有的内联注释/*!...*/在这里是神器,因为MySQL会执行其中的内容,而许多WAF会忽略或错误解析。
  4. 签名/正则匹配:基于已知攻击payload的特征库进行匹配。
    • 绕过思路:随机化。在关键字中随机插入注释、改变大小写、添加无关参数(如version()变成version/*foo*/()),使每次请求的payload签名都不同,绕过静态规则库。

实操心得:不要一上来就堆砌Tamper脚本。先用手工测试判断过滤类型。例如,在参数后分别添加'and 1=1and 1=2union select 1,2,3,观察响应差异。如果'被拦截但and 1=1and 1=2返回相同页面,说明可能只过滤了引号但没过滤and=。这个初步判断能极大缩小Tamper脚本的选择范围。

3. 基础Tamper脚本深度解析与实战应用

这一部分,我们挑选几个最常用、最具代表性的基础脚本,逐行分析其代码,理解其适用场景和局限性。

3.1 space2comment.py:空格的经典替身

这是使用频率最高的Tamper脚本之一。它的逻辑非常简单:将payload中的空格字符( )替换为多行注释/**/

#!/usr/bin/env python # 简化后的核心逻辑 def tamper(payload, **kwargs): retVal = payload if payload: retVal = re.sub(r"\s+", "/**/", payload) # 正则匹配所有空白字符(包括空格、制表符、换行等) return retVal
  • 作用:绕过对空格的过滤。许多简单的WAF或代码层过滤会直接str_replace(' ', '')或正则匹配\s+union\s+
  • 实战场景:当你的union select被拦截,但union/**/select能正常返回时,就应该使用它。
  • 注意事项
    1. 它替换所有空白字符。有时payload里可能有必要的换行符\n,也会被替换,这可能破坏某些特定上下文(极少见)。
    2. 对于更严格的过滤,/**/本身也可能被列入黑名单。此时需要尝试其他替代品,如space2plus.py(用+替换)或space2hash.py(用#加换行)。

3.2 randomcase.py:随机大小写的迷惑术

这个脚本通过随机化关键字的大小写,来绕过基于大小写敏感匹配的过滤规则。

#!/usr/bin/env python import random def tamper(payload, **kwargs): def process(match): word = match.group('word') return ''.join(random.choice((c.upper, c.lower))() for c in word) # 对每个字符随机选择大写或小写 retVal = payload if payload: retVal = re.sub(r"(?i)\b[A-Z_]+\b", process, retVal) # (?i)忽略大小写,匹配单词边界内的纯字母/下划线串 return retVal
  • 作用:将SELECT可能变为SeLeCtsELecT等,使SELECT这个静态签名失效。
  • 实战场景:适用于那些采用简单正则(如/select/i)进行过滤,但没有进行规范化(统一转小写再比较)的防御系统。
  • 注意事项
    1. 它只影响“单词”,即被\b边界包围的字母串。所以version()中的version会被变形,但括号不会。
    2. 过度随机化可能导致payload长度显著增加(虽然不明显),且每次请求的payload都不同,这在某些需要稳定payload的盲注场景下可能不是最优选择。
    3. 重要:如果目标系统(如Oracle)对SQL关键字大小写敏感(通常不,但自定义解析器可能),使用此脚本会导致语法错误。

3.3 charencode.py 与 charunicodeencode.py:编码的艺术

这两个脚本都涉及编码转换,但目的不同。

  • charencode.py:对payload中未编码的字符进行一次URL编码%xx格式)。

    • union select 1,2->%75%6e%69%6f%6e%20%73%65%6c%65%63%74%20%31%2c%32
    • 适用场景:某些WAF只解码一次URL,或者对原始参数进行关键字检查,但对解码后的内容检查不严。通过手动编码,可以让关键字“隐形”。
    • 注意:它使用urllib.quote,并设置safe="%&",意味着%&不会被二次编码,避免破坏已编码部分或参数分隔符。
  • charunicodeencode.py:将字符转换为Unicode编码形式(%u0075%u006e...\u0075\u006e...)。

    • union->%u0075%u006e%u0069%u006f%u006e
    • 适用场景:主要针对一些ASP/ASP.NET环境,它们可能支持这种Unicode表示法,而WAF规则库可能遗漏对此格式的检查。在现代Web应用中效果有限。

避坑指南:使用编码类Tamper时,务必使用-v 3(或更高)参数运行SQLMap,观察最终发出的payload。你需要确认编码后的payload在目标服务器的上下文中能被正确解码。例如,如果参数放在JSON body里,URL编码可能无效;如果放在application/x-www-form-urlencoded的POST数据中,URL编码是标准操作,通常有效。

3.4 between.py 与 equaltolike.py:操作符的“马甲”

这两个脚本针对的是对比较操作符(>,=,<)的过滤。

  • between.py:用BETWEEN ... AND ...语法替换>=

    • id > 1->id NOT BETWEEN 0 AND 1(逻辑等价:id > 1)
    • id = 1->id BETWEEN 1 AND 1
    • 原理BETWEEN是范围查询,在语义上可以等价于比较操作,但字符串形式完全不同,能绕过简单的操作符过滤。
    • 限制:生成的SQL语句更复杂,可能在某些非常简化的SQL解析场景(如某些ORM框架拼接的查询)中引发问题。
  • equaltolike.py:将等号=替换为LIKE

    • id=1->id LIKE 1
    • 原理:在绝大多数数据库中,当比较数值或简单字符串时,=LIKE(在没有通配符的情况下)功能是等价的。但LIKE这个关键字很少出现在注入攻击的规则集中。
    • 注意:如果比较的是字符串,LIKE是大小写不敏感的(取决于数据库配置),而=可能是大小写敏感的,这可能导致逻辑差异。但在注入探测中,我们通常只关心“真”和“假”的页面差异,这种细微差别通常不影响布尔盲注。

基础脚本组合策略:面对未知过滤,一个安全的起步组合是--tamper “space2comment,randomcase”。先用space2comment解决空格问题,再用randomcase扰乱关键字签名。如果不行,再考虑加入编码类(charencode)或操作符替换类(between)脚本。记住,--tamper参数的脚本顺序就是处理顺序。

4. 高级绕过技巧:脚本组合、定制与WAF对抗实战

当你用遍了内置脚本还是绕不过时,就需要更高级的策略了。这包括理解WAF的工作原理、巧妙组合现有脚本,以及最终手段——自己编写Tamper脚本。

4.1 针对特定WAF的脚本解析

SQLMap内置了一些针对历史版本或特定品牌WAF的脚本,理解它们有助于举一反三。

  • modsecurityversioned.py / modsecurityzeroversioned.py:这两个是针对ModSecurity(一个开源的WAF模块)的。核心技巧是利用MySQL内联注释

    # modsecurityversioned.py 核心代码片段 def tamper(payload, **kwargs): retVal = payload if payload: postfix = '' for comment in ('#', '--', '/*'): if comment in payload: postfix = payload[payload.find(comment):] # 保留原注释 payload = payload[:payload.find(comment)] # 去掉原注释 break # 在关键字前添加 /*!50000*/ retVal = re.sub(r"(?i)\b(union|select|insert|update|delete|drop|from|where)\b", r"/*!50000\1*/", payload) retVal += postfix return retVal
    • /*!50000*/是MySQL的特性,表示如果数据库版本大于等于5.00.00,就执行注释内的代码。对于WAF,它可能被视为普通注释而忽略,但MySQL会正常解析其中的unionselect等关键字。modsecurityzeroversioned.py使用/*!00000*/,原理类似。
    • 实战意义:这教会我们,利用数据库特性(尤其是MySQL的内联注释)是绕过WAF语义分析的利器。
  • bluecoat.py:这个脚本做了两件事:1) 在SQL语句后添加随机空白符;2) 将=替换为LIKE。它模拟了某些特定代理或WAF(如BlueCoat SGOS)的绕过模式。其价值在于展示了尾部填充的思路,添加无关内容可以干扰某些基于固定长度或位置签名的检测。

4.2 脚本组合的进阶策略与顺序考量

Tamper脚本的顺序至关重要,因为前一个脚本的输出是后一个脚本的输入。

  • 错误示例--tamper “charencode,space2comment”
    • 你先对整个payload进行了URL编码,空格变成了%20。然后space2comment脚本寻找的是空格字符 ,找不到%20,所以替换无效。最终payload里依然是%20而不是/**/
  • 正确顺序--tamper “space2comment,charencode”
    • 先把空格变成/**/,然后再对整个字符串进行URL编码,/**/被编码为%2f%2a%2a%2f。这样既绕过了空格过滤,又通过了可能的关键字检查。

一个针对较强过滤的通用组合思路

  1. 结构破坏randomcomments.py- 在关键字之间插入随机注释,破坏union select这样的连续签名。
  2. 关键字变形randomcase.pyversionedkeywords.py- 改变关键字本身的形式。
  3. 空格处理space2comment.pyspace2plus.py- 处理剩余的空格。
  4. 最终编码charencode.py- 对整个payload进行一次“化妆”。

你可以这样使用:--tamper “randomcomments,randomcase,space2comment,charencode”。使用-v 3观察最终payload,看是否符合预期。

4.3 手把手编写自定义Tamper脚本

当内置脚本全部失效,或者遇到非常独特的过滤规则时,自己写Tamper脚本是终极解决方案。一个Tamper脚本就是一个Python文件,放在SQLMap的tamper/目录下即可被识别。

编写步骤与模板

  1. 创建文件:在tamper目录下新建一个.py文件,例如my_bypass.py
  2. 编写函数:文件必须包含一个名为tamper的函数。
  3. 实现逻辑:在函数内对payload字符串进行操作。
  4. 添加依赖:如果需要,可以导入re(正则)、random等库。

下面是一个实战案例:假设目标网站过滤了select关键字,但不过滤selselectect(即采用简单的str_replace(‘select’, ‘’)过滤,我们可以用双写绕过)。

#!/usr/bin/env python """ Copyright (c) 2006-2024 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ import re from lib.core.enums import PRIORITY __priority__ = PRIORITY.NORMAL # 定义脚本优先级,NORMAL即可 def dependencies(): pass # 这里可以声明依赖关系,通常为空 def tamper(payload, **kwargs): """ 双写绕过简单字符串替换过滤 例如:select -> selselectect,替换后变成 select """ retVal = payload if payload: # 定义要双写的关键字列表 keywords = ['select', 'union', 'from', 'where', 'or', 'and', 'insert', 'update', 'delete', 'drop', 'table'] for keyword in keywords: # 使用正则忽略大小写进行替换 # 注意:替换模式是 ‘s’ -> ‘selsect’,‘e’->‘seleect’... 我们采用简单方法:在关键字中间插入自身 # 更健壮的做法:将 ‘select’ 替换为 ‘sel’ + ‘select’ + ‘ect’ if keyword.lower() in payload.lower(): # 粗略检查是否存在 # 构造双写后的字符串:将 ‘select’ 变成 ‘sel’ + ‘select’ + ‘ect’ doubled = keyword[:len(keyword)//2] + keyword + keyword[len(keyword)//2:] # 使用正则进行不区分大小写的替换 retVal = re.sub(r'(?i)\b' + re.escape(keyword) + r'\b', doubled, retVal) return retVal

代码解析

  • __priority__:脚本执行的优先级。当多个脚本对同一部分进行修改时,优先级高的后执行(覆盖前面的)。一般保持NORMAL
  • dependencies():用于声明此脚本运行所需的其他脚本,通常不需要。
  • tamper(payload, **kwargs):核心函数。payload是SQLMap传来的原始payload字符串。我们返回修改后的字符串。
  • 逻辑:遍历预定义的关键字列表,检查payload中是否存在(忽略大小写)。如果存在,则将其替换为“双写”版本。例如,select被替换为selselectect。当目标系统执行str_replace(‘select’, ‘’, $input)后,中间的select被移除,两边的select又拼接成了select,从而绕过过滤。

测试你的脚本

  1. 将脚本放入tamper/目录。
  2. 使用SQLMap的-t参数指定一个临时文件来观察payload变化:sqlmap -u “http://test.com?id=1” –tamper “my_bypass” -v 3 –flush-session。查看输出中[PAYLOAD]部分,确认变形是否符合预期。
  3. 在安全的测试环境(如DVWA、SQLi-Labs)中配置相应的过滤规则,进行实战测试。

高级技巧:利用kwargstamper函数接收**kwargs,其中包含一些有用的上下文信息,例如kwargs.get(‘headers’, {})可以获取HTTP头。你可以编写根据Content-TypeUser-Agent动态调整变形策略的智能脚本。例如,当Content-Typeapplication/json时,可能需要对payload进行JSON字符串转义。

5. 实战问题排查与Tamper脚本调试技巧

即使掌握了所有脚本,实战中依然会碰壁。本章节汇总了常见问题及其排查思路。

5.1 常见失败场景分析与解决思路

问题现象可能原因排查步骤与解决方案
使用Tamper后,SQLMap报告“所有参数似乎都不注入”1. Tamper脚本破坏了payload语法。
2. 变形后的payload触发了更严格的WAF规则。
3. 目标参数本身不存在注入点。
1.使用-v 3-v 4:这是最重要的步骤。仔细观察[PAYLOAD][HTTP请求]部分,看最终发出的SQL语句是什么。它是否还是一条合法的SQL?
2.简化Tamper:先只用一个最基本的脚本(如space2comment)测试,逐步增加。
3.手动验证:将-v 3看到的payload手工复制到Burp Suite Repeater中发送,观察服务器响应。确认是WAF拦截(返回403等)还是SQL语法错误(返回500或数据库报错)。
4.检查脚本顺序:确保编码类脚本在最后。
注入能检测到,但无法提取数据(如--dbs失败)1. 某些关键函数或语句被过滤(如select,from,information_schema)。
2. Tamper脚本在数据提取阶段未生效或生效方式不对。
1.分阶段测试:分别测试布尔盲注(--technique=B)、时间盲注(--technique=T)、报错注入(--technique=E)。可能某种技术能绕过。
2.使用--prefix--suffix:手动指定注入点前后缀,有时可以绕过对特定上下文语法的过滤。
3.检查WAF识别:使用--identify-waf更准确地识别WAF,然后查找针对该WAF的特定Tamper或技巧。
4.尝试--level--risk:提高检测等级(--level 3)和风险等级(--risk 3),SQLMap会使用更多、更“冒险”的payload和Tamper组合。
同一个Tamper脚本,有时成功有时失败1. WAF可能有动态规则或学习模式。
2. 脚本中使用了随机化(如randomcase),导致某些变形恰好被规则命中。
3. 服务器有速率限制或IP临时封锁。
1.降低请求频率:使用--delay 1(每秒1请求)和--timeout 30
2.使用代理池:通过--proxy--proxy-file轮换IP。
3.禁用随机化:如果怀疑是randomcase导致,换用确定性的变形脚本,如versionedkeywords
4.观察WAF日志模式:如果可能,在测试环境分析WAF日志,看它到底拦截了哪些特征。
自定义脚本不生效1. 脚本未放在正确的tamper/目录。
2. 脚本语法错误。
3. 函数名不是tamper,或优先级__priority__设置有问题。
4. SQLMap缓存了之前的测试结果。
1.检查路径:确保脚本在SQLMap根目录的tamper/文件夹内。
2.Python语法检查:在命令行运行python -m py_compile your_script.py检查错误。
3.使用--flush-session:清除缓存,强制SQLMap重新开始测试。
4.在脚本开头加print语句调试(临时):在tamper函数第一行添加print(“My script is called with:”, payload),运行SQLMap时观察控制台输出。

5.2 高效调试与信息收集方法论

  1. 必用参数-v 3:这是调试Tamper的“眼睛”。它显示每一个测试payload的变形前和变形后状态。
  2. 结合Burp Suite
    • 将SQLMap的代理设置为Burp (--proxy=http://127.0.0.1:8080)。
    • 在Burp中观察所有请求和响应。重点关注被WAF拦截(返回403、419等状态码或有特定拦截页面)的请求。
    • 对比拦截请求和成功请求的payload差异,能精准定位触发规则的“坏字符”或“坏模式”。
  3. 使用--test-filter:如果你怀疑某个特定的payload类型(如>的比较)被过滤,可以用--test-filter只测试包含该字符的payload,快速验证。
  4. 利用--string--not-string:在盲注中,指定一个在真/假条件下会稳定出现在页面中的字符串,可以帮助SQLMap更准确地判断,减少因WAF干扰导致的误判。
  5. 离线分析模式:使用-l参数从Burp Suite保存的日志文件中读取目标,可以避免频繁触发WAF的IP封锁,同时仔细分析每个请求。

5.3 超越Tamper:当脚本也无力时

Tamper脚本主要处理payload本身。如果WAF的防御层次更高,可能需要结合其他技巧:

  • HTTP参数污染(HPP)?id=1&id=2,不同的服务器端语言会以不同方式解析,可能绕过参数检查。SQLMap的-prefix-suffix可以模拟。
  • 畸形HTTP请求:修改Content-Type、使用GET传递POST数据、分块传输编码等。这需要修改SQLMap的lib/request/相关代码或使用其他工具配合。
  • 资源限制绕过:如果WAF有请求大小限制,可以尝试使用非常长的参数值,或者将payload拆分到多个参数(如Cookie、Header)中。
  • 时序攻击:对于时间盲注,精心设计SLEEP函数,使其延迟时间不规则,避开基于固定延时阈值的检测。

最终,SQL注入与WAF的对抗是道高一尺魔高一丈的持续过程。Tamper脚本是自动化工具中的重要一环,但真正的突破往往来自于对目标系统、数据库特性、WAF规则乃至HTTP协议的深刻理解。保持学习,手动测试,分析流量,你才能从脚本的使用者,成长为绕过规则的创造者。

http://www.jsqmd.com/news/1351279/

相关文章:

  • Moonshot Kimi K3 开放权重发布:从1.56TB到594GB,Unsloth动态量化打破硬件壁垒
  • 题解:瑞学堂 瑞瑞的会议安排
  • 深度学习环境配置全解析:从CUDA驱动到PyTorch依赖的完整逻辑链
  • 解析蛋白互作网络:酵母双杂交技术原理与优化策略剖析
  • SAP生产成本明细报表开发:打通业财数据,实现精细化成本分析
  • GPU并行计算架构与AI加速实践
  • 做跨境口播,别急着下单:7款多语种AI数字人平台横向测评
  • 蓝桥杯真题解析:置换环理论在最小交换次数问题中的应用
  • 生物素-黄芩素复合物的化学修饰与应用研究
  • U位资产管理系统:数据中心智能运维的关键技术
  • Flutter FSRS算法在鸿蒙OS的移植与优化实践
  • RPC框架核心原理与微服务通信实践:从概念到选型避坑指南
  • AI对话助手思考过程可视化:从提示工程到Agent框架的实现指南
  • Source Insight:大型C/C++项目代码阅读与符号导航的终极利器
  • React之服务端渲染ReactFizzServer
  • 域见抚苏:唤醒 · 原力 · 生长 ——品牌愿景、使命与核心优势深度解读
  • 用数学建模优化时间管理:从算法思维到实践应用
  • OpenClaw最新版部署教学,TopClaw内置6万技能免配置
  • Unity安卓实时预览工具包:原理、部署与高效调试指南
  • 5分钟搞定Vuforia开发许可证:Unity AR开发环境配置全攻略
  • 个人关系管理工具Monica:从社交焦虑到关系资产的数字化管理
  • KVM虚拟化中qcow2镜像在线扩容技术详解
  • 一键关闭电脑屏幕小工具快速又方便
  • 电动车防盗器触发导致车轮抱死故障的诊断与应急维修指南
  • 问卷式前端别只会翻页:用状态机做好断点续答与幂等提交
  • VirtualBox虚拟机深度使用报告:十年老用户谈核心优势、实战技巧与性能调优
  • 电动汽车充电负荷预测的蒙特卡洛方法实践
  • 题解:瑞学堂 徐老师的二进制加法
  • AI编程新范式:阿里Qoder与GLM-5.1协同提升开发效率
  • 09 K 近邻算法入门:从距离理解分类