-
-
Save neex/67d5b47e6ac457edd44a52c772104158 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// require_once('config.php'); NOTE: the line is commened by the writeup author. config.php is inlined below. | |
/* config.php START */ | |
// XXE? Lame. Real hackers get RCE. | |
$secret = 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ=='; | |
/* config.php END */ | |
error_reporting( E_ALL ); | |
session_start(); | |
// totally not copy&pasted from somewhere... | |
function get_size($file, $mime_type) { | |
if ($mime_type == "image/png"||$mime_type == "image/jpeg") { | |
$stats = getimagesize($file); | |
$width = $stats[0]; | |
$height = $stats[1]; | |
} else { | |
$xmlfile = file_get_contents($file); | |
$dom = new DOMDocument(); | |
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); | |
$svg = simplexml_import_dom($dom); | |
$attrs = $svg->attributes(); | |
$width = (int) $attrs->width; | |
$height = (int) $attrs->height; | |
} | |
return [$width, $height]; | |
} | |
function workdir() { | |
$d = 'upload/'.md5(session_id()); | |
if (!is_dir($d)) | |
mkdir($d); | |
return $d; | |
} | |
function list_photos() { | |
$d = 'upload/'.md5(session_id()); | |
if (!is_dir($d)) return []; | |
$result = []; | |
foreach(glob("{$d}/*.*") as $f) { | |
if (strrpos($f, 'small') === FALSE) | |
$result[basename($f)] = $f; | |
} | |
return $result; | |
} | |
function upload() { | |
if (!isset($_FILES['photo'])) | |
return; | |
$p = new PhotoUpload($_FILES['photo']['tmp_name']); | |
$p->thumbnail(); | |
} | |
class PhotoUpload { | |
private $failed = false; | |
function __construct($path) { | |
$formats = [ | |
"image/gif" => "gif", | |
"image/png" => "png", | |
"image/jpeg" => "jpg", | |
"image/svg+xml" => "svg", | |
// Uncomment when launching gVideoz | |
//"video/mp4" => "mp4", | |
]; | |
$mime_type = mime_content_type($path); | |
if (!array_key_exists($mime_type, $formats)) { | |
die; | |
} | |
$size = get_size($path, $mime_type); | |
if ($size[0] * $size[1] > 65536) { | |
die; | |
} | |
$this->ext = $formats[$mime_type]; | |
$this->name = hash_hmac('md5', uniqid(), $secret).".{$this->ext}"; | |
move_uploaded_file($path, workdir()."/{$this->name}"); | |
} | |
function thumbnail() { | |
exec(escapeshellcmd('convert '.workdir()."/{$this->name}".' -resize 128x128 '.workdir()."/{$this->name}_small.jpg"), $out, $ret); | |
if ($ret) | |
$this->failed = true; | |
} | |
function __destruct() { | |
if ($this->failed) { | |
shell_exec(escapeshellcmd('rm '.workdir()."/{$this->name}")); | |
} | |
} | |
} | |
if (isset($_GET['action'])) { | |
switch ($_GET['action']) { | |
case 'upload': | |
upload(); | |
header('Location: ?'); | |
die; | |
break; | |
case 'src': | |
show_source(__FILE__); | |
die; | |
default: | |
break; | |
} | |
} | |
?> | |
<html> | |
<head> | |
<title>gPhotoz</title> | |
</head> | |
<body> | |
<div> | |
<form action="?action=upload" method="POST" enctype="multipart/form-data"> | |
<input type="file" name="photo"><input type="submit" value="Upload"> | |
</form> | |
</div> | |
<div> | |
<?php foreach(list_photos() as $name => $path): ?> | |
<div> | |
<a href="<?=$path?>" alt="<?=$name?>"><img src="<?=$path.'_small.jpg'?>"></a> | |
</div> | |
<?php endforeach ?> | |
</div> | |
</body> | |
<a href="?action=src"></a> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice!