SQL注入绕过WAF的本质,不是寻找某种神秘代码,而是利用WAF规则集与后端数据库解析器之间的逻辑差异。绝大多数WAF并非铁板一块,它们依赖正则表达式、关键字黑名单或语法分析来识别攻击载荷。当你的注入语句被拦截时,通常意味着触发了某条特定规则。绕过技术就是在这条规则的边界上跳舞,通过改变字符的表达形式,让WAF认为这是无害数据,同时让数据库引擎成功解析出恶意逻辑。

编码绕过的核心逻辑:解码差异与多层解析

WAF与后端程序之间最经典的鸿沟在于解码顺序。许多WAF只做一次解码,或者只解码特定协议层,而Web服务器和数据库驱动可能会进行多次解码。例如,一个简单的单引号被双重URL编码为%2527,WAF可能只解码一次看到%27,认为这不是一个真实的单引号而放行,但Web服务器在接收到参数后会进行二次解码,将其还原为单引号。这种差异不仅限于URL编码,Unicode编码、十六进制编码、HTML实体编码都存在类似问题。关键在于,你要测试目标WAF究竟在哪一层进行检测,以及后端应用程序栈在哪个环节进行解码。针对多层解码的绕过,通常需要构造嵌套的编码载荷,比如对关键词SELECT进行两次URL编码,或者将部分字符用Unicode宽字节表示,观察WAF的反应。

大小写与关键字混淆的进阶用法

早期WAF对大小写敏感,SeLeCt就能绕过,现在大多数WAF已具备大小写不敏感匹配。但这并不意味着关键字混淆失效,只是需要更精细的操作。你可以利用数据库的内建函数或注释符来打乱关键字。在MySQL中,使用内联注释//嵌入特殊字符,比如/*!50000SeLeCt*/,WAF可能将其视为注释块,但MySQL会根据版本号执行其中的语句。在SQL Server中,可以利用方括号或双引号包裹关键字的一部分,如[SEL][ECT],只要拼接后能形成完整命令。另一种有效方式是利用数据库对空白符的宽容性,用注释符、换行符或特殊Unicode空白字符替代空格,打乱WAF依赖的单词边界识别。例如,在MySQL中,SELECT//1和SELECT%0a1都能正常执行,但WAF的正则表达式可能因为缺少明确的空格分隔而匹配失败。

等价函数与运算符替换策略

WAF黑名单通常覆盖常见的危险函数,如user()、database()、load_file()等,但数据库往往提供多种等价写法。在MySQL中,获取当前用户可以用user()、current_user()、current_user、session_user(),甚至通过读取系统变量@@hostname、@@version_compile_os来间接获取信息。字符串截取函数substr()被拦截,可以换用mid()、substring()、left()、right(),或者用正则函数regexp_substr()。运算符方面,逻辑与或可以用&&和||替代AND和OR,等号=可以用like、regexp、between...and...、in来替代。当WAF拦截1=1这类经典测试时,可以尝试1 like 1、1 in (1)、! (1<>1)等逻辑等价表达式。关键在于建立一个丰富的等价函数映射表,在测试时快速切换,直到找到未被规则覆盖的变体。

HTTP参数污染与分块传输的实战应用

HTTP参数污染是一种利用Web服务器对同名参数处理差异的绕过技术。当请求中包含多个同名参数时,不同服务器有不同的取值逻辑。例如,PHP/Apache通常取最后一个参数值,而ASP.NET可能取第一个。你可以构造?a=1&a=2这样的参数,WAF可能只检查第一个a的值,而业务逻辑使用了第二个。更隐蔽的做法是将注入载荷拆分到多个参数中,利用数据库的字符串拼接函数在服务器端重组。分块传输编码则是将请求体拆分成多个小块发送,WAF可能因为无法完整重组请求而放行。在Burp Suite中开启分块传输,将SQL语句分散到不同的块中,特别是将关键字从中间断开,能有效绕过依赖完整请求体检测的WAF。这两种技术通常需要结合使用,因为现代WAF也在逐步加强对分块传输的检测。

字符集攻击与宽字节注入的深度利用

字符集攻击是绕过WAF最被低估的技术之一。当数据库使用GBK、GB2312等宽字节字符集时,可以利用反斜杠转义机制的缺陷。在PHP的addslashes()或magic_quotes_gpc开启时,单引号会被自动加上反斜杠变成\',但在GBK环境下,如果提交的字符与反斜杠组合成一个合法的宽字节字符,反斜杠就被吃掉了。经典的%df',%df与反斜杠%5c组合成%df%5c,这是一个合法的中文字符,单引号就成功逃逸。WAF通常不会对这种编码层面的绕过进行深入检测。除了宽字节,还可以利用Latin1与UTF-8之间的转换漏洞,某些字符在转换过程中会丢失或被合并,从而改变SQL语句的语义。测试时,可以尝试在参数中插入各种高位字符,观察应用是否出现乱码或报错,这往往意味着字符集处理存在可利用空间。

SQL标准与数据库方言的规则差异

WAF规则大多基于通用的SQL语法编写,但各数据库厂商的方言扩展常常成为绕过突破口。PostgreSQL支持双美元符号$$作为字符串界定符,WAF可能只认单引号,使用$$绕过字符串检测极为有效。Oracle中,N'...'、Q'[...]'等字符串表示法也能规避基于单引号的规则。SQL Server的OPENROWSET、OPENQUERY等行集函数,以及xp_cmdshell的变形调用,往往因为规则覆盖不全而可被利用。MySQL的load data local infile、into outfile等文件操作函数,配合十六进制编码或char()函数构造路径,也能绕过对文件路径字符串的检测。深入理解目标数据库的方言特性,是高级绕过的基础。不要只盯着通用的SQL语法,要研究目标数据库特有的函数、存储过程和语法糖,这些往往是WAF规则的盲区。

规则加固:从攻击视角构建防御体系

理解绕过技巧的最终目的是构建更坚固的防御。规则加固不应是简单的黑名单堆砌,而要从解码一致性、语法规范化和行为分析三个层面入手。首先,统一解码标准,在WAF层面进行多次解码直到无法继续解码为止,确保检测的是最终载荷。其次,对SQL语法进行规范化处理,将所有变体还原为标准形式后再匹配规则,比如将所有空白字符替换为空格,去除注释,展开编码。最后,引入行为分析,不单看请求是否包含危险关键字,而是结合上下文判断。例如,一个参数中同时出现SELECT和FROM,且来自非登录用户,就应该提高警惕。规则加固的核心思路是消除WAF与数据库之间的认知差异,让两者对同一段数据的理解保持一致。

实战中的编码组合与测试方法论

在实际测试中,单一绕过技术往往不够,需要将多种技术组合使用。一个典型的组合链可能是:首先使用分块传输打乱请求结构,然后在参数内部使用双重URL编码处理关键字,接着用注释符替代空格,最后用等价函数替换被拦截的函数名。测试时要有系统的方法论,不要盲目尝试。建议先确定数据库类型和版本,这决定了可用的方言特性。然后测试WAF的解码层级,提交单次、双重、三重编码的简单载荷,观察拦截情况。接着测试空白符和注释的宽容度,最后才是关键字和函数的变体。记录每一次测试的结果,建立目标WAF的规则画像,找出其检测的边界条件。绕过WAF不是碰运气,而是基于对HTTP协议、数据库引擎和WAF规则引擎三者交互机制的深刻理解。

未来趋势:机器学习WAF的弱点与对抗

基于机器学习的WAF正在兴起,它们不依赖固定规则,而是通过训练模型识别恶意请求的特征。这类WAF的弱点在于训练数据的偏差和模型的可解释性不足。如果训练数据中缺少某种编码方式的样本,模型就可能对其视而不见。此外,机器学习模型往往对罕见字符组合敏感,但如果你将恶意载荷伪装成接近正常业务数据的形态,比如将注入语句嵌入到长文本中,使其整体特征偏向正常请求,就有可能绕过检测。对抗机器学习WAF需要更精细的载荷构造,利用模型的黑盒特性,通过大量测试找出其决策边界。但无论WAF如何进化,只要后端数据库的解析逻辑不变,编码与解码之间的差异就永远存在,这是防御者与攻击者之间永恒的博弈。