Hack the Box Bagel Walkthrough

D3u5Vu1t
6 min readJun 22, 2023

--

A guide to hacking the HTB Bagel box

Bagel Card

Today’s guide will walk you through how to complete Hack The Box’s Squashed box. The box can be found here.

Enumeration

First step is to run some scans to find out as much as we can about the machine. We can start with the following nmap command:

nmap -sV -sC -oA initial <IP>
Initial nmap scan

We can see that following ports are open:

  • 22 ssh: If we can acquire credentials we will be able to remotely login.
  • 5000: Unsure what service is running on this port. It could be an API or websocket of some kind. It may be important later.
  • 8000 HTTP: A webserver that can be enumerated further. Could lead to a foothold.

I looked at port 5000 and the only information I could find is that this box is using dotnet.

Linux server running dotnet

When I tried to connect to the website it redirected me to http://bagel.htb. For us to access the site we need to add a reference to the /etc/hosts file:

Add bagel.htb to hosts file

With the hosts file updated we can access the Bagel page on port 8000.

Bagel.htb port 8000 home page

I noticed that the redirected url contains page=index.html. Since the url contains that I tested for local file inclusion (LFI). This is where permissions are not approprieately assigned and files on the webserver that were not inteded to be accessed are accessible. To do this I tried the following url:

http://bagel.htb:8000/?page=../../../../../etc/passwd
Local File Inclusion on main page allows for us to read /etc/passwd

The server is vulnerable to LFI and we get the contents of the /etc/passwd file. Since the operating system is Linux we can access process information in the /proc directory. Self is an alias for the PID of the currently running process so we can list /proc/self/cmdline.

Accessing /proc/self/cmdline directory to see running commands

We see an app exists in /home/developer/app/ directory. Let’s view the contents of the file.

list contents of app.py

The note at the bottom states Don’t forget to run the order app first with “dotnet <path to .dll>” command. Use your ssh key to access the machine. We maybe able to access the ssh key if we can find they are mentioning. Below we can see that this is the service running on port 5000. Understanding the dll could allow us to interact with the service.

Port 5000 service

In the screenshot above also shows the syntax of how to interact with the websocket. We can use a tool called wscat to interact with it. We can use the following command to connect to the websocket.

wscat -c ws://<ip>:5000

Once the connection has been established we can pass the order information to it and see if we get a response.

{"ReadOrder":"orders.txt"}
Successful response from the websocket

To find the dll file we can list information about the current running processes. If we find the process ID (PID) for the service it will disclose the location of the dll file. To do this we can read the /proc/PID/cmdline file where the PID matches the service using the dll. Information on the file can be found here. Since we do not know what PID the service is running on we can write a quick script to try all PID’s between 1 and 1000.

The python script can be seen below.

Python script to look at every PID between 1 and 1000

If the PID does not exist we will be greeted with a File not Found error. If the PID does exist we will get a file location. We can use this to filter out all responses that do not contain a /.

Location of the bagel.dll file

We have found the location of the dll file. Now we can download it and view it.

Download bagel.dll

dnSpy is a tool we can use to get view the contents of the dll file.

The first thing I found was a clear text password. I tried to connect via ssh but it did not work. This could be useful later:

clear text password

Exploitation

JsonSeralizer in dll file

I searched through the contents of the files and found something interesting. I googled JsonSearializerSettings TypeNameHandling and found the article below.

We may be able to deserialize the information and view it in clear text. This could give us the ssh key we needed. We can try to access a file via the websocket using the following command:

{"RemoveOrder":{"$type" : "bagel_server.File, bagel", "ReadFile":"../../../../../etc/passwd" }}

We are creating a file object and then setting the contents to the file we want. The RemoveOrder field is not being used so we can try to use that.

Access File Test via websockets

We are able to access the /etc/passwd file this way. Now we can try to get an ssh key.

{"RemoveOrder":{"$type" : "bagel_server.File, bagel", "ReadFile":"../../../../../phil/.ssh/id_rsa" }}
Phil ssh private key

We need to put the key into a file, we can use echo -n to correctly format it.

Format id_rsa key

We need to change the permissions of the file to 600.

chmod 600 id_rsa

Now the key can be used to log in.

SSH login using private key

Privilege Escalation

The first thing I tried was the password we saw in the dll for the dev user.

SU to developer user

Now we need root. We can use sudo -l to see if we have sudo permissions. The developer user has sudo access to donet. Using GTFO bins we can see that it is possible to escalate our privilege with this.

Root via dotnet

Thank you for joining me through this journey, I hope you had fun and learned something. Feel free to reach out to me if you have any questions. You can find me at the following links:

LinkedIn: https://www.linkedin.com/in/seth-mccoun-353669163

Twitter: https://twitter.com/seth_mccoun

--

--