Page cover

MagicGardens

Synopsis

MagicGardens is a insane linux machine created by m4rsh3llarrow-up-right. The domain magicgardens.htb contains the django admin. The XSS exploit is used to steal the admin cookie. The django admin panel contains the morty's hash which can be cracked and can ssh into the system as morty. The pillaging reveals that the alex is running the custom binary harvest and morty also has access to it. Reversing the binary and found that it is vulnerable to buffer overflow, which can be used to gain the shell as alex. The user alex has got a mail which contains the auth.zip file which contains the username and hash to access the docker registry. Cracking the hash and dumping the contain of docker registry, the django PickleSerializer is used in the app. It is vulnerable to RCE which will give us the shell as root in docker container. The root in docker container has the capability of cap_sys_module which can be abused to load the kernel model and privilege escalate into systems root.

OS
Difficulty
Points
Release Date
Retired Date

Linux

Insane

50

18-05-2024

08-02-2025


Enumeration

Nmap

Starting the nmap scan reveals that ssh, http, docker registry and other services are running.

nmap -p- -Pn -sC -sV --min-rate=1000 10.10.11.9 
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-05 21:52 EST
Warning: 10.10.11.9 giving up on port because retransmission cap hit (10).
Nmap scan report for 10.10.11.9
Host is up (0.55s latency).
Not shown: 64603 closed tcp ports (conn-refused), 928 filtered tcp ports (no-response)
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
| ssh-hostkey: 
|   256 e0:72:62:48:99:33:4f:fc:59:f8:6c:05:59:db:a7:7b (ECDSA)
|_  256 62:c6:35:7e:82:3e:b1:0f:9b:6f:5b:ea:fe:c5:85:9a (ED25519)
80/tcp   open  http     nginx 1.22.1
|_http-server-header: nginx/1.22.1
|_http-title: Did not follow redirect to http://magicgardens.htb/
1337/tcp open  waste?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, JavaRMI, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NotesRPC, RPCCheck, RTSPRequest, TerminalServer, TerminalServerCookie, X11Probe, afp, giop, ms-sql-s: 
|_    [x] Handshake error
5000/tcp open  ssl/http Docker Registry (API: 2.0)
| ssl-cert: Subject: organizationName=Internet Widgits Pty Ltd/stateOrProvinceName=Some-State/countryName=AU
| Not valid before: 2023-05-23T11:57:43
|_Not valid after:  2024-05-22T11:57:43
|_http-title: Site doesn't have a title.
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-Port1337-TCP:V=7.94SVN%I=7%D=2/5%Time=67A4248D%P=x86_64-pc-linux-gnu%r(
SF:GenericLines,15,"\[x\]\x20Handshake\x20error\n\0")%r(GetRequest,15,"\[x
SF:\]\x20Handshake\x20error\n\0")%r(HTTPOptions,15,"\[x\]\x20Handshake\x20
SF:error\n\0")%r(RTSPRequest,15,"\[x\]\x20Handshake\x20error\n\0")%r(RPCCh
SF:eck,15,"\[x\]\x20Handshake\x20error\n\0")%r(DNSVersionBindReqTCP,15,"\[
SF:x\]\x20Handshake\x20error\n\0")%r(DNSStatusRequestTCP,15,"\[x\]\x20Hand
SF:shake\x20error\n\0")%r(Help,15,"\[x\]\x20Handshake\x20error\n\0")%r(Ter
SF:minalServerCookie,15,"\[x\]\x20Handshake\x20error\n\0")%r(X11Probe,15,"
SF:\[x\]\x20Handshake\x20error\n\0")%r(FourOhFourRequest,15,"\[x\]\x20Hand
SF:shake\x20error\n\0")%r(LPDString,15,"\[x\]\x20Handshake\x20error\n\0")%
SF:r(LDAPSearchReq,15,"\[x\]\x20Handshake\x20error\n\0")%r(LDAPBindReq,15,
SF:"\[x\]\x20Handshake\x20error\n\0")%r(LANDesk-RC,15,"\[x\]\x20Handshake\
SF:x20error\n\0")%r(TerminalServer,15,"\[x\]\x20Handshake\x20error\n\0")%r
SF:(NCP,15,"\[x\]\x20Handshake\x20error\n\0")%r(NotesRPC,15,"\[x\]\x20Hand
SF:shake\x20error\n\0")%r(JavaRMI,15,"\[x\]\x20Handshake\x20error\n\0")%r(
SF:ms-sql-s,15,"\[x\]\x20Handshake\x20error\n\0")%r(afp,15,"\[x\]\x20Hands
SF:hake\x20error\n\0")%r(giop,15,"\[x\]\x20Handshake\x20error\n\0");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 330.42 seconds

Add the magicgardens.htb in /etc/hosts file.

Docker Registry - Port 5000

The docker registry needs the credentials to be accessed and we are unauthorized.

Web - magicgardens.htb

The magicgarden is a e-commerce site where we can order flowers online.

The website has product catalog, sign-in features and allows us to search, buy, watchlist and add to cart the products. Purchasing the product gives us the success alert with the below message.

Creating the account and login into the account gives us the option to upgrade our subscription and getting a QR code for 25% discounts on all products.

Clicking the Upgrade button we are presented with payment form where we have to input our credit card details and choose the banks. The banks listed are honestbank.htb, magicbank.htb and plunders.htb.

Submitting the filled form gives up error message.


Foothold

Getting Subscriptions - magicgardens [ Creating Fake Bank ]

1

Changing bank parameter value

Intercepting the subscribe request with burpsuite reveals the bank parameter which I will be going to change it with the nc listener ip and port.

While trying to pay the /api/payments/ POST request is made at the bank.

2

Sending the same request to one of the listed banks

Sending the same POST request to honestbank.htb returns a 402 status.

3

Creating python script for changing the status to 200 when the /api/payments POST request is made

4

Execute the script and send the POST request to /api/payments

We got the status code 200.

5

Initating payment.

Repeat the subscription process while your python script running and change that bank parameter value to your vpn ip address and port to 5000.

The payment for subscription is completed and we got the QR code.

The endpoint to generate QR code was /qr_code/images/serve-qr-code-image which path is used by django_qr_codearrow-up-right and it is conformed by visiting the /admin, which presents us with django admin panel.

1

Decoding the QR code

Download the QR code and decode it using zbarimg

The QR code value has three part and last part contains the username.

2

Buy any products and morty will message asking the qr code for discount.

3

Encode the QR code with the XSS payload.

4
5

Head-over to the Django admin panel and save the cookies using dev tools.

Refresh the page and you will get the access.

Shell - morty

Enumerating the admin panel found the morty's hash in Store users section.

Copying the hash in file and using hashcat to crack it.

Using the password for ssh as user morty gives us access to system via ssh.


Lateral Movement

Pillaging - morty [ user ]

The ps aux reveals that the user alex is running the harvest command.

The harvest binary can be accessed by morty also.

Downloading the harvest binary using the scp for further enumeration.

Pillaging - harvest [ binary ]

Checking the file type of harvest. It is a 64-bit binary and is not stripped.

Surfing the web about the harvest doesn't provide any information. The binary is a custom made binary. Running the help command.

It is a remote network analyzer tool. It runs in two mode server and client mode.

Running in the client mode it starts dumping the network packets.

Running in server mode requires sudo privilege and it just starts listening to the interface.

Reversing the binary with ghidra. If the ghidra is showing the no filesystem provider found while importing the file. Archive the harvest using tar and import the file in ghidra.

Enumerating the function log_packets.

The file_name buffer with length 40 can be used to overwrite the file by buffer overflowing the packets buffer with length 32680

Shell - alex [ Buffer Overflow ]

Testing

Executing the harvest server and client, then sending the 100 A's character in IPv6 packets.

The segmentation fault error is occurred and the empty file is created with 100 A's character file name.

Executing

I will be adding my ssh public key in alex authorized_keys file through buffer overflow.

1

Create the ssh key

2

Create the python script in morty's shell to add public key in authorized_keys

3

Run the harvest client in your local machine and execute the pwn.py

The harvest client is closed by server when executed the pwn.py

4

SSH into alex using the ssh private key.

circle-info

The user.txt is contains the user flag 👏

Pillaging - alex [ user ]

While logging in the message You have mail is given. Checking the mail gives us the auth.zip file which contains the registry configurations and passwords.

Pillaging - auth.zip [ file ]

Getting Docker registry password

1

Decoding the base64 and unzipping the file

The file is protected with password.

2

Getting the hash and cracking it

3

Extract the file

The file contains the hash.

4

Crack the hash

Pillaging - Docker registry [ Port 5000 ]

Using the above credentials gives us access to the Docker registry.

Checked the registry and it only contains only one repository.

Dumping

The Docker registry can be dumped using this scriptarrow-up-right.

1

Git clone the repository

2

Create the python virtual environment and activate it

3

Install the required dependencies and libraries

4

Execute the drg.py to dump the Docker registry repository

Extracting all the layers, listing all the files and folders.

It has same file system as linux file system. The /usr/src/app directory contains the python application.

The .env file contains the application SECRET_KEY and app/settings.py shows that it is using PickleSerializer which is no longer supported in django.


Pivoting

Shell - Docker Container [ root - django serialization rce exploit ]

The secret key is revealed and we can forge the valid cookie that is deserialized in the application. The 0xdf has released the PoCarrow-up-right script of the exploit.

1
2

Downgrade the django version

The current version of django doesn't support the PickleSerializer, so it is giving us error.

Downgrading the django version in which it supports the PickleSerializer.

3

Getting the shell

Open the nc listener and execute the script, we will get the shell.

circle-info

We have to create the python virtual environment and activate it to execute above script if not done previously.


Privilege Escalation

Pillaging - Docker Container [ root ]

Listing the capabilities reveals the cap_sys_module, which allows the container to load and unload kernel modules.

Shell - root [ cap_sys_module exploit ]

Hacktricks has created a post for abusing this exploit in this sectionarrow-up-right.

1

Copying the reverse-shell.c and Makefile from the post and replacing the IP and Port.

2

Sending the reverse-shell.c and Makefile into Docker Container.

3

Compile it using make.

4

Open the nc listener and run insmod.

circle-info

The root.txt file in /root directory contains the root flag 🎉


Proof of Concepts

The below video provides the PoC of MagicGardens machine.

Last updated