HackTheBox: Sink Machine (insane difficulty) Walkthrough

HackTheBox: Sink Machine Walkthrough

A complete guide to pwning an Insane-rated box featuring HTTP Request Smuggling, Gitea source code analysis, and AWS KMS exploitation

INSANE Linux CVE-2019-18277
PropertyValue
MachineSink
OSLinux
DifficultyInsane
IP10.10.10.225
Key TechniquesHTTP Request Smuggling, Gitea Credential Harvesting, AWS Secrets Manager, AWS KMS Decryption
CVEsCVE-2019-18277 (HAProxy HTTP Request Smuggling)

Attack Chain Overview

Nmap Recon HTTP Smuggling (HAProxy + Gunicorn) Session Hijacking Credential Extraction from Notes Gitea Source Code Review SSH Key + AWS Keys from Commits SSH as marcus AWS Secrets Manager → su david AWS KMS Decrypt → Root

1. Reconnaissance & Port Scanning

The initial phase involves scanning the target to map the attack surface. A standard Nmap service scan reveals three interesting open ports:

nmap -sC 10.10.10.225
Nmap scan report for 10.10.10.225
Host is up (0.26s latency).
Not shown: 997 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
| ssh-hostkey: 
|   3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_  256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
3000/tcp open  ppp
5000/tcp open  upnp
Nmap scan results showing ports 22, 3000, and 5000 open on HackTheBox Sink machine
Fig 1: Nmap scan revealing SSH (22), Gitea (3000), and a web application (5000)
Initial Observations:
  • Port 22 - SSH (standard, likely for shell access after credential discovery)
  • Port 3000 - Gitea instance (source code hosting - high-value target for secrets)
  • Port 5000 - Web application (our initial attack vector)

2. Web Application Analysis (Port 5000)

The web application running on port 5000 is a note-taking platform with two key features:

  • User Registration - anyone can create an account
  • Note Management - authenticated users can create and delete notes
Sink web application homepage on port 5000 with note-taking functionality
Fig 2: The note-taking web application on port 5000
Sink signup form allowing user registration
Fig 3: Open registration - any user can create an account
Note submission interface in the Sink web application
Fig 4: Note submission and deletion interface after authentication

Intercepting Requests

Capturing the note submission request reveals critical information about the server architecture in the response headers:

Burp Suite intercepted request showing HAProxy and Gunicorn headers
Fig 5: Response headers reveal HAProxy (reverse proxy) and Gunicorn/20.0.0 (backend server)
Key Discovery: The response exposes a HAProxy reverse proxy fronting a Gunicorn 20.0.0 backend. This exact combination is vulnerable to HTTP Request Smuggling via CVE-2019-18277.

3. HTTP Request Smuggling (CVE-2019-18277)

Understanding the Vulnerability

HTTP Request Smuggling exploits the discrepancy in how frontend (HAProxy) and backend (Gunicorn) servers parse HTTP requests. The core issue:

ComponentParsesIgnores
HAProxy (frontend)Content-LengthTransfer-Encoding
Gunicorn (backend)Transfer-EncodingContent-Length

This is a classic CL.TE (Content-Length vs Transfer-Encoding) desync attack. When both headers are present in a single request:

  1. HAProxy reads Content-Length, forwards what it thinks is one complete request
  2. Gunicorn reads Transfer-Encoding: chunked, interprets the body differently
  3. The leftover bytes from the "smuggled" portion get prepended to the next legitimate request from another user
Why is this dangerous? The smuggled content gets combined with the next user's request. By crafting the smuggled portion as a POST to the notes endpoint, the victim's entire HTTP request (including session cookies) gets captured as a note in our account.

Executing the Attack

The crafted smuggling payload injects a POST request to /notes that will capture the next user's request headers:

HTTP request smuggling payload crafted for HAProxy and Gunicorn desync on Sink machine
Fig 6: The CL.TE smuggling payload - the smuggled request will capture the next user's session
Smuggled request captured in notes showing another user session cookie
Fig 7: The smuggled request gets combined with the next legitimate request, captured in our notes

4. Credential Extraction via Session Hijack

Using the captured session cookie from the smuggled request, we gain access to an admin account's notes:

Stolen admin session cookie used to access privileged notes on Sink
Fig 8: Using the hijacked session cookie to view the admin's /notes endpoint
Jackpot! The admin's notes contain plaintext credentials for three internal services:

Credential Set 1 - Chef

ServiceURLUsernamePassword
Chefhttp://chef.sink.htbchefadm/6'fEGC&zEx{4]zz
Chef admin credentials found in stolen notes
Fig 9: Chef admin credentials in plaintext

Credential Set 2 - Dev Node (Gitea)

ServiceURLUsernamePassword
Dev Nodehttp://code.sink.htbrootFaH@3L>Z3})zzfQ3
Gitea root credentials found in stolen notes
Fig 10: Gitea root credentials - this gives us access to source code

Credential Set 3 - Nagios

ServiceURLUsernamePassword
Nagioshttps://nagios.sink.htbnagios_admg8<H6GK\{*L.fB3C
Nagios monitoring credentials found in stolen notes
Fig 11: Nagios monitoring credentials

5. Gitea Repository Analysis (Port 3000)

Using the Dev Node credentials (root:FaH@3L>Z3})zzfQ3), we authenticate to the Gitea instance on port 3000:

Gitea dashboard after login with stolen credentials on Sink HTB
Fig 12: Authenticated access to Gitea with the stolen root credentials
Gitea repositories list showing Key_Management and Log_Management repos
Fig 13: Available repositories - Key_Management and Log_Management are high-value targets

Finding 1: SSH Private Key in Key_Management

The Key_Management repository contains a commit history with an exposed OpenSSH private key for user marcus:

Key_Management repository commit history showing SSH key leak
Fig 14: Key_Management repo commit history - SSH keys were committed
Marcus SSH private key (id_rsa) exposed in Gitea commit
Fig 15: Full OpenSSH private key for user marcus found in commit history

Finding 2: AWS Credentials in Log_Management

The Log_Management repository contains a commit that leaks AWS access keys:

AWS access key and secret key leaked in Gitea commit history
Fig 16: AWS credentials (Access Key ID + Secret Access Key) leaked in a commit
Critical Findings from Gitea:
  • SSH private key for user marcus - direct shell access
  • AWS credentials - access to cloud services (Secrets Manager, KMS)

6. User Shell: SSH as Marcus

Save the extracted private key and SSH into the box as marcus:

chmod 600 dev_keys
ssh -i dev_keys marcus@10.10.10.225
SSH login as marcus user on Sink HTB machine
Fig 17: SSH access as marcus using the extracted private key
User flag captured! We now have a foothold on the box as marcus.

7. Lateral Movement: AWS Secrets Manager

Configure the AWS CLI with the credentials found in the Gitea commit history:

aws configure
# Enter the leaked Access Key ID and Secret Access Key
# Region: us-east-1
# Output: json
AWS CLI configuration with leaked credentials on Sink
Fig 18: Configuring AWS CLI with the leaked credentials
Note: AWS Secrets Manager allows developers to store credentials securely instead of hardcoding them. The local endpoint http://127.0.0.1:4566 indicates LocalStack is being used to simulate AWS services.

Enumerating Secrets

aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager list-secrets
AWS Secrets Manager listing showing Jenkins, Sink Panel, and Jira secrets
Fig 19: Three secrets discovered in AWS Secrets Manager

Three secrets are available:

#Secret ARN
1arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-nnEwi
2arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-puoRL
3arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-dxAXV

Extracting Secret Values

aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value \
  --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jenkins Login-nnEwi"
Jenkins Login secret value extracted from AWS Secrets Manager
Fig 20: Jenkins Login credentials extracted
aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value \
  --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Sink Panel-puoRL"
Sink Panel secret value extracted from AWS Secrets Manager
Fig 21: Sink Panel credentials extracted
aws --endpoint-url="http://127.0.0.1:4566/" secretsmanager get-secret-value \
  --secret-id "arn:aws:secretsmanager:us-east-1:1234567890:secret:Jira Support-dxAXV"
Jira Support secret value extracted from AWS Secrets Manager
Fig 22: Jira Support credentials extracted

8. User Shell: Pivoting to David

Checking the system users, we discover another user david:

System user david discovered on Sink machine
Fig 23: User david exists on the system

One of the extracted secret passwords works for david:

su david
Successful su to david user using AWS Secrets Manager password
Fig 24: Successfully switched to david using credentials from Secrets Manager

In david's home directory, we find ~/Projects/Prod_Deployment/servers.enc - an encrypted file that will lead us to root.


9. Privilege Escalation: AWS KMS Decryption

AWS Key Management Service (KMS) provides encryption and decryption capabilities. Since we have AWS credentials configured, we can leverage KMS to decrypt servers.enc.

Step 1: List Available KMS Keys

aws --endpoint-url="http://127.0.0.1:4566/" kms list-keys
AWS KMS list-keys showing multiple encryption key IDs
Fig 25: Multiple KMS keys available - we need to find which one encrypted our file

Step 2: Extract Key IDs

aws --endpoint-url="http://127.0.0.1:4566/" kms list-keys | grep "KeyId" | cut -d '"' -f4 > key.txt
Extracted KMS key IDs saved to file for brute force decryption
Fig 26: Key IDs extracted for systematic decryption attempts

Step 3: Brute-Force Decryption

Since we don't know which key was used to encrypt the file, we iterate through all available keys:

for key in $(cat key.txt); do
  aws --endpoint-url="http://127.0.0.1:4566/" kms enable-key --key-id "${key}"
  aws kms decrypt \
    --ciphertext-blob "fileb:///home/david/Projects/Prod_Deployment/servers.enc" \
    --endpoint-url="http://127.0.0.1:4566/" \
    --key-id "$key" \
    --encryption-algorithm "RSAES_OAEP_SHA_256" \
    --output text \
    --query Plaintext > "$key.out"
done

One key successfully decrypts the file, producing base64-encoded output:

Successful KMS decryption output showing base64 encoded data
Fig 27: Key 804125db-bdf1-465a-a058-07fc87c0fad0 successfully decrypts the file

Step 4: Decode and Extract

# Decode the base64 output
cat 804125db-bdf1-465a-a058-07fc87c0fad0.out | base64 -d > encoded

# Check file type
file encoded
# Output: gzip compressed data
Decrypted file identified as gzip compressed data
Fig 28: The decrypted file is gzip-compressed
# Extract the gzip file
mv encoded encoded.gz
gzip -d encoded.gz
Extracted credentials showing admin password for root access
Fig 29: The decrypted file contains admin credentials
Root credentials found! The decrypted servers.enc file contains the root password in plaintext.

10. Root Shell

su root
# Enter the password from the decrypted file
Root shell access achieved on HackTheBox Sink machine
Fig 30: Root access achieved - machine fully compromised
Machine Pwned! Full root access obtained on Sink.

11. Key Takeaways & Lessons Learned

Vulnerabilities Exploited

StageVulnerabilityImpactMitigation
Initial Access HTTP Request Smuggling (CVE-2019-18277) Session hijacking, credential theft Ensure consistent HTTP parsing between proxy and backend; update HAProxy
Credential Theft Plaintext credentials in application notes Access to multiple internal services Use a proper secrets manager; never store passwords in notes
Source Code Exposure SSH keys and AWS credentials in Git commits Shell access + cloud service compromise Use git-secrets or trufflehog to prevent credential commits; rotate leaked keys
Lateral Movement Password reuse from AWS Secrets Manager Pivot from marcus to david Principle of least privilege; unique passwords per service
Privilege Escalation Unrestricted AWS KMS access + encrypted admin creds Root access via decrypted credentials Restrict KMS key policies; don't store root passwords in encrypted files accessible to regular users

Tools Used

  • Nmap - port scanning and service enumeration
  • Burp Suite - HTTP request interception and smuggling payload crafting
  • Gitea - source code and commit history analysis
  • AWS CLI - Secrets Manager enumeration and KMS decryption
  • SSH - remote shell access with extracted private key

References


Written by 0xMMN | HackTheBox Walkthrough Series
If you found this useful, check out my other writeups and follow for more security content.

Popular posts from this blog