泛微e9分析思路
字数 6303
更新时间 2026-05-15 02:41:22
泛微 Ecology 9 (e9) 漏洞分析实战教学文档
1. 前言与目标
本文档基于泛微 Ecology 9 (版本 9.00.210804 v10.42) 的漏洞分析实践整理而成。目标并非单纯复现漏洞,而是建立一套针对 e9 系统的分析方法论。
核心难点:
- e9 的安全补丁生效逻辑复杂,多层过滤机制导致漏洞利用常伴随“绕过”。
- 不同类型的路由(如
/weaver/*、/api/*、/services/*)拥有独立的鉴权与过滤逻辑。
本教学将引导读者从环境搭建开始,逐步深入分析各类漏洞的产生原因、绕过技巧及安全策略生效点。
2. 环境搭建与调试准备
2.1 基础环境
- 操作系统:Windows 11
- 数据库:MySQL 8.0.20(避免使用 8.0.12 以免初始化失败)
- 中间件:Resin
- JDK:自行指定路径
关键配置:
- 修改
my.ini配置文件(参考安装手册)。 - 数据库初始化耗时较长(约半小时),需耐心等待。
- Windows 服务中的 Resin 建议设为“手动”,通过
\Resin\resinstart.bat启动以便查看控制台输出。
2.2 IDEA 远程调试配置
- 导入项目:直接使用 IDEA 打开
ecology主目录。 - 添加依赖库:
- 进入项目结构,按住 Ctrl 依次点击相关依赖目录,右键选择“添加到库”。
- 注意:必须通过此方式添加,直接在项目结构中添加可能导致 Jar 包分析异常。
- 配置远程调试:
- 编辑
\Resin\conf\resin.properties,添加远程调试参数。
- 编辑
- 验证断点:
- 在
com.caucho.server.http.HttpRequest#handleRequest处打断点,确认能断下。 - 若
weaver.security.filter.SecurityMain#process反编译失败,需在idea64.exe.vmoptions中增加内存分配,并重启 IDEA。
- 在
3. 分析前置工作与信息收集
3.1 路由特征识别
通过分析 web.xml 及前人经验,总结出 e9 的核心路由分类:
/weaver/*/*.jsp/services/*(WebService)/api/*/*.do/dwr/*(Direct Web Remoting)
3.2 核心安全组件
- 主要过滤器:
SecurityFilter,SecurityMain - 安全策略文件:
WEB-INF/myclasses/weaver/security/rules/ruleImp(核心规则类目录)WEB-INF/securityRule
3.3 测绘指纹
- Fofa:
app="泛微-协同商务系统" - Hunter:
app.name=="泛微 e-cology 9.0 OA" - X 社区:
app="泛微-E-cology"
4. 核心漏洞分析与绕过实战
4.1 /weaver/* 路由:FileDownloadLocation 文件读取
4.1.1 漏洞原理
- 接口:
/weaver/weaver.email.FileDownloadLocation - 功能:通过
mailId参数读取 EML 文件,但由于逻辑缺陷,可通过 SQL 注入将敏感信息(如管理员密码)绑定到 HTTP 响应头(content-disposition的filename字段)中。 - 关键参数:
mailId需经过 DES 解密,且包含 User ID(通常为 1,代表管理员)。
4.1.2 SQL 变形与绕过分析
现象:直接请求接口会导致 SQL 语句中的 UNION SELECT 等关键字失效。
原因:
- 全局 XSS/SQL 过滤:
weaver.security.webcontainer.XssRequestForWeblogic#doFilter会对getParameter()获取的参数进行过滤。 - 过滤触发条件:
weaver.security.core.SecurityCore#isXssFilter方法检查请求路径是否匹配xssList中的规则。 - 绕过技巧:
- 原始 PoC 中的
/login/LoginSSOxjsp是关键。 - 因为
xssList中存在/login/LoginSSO.jsp,而.在正则matches中代表任意字符,因此LoginSSOxjsp能匹配成功。 - 匹配成功后,
isXssFilter返回false,从而跳过 HTMLFilter 过滤(该过滤器会将union select转换为全角字符)。
- 原始 PoC 中的
4.1.3 登录绕过分析
现象:直接访问 /weaver/... 会被重定向到登录页。
绕过逻辑 (SecurityMain#process):
- 静态资源判断:
process方法会判断是否为静态文件(如.jsp)。如果是且路径包含/api/或/weaver/等特定关键字,会强制跳转登录。- 坑点:
.jsp后缀会被拦截,但使用.mp4等非列表中的后缀可绕过此处的静态文件判断。
- 坑点:
- isLogin 逻辑:
SecurityMain#isLogin方法决定是否需要登录。- 若 URL 中包含
login、js、css等关键字,直接返回true(允许未登录访问)。 - 这也是 PoC 中使用
LoginSSOxjsp的另一个作用——满足isLogin条件。
- 若 URL 中包含
4.1.4 安全策略生效点 (RuleImp)
- 拦截点:
weaver.security.rules.ruleImp.SecurityRuleFileAlaPoc#validate - 规则:如果路径是
.jsp且后面紧跟着/(如.jsp/111),会被判定为非法请求并拦截。 - 结论:这就是为什么 PoC 中路径必须写成
/login/LoginSSOxjsp而不能随意添加后缀。
4.2 /weaver/* 路由:XmlRpcServlet 文件读取 (历史漏洞)
4.2.1 漏洞修复分析
该漏洞在新版本中被修复,修复点位于 SecurityMain#process 中的 sc.executeCustomRules。
修复逻辑:
weaver.security.rules.ruleImp.SecurityRuleHttpServlet#validate会校验调用的 Servlet 类是否属于weaver包。- 由于
XmlRpcServlet属于第三方库(非weaver包),因此被拦截,返回false,导致请求失败。
启示:这是 e9 的第二处核心安全策略生效点(遍历 ruleImp 目录下所有类的 validate 方法)。
4.3 /api/* 路由:Doc Out More List SQL 注入
4.3.1 接口定位
/api/*接口的映射关系不完全记录在\WEB-INF\Api.xls中。- 逆向手段:需反编译
\classbean\com目录下的 class 文件进行搜索。
4.3.2 漏洞复现
- 第一次请求:不带 Session,获取
sessionKey。 - 第二次请求:带上
sessionKey,通过修改doccreatedateto或doclastmoddateto参数构造布尔盲注。- 示例:
doccreatedateto=*/loginid,1,1)),'073') /*
- 示例:
4.3.3 鉴权机制 (SessionFilter)
- 过滤器:
com.cloudstore.dev.api.service.SessionFilter - 白名单机制:通过
checkUrl,uncheckUrl,uncheckSessionUrl进行控制。 - 配置来源:这些 URL 列表实际上是从
WEB-INF/prop目录下的配置文件中读取的。 - 攻击面:只有
uncheck系列的接口才是前台攻击面。
4.4 /services/* 路由:WorkPlanService SQL 注入
4.4.1 WebService 基础
- 技术:基于 XFire 的 SOAP WebService。
- 服务列表:访问
/services?wsdl或查看\classbean\META-INF\xfire\services.xml。
4.4.2 限制与利用
- 网络限制:默认情况下,该接口仅允许内网访问。
- 安全验证:默认开启安全验证,且通常无外网白名单。
- 分析重点:主要关注
services.xml中定义的服务类及其实现方法。
4.5 /dwr/* 路由:前台绕过与 RCE
4.5.1 DWR 技术简介
DWR (Direct Web Remoting) 允许 JavaScript 直接调用 Java 方法。
4.5.2 路由逻辑分析
- 入口:
DwrServlet(配置于web.xml)。 - 参数解析:
org.directwebremoting.dwrp.BaseCallMarshaller#marshallInboundc0-scriptName: 要调用的类名 (如WorkflowSubwfSetUtil)c0-methodName: 要调用的方法名 (如LoadTemplateProp)c0-param0: 方法参数
- 可调用性校验:
- 必须是
public方法。 - 方法参数类型不能以
org.directwebremoting.开头。 - 某些类限制了可调用的特定方法。
- 必须是
4.5.3 利用前提
- 较新版本中,许多 SQL 注入点已修复,且大部分高危方法需要有效的 Session 才能调用。
4.6 *.jsp 路由:browser.jsp SQL 注入
4.6.1 漏洞原理
- 参数:
isDir=1,keyword,browserTypeId=269 - 注入点:最终在
weaver.general.SplitPageUtil#getCurrentPageRs执行 SQL。
4.6.2 编码绕过分析
现象:PoC 中使用了 %20 (空格) 进行绕过。
原因分析:
- 容器特性:Resin 中间件在处理路径时,
getServletPath()会自动忽略%20,而getRequestURI()保留原样。 - 安全策略绕过:安全规则(如
SecurityRuleMobile29)通常匹配/mobile/plugin/browser.jsp。- 当路径变为
/mobile//plugin/browser.jsp(双斜杠) 时,由于不匹配预设规则,且安全策略未拦截//,从而导致绕过。
- 当路径变为
5. 核心安全组件深度解析:SecurityMain
SecurityMain#process 是整个 e9 安全体系的心脏。
5.1 执行流程
- 自定义规则执行 (第一处):
this.executeCustomRules(): 遍历固定的几个安全规则(如静态文件判断)。
- URL 路径校验:对路径进行标准化处理并校验。
- 自定义规则执行 (第二处):
SecurityCore.executeCustomRules(): 遍历WEB-INF\myclasses\weaver\security\rules\ruleImp下所有.class文件的validate方法。- 这是绝大多数补丁生效的地方。
- 登录校验:
isLogin(): 判断当前路径是否允许未登录访问(通过关键词匹配或静态文件列表)。
5.2 关键方法:isLogin()
- 逻辑:如果 URL 包含
login、js、css、images、mp4等,直接返回true。 - 注意:
process方法内的静态文件列表与isLogin内的列表不完全一致。
6. 1day 漏洞挖掘思路
针对 e9 的高效漏洞挖掘方法:
- 增量补丁对比:
- 从官网下载最新的增量补丁包。
- 重点关注
\WEB-INF\myclasses\weaver\security\rules\ruleImp目录下新增的.class文件。
- 全量补丁对比:
- 对比相邻版本的两个全量补丁,分析
ruleImp目录的变化。
- 对比相邻版本的两个全量补丁,分析
- 逆向分析:
- 对新出现的
Rule类进行反编译,分析其validate方法拦截了哪些路径或参数,这些被拦截的点往往就是漏洞所在。
- 对新出现的
7. 总结与关键点回顾
- 全局参数过滤:
XssRequestWeblogic会对所有getParameter()获取的 GET/POST 参数进行过滤,绕过的关键在于路径匹配 (isXssFilter)。 - 路由差异:
/weaver/*:逻辑最复杂,涉及isLogin和process静态文件判断。/api/*:受SessionFilter约束,白名单在/prop配置文件。/services/*:默认内网访问,需分析services.xml。/dwr/*:可直接调用 Java 方法,但有方法签名和权限限制。
- 安全策略生效点:
SecurityMain#process中的两个executeCustomRules。ruleImp目录下的所有规则类。
- 绕过核心:
- 路径混淆:利用
/login/LoginSSOxjsp绕过 XSS 过滤和登录校验。 - 编码与分隔符:利用
%20或//绕过字符串匹配型的安全规则。 - 后缀利用:利用非黑名单后缀(如
.mp4)绕过静态文件登录跳转。
- 路径混淆:利用
8. 附录:关键资源索引
- 后端接口文档:
https://e-cloudstore.com/ec/api/applist/index.html#/ - 安全补丁下载:
https://www.weaver.com.cn/cs/securityDownload.html - E9 后端开发指南:
https://e-cloudstore.com/e9/file/E9BackendDdevelopmentGuide.pdf - 审计参考 (核心):
https://github.com/ax1sX/SecurityList/blob/main/Java_OA/EcologyAudit.md - 漏洞复现参考:
https://xz.aliyun.com/news/18849(dwr 绕过),https://xz.aliyun.com/news/14777(WorkPlanService)
相似文章
相似文章