Research / Article

Hacking the Java Debug Wire Protocol - or - “How I met your Java debugger”

Discover techniques for hacking the Java Debug Wire protocol and turning JDWP services into reliable code execution methods.

Christophe AlladoumJDWPhackinfosecjava debugger
Hacking the Java Debug Wire Protocol - or - “How I met your Java debugger”
  • It is a packet-based network binary protocol.
  • It is mostly synchronous. The debugger sends a command over JDWP and expects to receive a reply. However, some commands, like Events, do not expect a synchronous response. They will send a reply when specific conditions are met. For example, a BreakPoint is an Event.
  • It does not use authentication.
  • It does not use encryption.

An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response.

  • VirtualMachine/IDSizes defines the size of the data structures handled by the JVM. This is one of the reasons why the nmap script jdwp-exec.nse[11] does not work, since the script uses hardcoded sizes.
  • ClassType/InvokeMethod allows you to invoke a static function.
  • ObjectReference/InvokeMethod allows you to invoke a function from an instantiated object in the JVM.
  • StackFrame/(Get|Set)Values provides pushing/popping capabilities from threads stack.
  • Event/Composite forces the JVM to react to specific behaviors declared by this command. This command is a major key for debugging purposes as it allows, among many other things, setting breakpoints, single-stepping through the threads during runtime, and being notified when accessing/modifying values in the exact same manner as GDB or WinDBG.
  • VirtualMachine/CreateString allows you to transform a string into a java.lang.String living in the JVM runtime.
  • VirtualMachine/RedefineClasses allows you to install new class definitions.
  • “Default” mode is totally non intrusive and simply executes Java code to get local system information (perfect for a PoC to a client).
  • Passing the “cmd” option executes a system command on the remote host and is therefore more intrusive. The command is done with the privileges the JVM is running with.
  • Oracle Java JDK 1.6 and 1.7
  • OpenJDK 1.6
  • IBM JDK 1.6
  • At the time of writing this article, a quick search on ShodanHQ[4] immediately reveals about 40 servers sending the JDWP handshake:
  • GitHub[7] also reveals a significant number of potentially vulnerable open-source applications:
  • masscan-ing the Internet looking for specific ports (tcp/8000, tcp/8080, tcp/8787, tcp/5005) revealed many hosts (which cannot be reported here) responding to the initial handshake.
  • “Enterprise” applications were found in the wild running a JDWP service *by default* (finding the actual port number is left as an exercise to the curious reader).
  1. https://github.com/IOActive/jdwp-shellifier
  2. http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html
  3. http://www.secdev.org/projects/scapy(no longer active)
  4. http://www.shodanhq.com/search?q=JDWP-HANDSHAKE
  5. http://www.hsc-news.com/archives/2013/000109.html (no longer active)
  6. http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt
  7. https://github.com/search?q=-Xdebug+-Xrunjdwp&type=Code&ref=searchresults
  8. http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html
  9. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html
  10. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html
  11. http://nmap.org/nsedoc/scripts/jdwp-exec.html

Want the research before the news cycle?

Get in touch