所谓 WAF Bypass,就是利用 WAF 的规则设计缺陷,绕过其对恶意参数的检测。这里对常见的 bypass 姿势进行汇总,方便以后遇到时能够查阅使用。
SQL 注入绕过
脏数据绕过
受限于性能,大部分 WAF 对于检测的数据包长度都有一定的限制,所以可以通过在 payload 前添加大量脏数据,使整个请求包的长度超出 WAF 的长度限制,进而跳过检测环节,实现绕过。
高并发绕过
对于配置了负载均衡的系统,采用高并发请求,带有 payload 的请求会被调度到不同的节点上,可能由于负载均衡的配置不当,导致某些请求不经过 WAF 而直接发送到 Web 服务上,实现绕过。
参数污染绕过
对于 PHP 语言,如果采用 ?id=1&id=1'
的形式传参,后面的同名参数会覆盖掉前面的参数,某些 WAF 只检测了第一个参数,后面的同名参数就能绕过检测。
Method 绕过
某些 WAF 只对某些请求方法的请求进行了过滤,如只过滤了 POST,但没有过滤 PUT,这时候就可以通过修改请求方式的方式实现绕过。
编码绕过
指的是将传入进行特殊编码,使得 WAF 无法进行有效解码而后端服务能正常解码,这样 payload 就顺利被发送到了后端服务。常见的编码绕过方式有二次 URL 编码、Unicode 编码、HTML 编码等。
空格绕过
有的 WAF 会检测过滤参数中的空格符,对于这种情况,可以使用 +
、%09
、%0A
、%0C
等进行替代。对于 MySQL ,还可以使用内联注释替代空格,形式为 SELECT/**/*FROM/**/users;
。
大小写绕过
某些 WAF 对大小写敏感,检测规则中无法列举所有的大小写组合情况,所以可以通过大小写混写的方式进行绕过。
双写绕过
这种方式适用于使用了 replace
函数对黑名单关键字进行替换的 WAF,例如对于关键字 SELECT
,可以写成 SELSELECTECT
的形式,藏在中间的 SELECT
被替换成空字符串后,剩下的就是符合语法的 SELECT
关键字,依然可以造成注入。
宽字节绕过
宽字节是相对于单字节而言的,GBK 编码每个字符使用 2 字节,UTF-8 编码每个字符使用 3 字节,而 ASCII 编码每个字符只使用 1 字节,所以 ASCII 编码就称为单字节,GBK 和 UTF-8 等编码就称为宽字节。
当 MySQL 使用 GBK 编码时,如果同时输入两个字符,且前一个字符的 ASCII 编码大于 128 (最常用的是 %df
),那么 MySQL 就会同时读取这两个字符,把他看作一个汉字字符来解析。
当输入单引号 '
(ASCII 编码为 %27)时,如果存在转义函数,就会在单引号前添加一个反斜杠 \
(ASCII 编码为 %5c
),变成 \'
。
如果在输入单引号的时候,在单引号前加一个 ASCII 编码大于 128 的字符,例如 %df
,这样 MySQL 在经过转义之后,输入就会变成 %df%5c%27
,此时 MySQL 再去解析,就会将 %df%5c
看作一个汉字字符,单引号 %27
就逃逸了。
命令执行绕过
通配符绕过
常用的通配符有:
*
:0 个或多个字符?
:1 个或多个字符
例如在尝试读取某些黑名单文件时,就可以使用通配符替代目录名或文件名中的某些字符,实现绕过检测:
cat /e?c/pa*wd
连接符绕过
连接符 '
适用于命令黑名单的情况,在 bash 中可以使用 '
来连接字符,在解析时会自动去除字符间的 '
,最后形成的还是合法的命令,例如:
/b'i'n/who'a'mi
需要注意的是,'
需要成对出现,即必须闭合。
Null 变量绕过
在 bash 环境中,任何未定义的变量都是 null,所以可以在命令中间插入未定义的变量,这样在 bash 解析时仍然会得到合法的命令:
cat$a /etc$b/passwd$c
空格绕过
如果在执行 shell 命令时被过滤了空格,可以考虑以下方式:
- 使用
${IFS}
代替空格 - 使用
<>
代替空格
Base64 绕过
使用管道符输出 base 64 编码的命令到 base64 -d
命令,解码得到真实的命令:
echo "Y2F0IGZsYWcudHh0Cg==" | base64 -d | bash
命令嵌套
Bash 中支持命令嵌套,常用方式有:
1、反引号
echo `whoami`
2、$()
echo $(whoami)
追加绕过
通过把一个命令拆分,依次追加写入一个文件中,然后读取这个文件的内容传递给 bash 命令,也能达到绕过执行的目的:
echo 'wh' >> t.txt
echo 'am' >> t.txt
echo 'i' >> t.txt
cat t.txt | bash
文件上传绕过
等号绕过
抓取文件上传的表单,在 filename=
后面添加两个等号,变成 filename===
。
换行绕过
在文件后缀名处换行,如:
原始报文:
filename=1.php
修改变成:
filename=1.p
hp
脏数据绕过
还是因为 WAF 的性能限制,对检测的内容长度有限制,所以可以在请求包中填充大量脏数据,使其超过 WAF 的长度上限,跳过检测阶段。
双文件上传
某些 WAF 只检测了上传的第一个文件,而忽略了第二个文件,所以可以同时上传两个文件,第一个为合法文件,第二个为恶意文件,实现绕过的目的。
条件竞争绕过
利用的是 WAF 检测文件到删除恶意文件到时间差,通过高并发,使得 WAF 来不及删除恶意文件,导致恶意文件能够停留在服务器磁盘中,从而被利用。