## https://sploitus.com/exploit?id=07475DB5-835F-5DD6-BF42-BCF4088E9F57
# CVE-2025-55423 โ ipTIME UPnP Command Injection: Analysis & Reproduction
A full reverse-engineering and reproduction walkthrough of **CVE-2025-55423**, a command-injection vulnerability in ipTIME router firmware (model A604M) reachable through the UPnP `upnp_relay` code path. This repository documents the complete process โ from firmware extraction and static analysis, through open-source (`miniupnpc`) chain tracing, to a fake SSDP/HTTP attacker server and a QEMU mipsel **user-mode** proof that an attacker-controlled string reaches the command-injection sink.
> **This is a learning-oriented reproduction of an already-published, patched CVE, performed entirely in a controlled emulation environment.** It deliberately does **not** include the network-takeover stage (DHCP hijack / ARP spoofing automation), which is a generic MITM technique rather than a property of this CVE. See [DISCLAIMER.md](DISCLAIMER.md).
## TL;DR โ what was proven
1. **Attacker payload reaches `igd_url`.** A fake SSDP + HTTP server, answering the two SOAP probes (`GetStatusInfo`, `GetExternalIPAddress`) that `miniupnpc`'s `UPNP_GetValidIGD` issues, makes the firmware's own `upnpc` print:
```
Found valid IGD : http://10.0.11.234:8080/87895a19/upnp/control/WANIPConn1;PWNED
```
The `;PWNED` marker is the attacker-controlled `controlURL`, carried through verbatim.
2. **Payload reaches the command sink.** Planting that value via `istatus_set_value_direct("igd_url", ...)` โ the same function `discover_upper_upnp_igd` calls โ and invoking `upnp_relay`, gdb confirms the payload lands in `system`'s argument register (`A0`):
```
*A0 โโ '/sbin/upnpc -u http://1.2.3.4/x;echo hello world > /tmp/pwn;# -m 1.2.3.4 -d 8080 tcp >/dev/null 2>&1'
โบ system+24 beqz $a0, system+48
```
Command injection at `system` is therefore proven. (Actual `/bin/sh` execution is blocked only by QEMU user-mode's `fork` limitation โ system-mode would complete it.)
## The vulnerability in one paragraph
ipTIME is a SOHO router in a double-NAT topology. When a LAN client requests a port-forward, ipTIME (acting as a UPnP **Control Point**) must delegate the mapping to the upstream router (the **Device/IGD**), so it multicasts `M-SEARCH` out the **WAN** interface and trusts the description XML it receives. `discover_upper_upnp_igd` runs the firmware's `upnpc`, scrapes the `Found valid IGD : ` line, and stores `` as `igd_url`. `upnp_relay` later composes that unvalidated `igd_url` into a string passed to `system2()` โ `system()` โ yielding root RCE. An attacker on the WAN side who can impersonate the upstream IGD controls that URL.
## Documentation
| # | Doc | Contents |
|---|-----|----------|
| 01 | [Background](docs/01-background.md) | UPnP, ARP spoofing, double-NAT, the essence of the flaw |
| 02 | [Attack Scenario](docs/02-attack-scenario.md) | The 3-phase scenario (recon, DHCP manipulation, reboot induction) |
| 03 | [Vulnerable Function Analysis](docs/03-vuln-analysis.md) | Locating & decompiling `upnp_relay`; the injection sink |
| 04 | [Chain Analysis](docs/04-chain-analysis.md) | `discover_upper_upnp_igd` + tracing the `miniupnpc` chain to `UPNP_GetValidIGD` |
| 05 | [Attacker Server Setup](docs/05-server-setup.md) | Fake SSDP server, fake HTTP server, the two SOAP probes |
| 06 | [RCE Trigger](docs/06-rce-trigger.md) | Dependency analysis, QEMU user-mode harness, 4-round gdb debugging |
## Repository layout
```
.
โโโ README.md
โโโ DISCLAIMER.md
โโโ docs/ # 01โ06, the full writeup
โโโ exploit/
โโโ ssdp_server.py # answers M-SEARCH with a LOCATION pointing at our HTTP server
โโโ http_server.py # serves attacker.xml (GET) + two SOAP responses (POST)
โโโ attacker.xml # description XML with payload in the first controlURL
โโโ call_rce.c # QEMU user-mode harness (dlopen-based)
โโโ stub.c # overrides hardware-dependent WAN probes
```
## Reproducing (controlled lab only)
**1. Extract the firmware** โ obtain the A604M firmware from ipTIME's official site and extract it yourself. The firmware binaries (`libcgi.so`, `libuserland.so`, etc.) are **not** redistributed here for copyright reasons.
```bash
binwalk -e a604m_kr_10_064.bin
cd _a604m_kr_10_064.bin.extracted/squashfs-root
```
**2. Stand up the attacker servers** (separate terminals):
```bash
sudo python3 exploit/ssdp_server.py # answers M-SEARCH
python3 exploit/http_server.py # serves attacker.xml + SOAP
# verify with: upnpc -P โ "Found valid IGD : ...;PWNED"
```
**3. Build & run the user-mode harness:**
```bash
mipsel-linux-gnu-gcc -shared -fPIC -o stub.so exploit/stub.c
mipsel-linux-gnu-gcc -o call_rce exploit/call_rce.c -ldl \
-Wl,--dynamic-linker=/glibc/ld.so.1 -Wl,-rpath=/glibc:/lib
cp call_rce stub.so . # into squashfs-root
sudo mkdir -p var/run && sudo chmod 777 var var/run
sudo cp /usr/bin/qemu-mipsel-static usr/bin/
sudo chroot . /usr/bin/qemu-mipsel-static /call_rce
```
> Replace the `touch`/`echo` payloads in `call_rce.c` and `attacker.xml` with a benign marker of your choosing.
## Toolchain
`binwalk` ยท `Ghidra` ยท `qemu-mipsel-static` ยท `mipsel-linux-gnu-gcc` ยท `tcpdump` ยท `pwndbg`/multi-arch gdb ยท Python 3. Reference for `miniupnpc`: .
## Credit
Original CVE: . This repository is an independent analysis & reproduction for study purposes.