HackTheBox: Shoppy

OS: Linux
Difficulty: Easy
Review: 4.8/5
Description:
Shoppy is an easy Linux machine that features a website with a login panel and a user search functionality, which is vulnerable to NoSQL injection. It can be exploited to obtain the password hashes of all the users. Upon cracking the password hash for one of the users we can authenticate into the Mattermost chat running on the server where we obtain the SSH credentials for user `jaeger`. The lateral movement to user `deploy` is performed by reverse engineering a password manager binary, which reveals the password for the user. We discover that the user `deploy` is a member of the group `docker`. Its privileges can be exploited to read the root flag.
Recon:
As part of my usual recon, we can break out "Rustscan" and my "Demon" wrapper to create a clean Markdown table.
Rustscan output:
rustscan -a $IP -n --ulimit 70000 -t 5000 -- -A -Pn
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 9e5e8351d99f89ea471a12eb81f922c0 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDApZi3Kltv1yDHTatw6pKZfuIcoHfTnVe0W1yc9Uw7NMUinxjjQaQ731J+eCTwd8hBcZT6HQwcchDNR50Lwyp2a/KpXuH2my+2/tDvISTRTgwfMy1sDrG3+KPEzBag07m7ycshp8KhrRq0faHPrEgcagkb5T8mnT6zr3YonzoMyIpT+Q1O0JAre6GPgJc9im/tjaqhwUxCH5MxJCKQxaUf2SlGjRCH5/xEkNO20BEUYokjoAWwHUWjK2mlIrBQfd4/lcUzMnc5WT9pVBqQBw+/7LbFRyH4TLmGT9PPEr8D8iygWYpuG7WFOZlU8oOhO0+uBqZFgJFFOevq+42q42BvYYR/z+mFox+Q2lz7viSCV7nBMdcWto6USWLrx1AkVXNGeuRjr3l0r/698sQjDy5v0GnU9cMHeYkMc+TuiIaJJ5oRrSg/x53Xin1UogTnTaKLNdGkgynMqyVFklvdnUngRSLsXnwYNgcDrUhXxsfpDu8HVnzerT3q27679+n5ZFM=
| 256 5857eeeb0650037c8463d7a3415b1ad5 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHiKrH/B/4murRCo5ju2KuPgkMjQN3Foh7EifMHEOwmoDNjLYBfoAFKgBnrMA9GzA+NGhHVa6L8CAxN3eaGXXMo=
| 256 3e9d0a4290443860b3b62ce9bd9a6754 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBRsWhJQCRHjDkHy3HkFLMZoGqCmM3/VfMHMm56u0Ivk
80/tcp open http syn-ack nginx 1.23.1
|_http-server-header: nginx/1.23.1
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://shoppy.htb
9093/tcp open copycat? syn-ack
| fingerprint-strings:
| GenericLines:
Demon Wrapper:
Demon
Enter the target IP or domain for rustscan: 10.129.227.233
| Port | Status | Service | Description |
|------------|--------|-----------------|-------------|
| 22/tcp | open | ssh | OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0) |
| 80/tcp | open | http | nginx 1.23.1 |
| 9093/tcp | open | http | Golang net/http server |
Based on the open ports, this appears to be a web server, and the method of entry will most likely involve some form of web exploitation to gain access or disclose information. We can also note that the Golang server might provide additional functionality that could help us gain access.
HTTP enumeration:
Looking into the site, we can see that it appears to be an eCommerce platform currently in beta and scheduled for release at a later date.

FFuF:



FFuFing Directories, files, Vhosts
Using FFuF, we discovered an admin page and attempted a few generic logins, but none of them granted access.

Port 9093:
Navigating to port 9093, we can see what appear to be Go logs. Looking further into the logs, we can identify possible plugin versions.

However, further research into this did not yield any additional access.
Verbose FFuF:
With limited access gained, I chose to run FFuF again using a more verbose wordlist.

Luckily, we found another virtual host, which we can add to /etc/hosts
.

/etc/host
entryMattermost.shoppy.htb:
Navigating to the new subdomain, we can see what appears to be a Mattermost login page.

Using BurpSuite to analyze the authentication mechanism, I observed a JSON POST request, which immediately led me to suspect a possible NoSQLi vulnerability.

With this in mind, I tested a few NoSQLi authentication bypass techniques; however, these attempts did not result in access.
Shoppy.htb Admin access:
Seeing the potential NoSQLi on Mattermost led me to test for a NoSQL bypass on the admin page. Before approaching this, I conducted some research and found a great reference page here.
The following is a summary of the referenced article:
A basic JavaScript NoSQL query in the backend code of a login panel might look like this:
this.username === '${value}' && this.password === '${value}'
If we assume the user is admin, we can attempt to bypass this query using the following payload:
admin' || '' === '
This payload will cause the query to look as follows under the hood once the values are substituted:
this.username === 'admin' || '' === '' && this.password === 'value'
Testing this theory with BurpSuite, we were able to gain access.

Once logged in, we can see a list of products. Notably, a smartphone is listed at only $200, which is unusually cheap.

Application enumeration:
Once we have access, we can use the search feature to retrieve user data, which may also expose information belonging to other users.

Searching for "admin" and viewing the export reveals a password.

The admin information is useful; however, since we already have admin access, and we know NoSQL logic is running on the backend, we can leverage it to enumerate all users. ' || 'a'=='a


Once executed, we identified a username josh
with a hashed password, which was easily cracked using CrackStation. The result revealed his password as remembermethisway
.

Mattermost access as Josh:
I initially tested Josh’s credentials against SSH without success. When this failed, I immediately tested them against the Mattermost application, which granted me access.


Looking further into the application, I discovered credentials for the deployment machine: jaeger:Sh0ppyBest@pp!
.

Initial Access:
Using the plain-text credentials found in the Mattermost app, we were able to gain SSH access as the user jaeger
.

Low level enumeration:
Sudo -l:
Checking sudo
, we can see that we are allowed to run a password manager application as the deploy
user.

Running the application revealed it to be Josh’s password manager; however, it prompted for a password, and attempts with the two known credentials failed.

Binary Reverse engineering:
As mentioned in the earlier chat, they are working with C, so we may need to attempt reverse engineering. I’m not an expert in reverse engineering, so please bear with the somewhat vague approach.
Before starting, we need to transfer the binary to Kali. This can be done by creating a Python web server on the target and then using wget
on Kali to download it.

Once downloaded, we can open the binary in Ghidra and examine the main
function, since it is written in C. Within the function, we see the string "Sample" following the prompt to "enter the main password," which appears to be used in a string comparison.

App Access:
Testing the possible password Sample
successfully granted access to the credential manager, where we retrieved the password for the deploy
user.

Pivoting to Deploy user:
Using these credentials, we were able to obtain a shell as the deploy
user.

From the id
output, we can see that the deploy
user is part of the docker
group, which can be leveraged to escalate privileges.
Docker privilege escalation:
This is a method I am well-versed in, where we can create a container and mount it with root access by abusing the user’s group membership in docker
.
- First, we can check which Docker images are available on the machine.

- Next, we create a new container.

- Lastly, we gain a shell by chrooting into the filesystem.

Key learning points:
- NoSQL Injection Authentication Bypass via JavaScript Injection
- Reverse Engineering of Binary Application