从泛微云桥漏洞看文件读取风险:手把手教你编写基础防护规则(WAF/IDS篇)
最近在帮几个客户做安全巡检时,发现了一个挺有意思的现象:不少企业虽然部署了WAF和IDS,但面对一些已知的、利用方式固定的漏洞攻击,防护效果却并不理想。比如,一个典型的任意文件读取漏洞,攻击者只需要构造一个特定的URL参数,就能轻松绕过基础防御,读取服务器上的敏感配置文件。这让我意识到,很多安全团队不缺工具,缺的是如何让工具“理解”攻击并精准拦截的能力。今天,我们就以曾经广泛影响的泛微云桥(e-Bridge)文件读取漏洞为例,抛开复杂的理论,直接聊聊如何从一次具体的攻击中,提炼出关键特征,并亲手编写出能真正拦住它的防护规则。无论你是安全产品的运维人员,还是刚开始接触规则开发的工程师,这篇文章都将带你走完从分析到落地的完整过程。
1. 漏洞原理:不仅仅是“读文件”那么简单
在开始写规则之前,我们必须先搞清楚攻击者到底做了什么。很多人看到“任意文件读取”,第一反应就是攻击者传了一个文件路径,然后系统就把文件内容返回了。这个理解没错,但过于笼统,无法指导我们编写精确的规则。我们需要深入到HTTP请求的细节里去观察。
以泛微云桥的这个漏洞为例,攻击的核心在于一个名为/wxjsapi/saveYZJFile的接口。这个接口本意可能是用于处理文件上传或保存,但它对外部传入的downloadUrl参数缺乏严格的校验。攻击者发现,可以将downloadUrl参数的值设置为file://协议开头的本地文件路径。当应用服务器(如Tomcat)接收到这个请求并尝试去“下载”这个URL指定的资源时,由于file://协议指向的是服务器本地文件系统,便导致了任意文件读取。
这里有几个关键点需要拆解:
- 攻击入口:特定的API路径 (
/wxjsapi/saveYZJFile)。这不是一个普通的静态资源或首页,而是一个功能接口。 - 恶意参数:
downloadUrl。这是承载攻击载荷的参数名。 - 攻击协议:
file://。这是将请求导向本地文件系统的“开关”。 - 攻击路径:如
/etc/passwd、c://windows/win.ini等。这是攻击者意图读取的目标。
注意:在实际攻击链中,攻击者可能会先利用另一个接口(如获取文件ID)进行信息搜集,再通过文件ID下载内容。但最核心、最直接的利用点,往往就是第一个发起文件读取请求的接口。
所以,这个漏洞的原理远不止“读取文件”,而是 “通过未经验证的文件协议参数,诱使服务器应用程序访问其本地文件系统” 。理解到这一层,我们提取防护特征时思路就会清晰很多:我们需要关注那些试图让服务器访问file://协议的请求。
2. 攻击特征提取:在流量中寻找“指纹”
知道了攻击原理,下一步就是在海量的网络流量中,如何像侦探一样找到带有恶意“指纹”的请求。我们不能简单地拦截所有访问/wxjsapi/saveYZJFile的请求,因为那可能是正常业务。我们必须找到正常业务不会出现,但攻击必然包含的特征组合。
基于上面的分析,我们可以提取出多层特征,这些特征组合在一起,就能构成一个高置信度的攻击判定规则:
第一层:基础请求特征
- 请求路径:包含
/wxjsapi/saveYZJFile。这是漏洞利用的固定入口点。 - 请求方法:通常为
GET。这类利用往往通过URL参数传递,简单直接。 - 关键参数名:URL查询字符串中存在
downloadUrl参数。
第二层:协议与路径特征(核心恶意载荷)
这是区分恶意请求与正常请求的关键。恶意请求的downloadUrl参数值会包含以下特征:
- 文件协议标识:以
file://或file:开头。这是最强烈的恶意信号。 - 敏感路径模式:
- Linux系统敏感文件:如
/etc/passwd,/etc/shadow,/proc/self/下的文件,以及应用自身的配置路径如/usr/ebridge/下的server.xml,my.ini,init.properties等。 - Windows系统敏感文件:如
c://windows/win.ini,c://boot.ini,以及盘符路径如d://ebridge/下的各类配置文件。
- Linux系统敏感文件:如
- 路径遍历尝试:虽然本例未直接展示,但同类漏洞中常伴随
../这样的路径遍历符,用于跳出当前目录。
第三层:上下文与行为特征(用于高级规则)
- 无Referer或异常Referer:攻击脚本发起的请求可能没有Referer头,或Referer头为恶意站点。
- 短时间内高频访问:攻击者可能会自动化扫描或尝试读取多个文件。
- 非常规User-Agent:使用工具默认的UA,如某些扫描器的标识。
对于编写基础的WAF/IDS规则,我们主要聚焦于第一层和第二层特征,因为它们最直接、误报率相对可控。我们可以将这些特征转化为一个结构化的观察清单:
| 特征层级 | 特征项 | 示例/说明 | 检测位置 |
|---|---|---|---|
| 请求行/路径 | URI路径 | /wxjsapi/saveYZJFile | REQUEST_URI |
| 请求方法 | GET | REQUEST_METHOD | |
| 查询参数 | 参数名称 | downloadUrl | QUERY_STRING |
| 参数值 | 文件协议 | file:// | ARGS:downloadUrl |
| Linux敏感路径 | /etc/passwd, /usr/ebridge | ARGS:downloadUrl | |
| Windows敏感路径 | c://windows, d://ebridge | ARGS:downloadUrl | |
| 路径遍历符 | ../ | ARGS:downloadUrl |
有了这份“指纹”清单,我们就可以着手打造我们的“检测器”了。
3. 规则编写实战:从正则表达式到规则引擎
不同的WAF/IDS系统规则语法不同,但其核心思想是相通的:定义条件,当流量匹配条件时,执行动作(如拦截、告警)。这里我们以最通用的正则表达式和ModSecurity规则为例,展示如何将特征转化为可执行的规则。
3.1 核心正则表达式设计
正则表达式是我们匹配攻击特征字符串的利器。我们需要为downloadUrl参数的值设计匹配模式。
一个基础但有效的正则表达式可以这样写:
(file:\/\/|file:).*(\/etc\/(passwd|shadow|hosts)|\\w:\\\\windows|\.\.\/|\\/usr\\/ebridge)
让我们拆解一下这个表达式:
(file:\/\/|file:):匹配file://或file:。这是攻击的起点。.*:匹配任意数量的任意字符(贪婪模式),用于填充协议头和敏感路径之间的部分。(\/etc\/(passwd|shadow|hosts)|\\w:\\\\windows|\.\.\/|\\/usr\\/ebridge):这是一个选择组,匹配多种敏感路径模式。\/etc\/(passwd|shadow|hosts):匹配经典的Linux系统敏感文件。\\w:\\\\windows:匹配Windows系统盘符下的windows目录(如c:\\windows)。\.\.\/:匹配路径遍历符../。\\/usr\\/ebridge:匹配泛微云桥在Linux上的典型安装路径。
提示:这个正则是一个示例,在实际环境中,你需要根据业务情况调整敏感路径列表。例如,如果你知道自己的应用配置存放在
/opt/app/config.xml,也应该将其加入监控。
3.2 ModSecurity (CRS) 规则示例
ModSecurity是一个开源的WAF引擎,其规则集(CRS)被广泛使用。下面是一条基于ModSecurity语法的防护规则:
SecRule REQUEST_URI “@rx /wxjsapi/saveYZJFile” \
“id:100001,\
phase:2,\
block,\
msg:’Potential e-Bridge Arbitrary File Read Attempt’,\
logdata:’Matched URI: %{REQUEST_URI}’,\
chain”
SecRule ARGS:downloadUrl “@rx (?i)(file:\/\/|file:).*(\/etc\/(passwd|shadow|hosts)|\\w:\\\\windows|\.\.\/|\\/usr\\/ebridge)” \
“setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\
setvar:tx.afd_counter=+1”
规则解读:
- 第一条规则(父规则):匹配请求URI是否包含漏洞路径
/wxjsapi/saveYZJFile。phase:2表示在请求体解析阶段进行检查。 chain动作:表示规则链,只有父规则匹配,才会继续检查子规则。- 第二条规则(子规则):检查
downloadUrl参数的值是否匹配我们设计的恶意正则表达式。(?i)表示忽略大小写。 - 执行动作:
block表示拦截请求。同时,增加异常分数 (anomaly_score) 和一个自定义的计数器 (afd_counter),用于后续可能的聚合分析。
3.3 云WAF/商业产品规则思路
对于阿里云WAF、腾讯云WAF或Imperva等产品,它们通常提供图形化界面或自定义规则字段。思路是一致的:
- 规则名称:
防护-泛微云桥任意文件读取漏洞 - 匹配条件:通常支持“且”、“或”逻辑。
- 条件1:
URL路径包含/wxjsapi/saveYZJFile - 条件2:
参数名等于downloadUrl - 条件3:
参数值正则匹配(file:\/\/|file:).*(\/etc\/(passwd|shadow|hosts)|\\w:\\\\windows|\.\.\/|\\/usr\\/ebridge)
- 条件1:
- 执行动作:
拦截或告警并拦截。 - 防护等级/策略:可设置为“紧急”或“高”。
4. 规则测试与验证:确保不误杀、不漏杀
规则写好了,直接上线是危险的。一条过于严格的规则可能会阻断正常业务(误报),一条过于宽松的规则则会放行攻击(漏报)。因此,测试环节至关重要。
4.1 搭建测试环境
理想情况是在与生产环境相似的测试环境中进行。如果条件有限,可以借助以下工具模拟:
- Burp Suite:手动构造和重放HTTP请求。
- curl命令:在命令行快速发起测试请求。
- 自定义脚本:用Python的requests库批量测试多种情况。
4.2 设计测试用例
我们需要设计两类测试用例:攻击用例和正常业务用例。
攻击用例(应被拦截):
- 用例1:基础利用
curl "http://test-target.com/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///etc/passwd&fileExt=txt" - 用例2:Windows路径利用
curl "http://test-target.com/wxjsapi/saveYZJFile?downloadUrl=file://c:/windows/win.ini" - 用例3:路径遍历尝试
curl "http://test-target.com/wxjsapi/saveYZJFile?downloadUrl=file:///usr/local/../../etc/passwd" - 用例4:大小写绕过尝试(测试规则是否大小写敏感)
curl "http://test-target.com/wxjsapi/saveYZJFile?downloadUrl=FILE:///etc/passwd"
正常业务用例(应被放行):
- 用例5:合法的HTTP/HTTPS URL参数(假设该接口本应处理网络文件)
curl "http://test-target.com/wxjsapi/saveYZJFile?downloadUrl=https://example.com/legit.pdf" - 用例6:访问同一路径的其他参数(无downloadUrl)
curl "http://test-target.com/wxjsapi/saveYZJFile?action=ping" - 用例7:路径相似但不同的正常接口
curl "http://test-target.com/wxjsapi/getUserInfo"
4.3 验证与调优
- 执行测试:在WAF/IDS的“检测”或“日志”模式下运行上述测试用例。
- 查看日志:检查攻击用例是否触发了规则并产生告警/拦截日志;正常用例是否被安静地放行。
- 分析误报/漏报:
- 如果正常业务被拦截:需要放宽规则条件。例如,是不是我们的正则匹配到了正常URL中的某些字符?可能需要更精确地限定
file://协议后的内容。 - 如果攻击请求未被拦截:需要收紧规则条件。例如,攻击者使用了
FILE:(大写)是否绕过了?我们的正则是否支持大小写?攻击者是否对路径进行了双重编码(..%252f)?
- 如果正常业务被拦截:需要放宽规则条件。例如,是不是我们的正则匹配到了正常URL中的某些字符?可能需要更精确地限定
- 迭代规则:根据测试结果,反复调整正则表达式或规则条件。这是一个持续优化的过程。
5. 规则维护与拓展:构建主动防御体系
编写一条规则应对一个漏洞只是开始。真正的安全运营,需要建立一个可持续的规则生命周期管理机制。
规则库分类管理:不要将所有自定义规则混在一起。建议按漏洞类型、应用系统或风险等级进行分类。例如:
APP_OA_Weaver_eBridge:存放所有与泛微云桥相关的防护规则。VULN_File_Read:存放针对各类任意文件读取漏洞的通用规则。POLICY_Block_File_Protocol:存放一条更通用的、拦截所有非业务必要的file://协议请求的策略规则(需谨慎评估业务影响)。
建立更新流程:当出现新的漏洞利用方式(例如,攻击者开始使用FILE://或对路径进行编码),需要及时更新现有规则。可以订阅安全厂商的威胁情报,或定期从应急响应中心(如CNVD、CNNVD)获取漏洞详情,分析其利用方式,并转化为规则。
从特征到情报:我们编写的这条规则,其核心是检测file://协议在特定接口的滥用。这个特征本身可以抽象为一种攻击意图:利用文件协议进行本地文件读取。我们可以将这个意图提炼出来,形成一个更通用的检测逻辑,应用于其他可能存在类似问题的接口上,实现从“针对一个漏洞”到“防御一类攻击”的跃升。
最后,我想分享一个实际踩过的坑。早期我们写规则时,只盯着/etc/passwd这样的绝对路径,结果攻击者稍微变通一下,先去读/proc/self/environ获取应用路径,再拼接路径去读配置文件,就绕过了我们的防御。所以,规则不是一劳永逸的咒语,而是需要根据攻击者的“招式”变化而不断演进的“活体”防御策略。最好的学习方式,就是像今天这样,从一个真实的案例出发,亲手分析、编写、测试,把死的规则变成你安全体系中有生命的一部分。
2384



被折叠的 条评论
为什么被折叠?



