Lucene search

K
attackerkbAttackerKBAKB:C391FE82-5C99-4092-B586-0FF9F6593965
HistorySep 08, 2019 - 12:00 a.m.

Bludit 3.9.2 remote code execution

2019-09-0800:00:00
attackerkb.com
261

0.937 High

EPSS

Percentile

99.1%

Bludit 3.9.2 allows remote code execution via bl-kernel/ajax/upload-images.php because PHP code can be entered with a .jpg file name, and then this PHP code can write other PHP code to a โ€ฆ/ pathname.

Recent assessments:

wchen-r7 at October 24, 2019 4:38am UTC reported:

CVE-2019-16113 Bludit Directory Traversal Vulnerability

Description

Bludit is a web application written in PHP to build your own website or blog, free and open source. It uses files in JSON format to store the content, so it is configuration-free.

A vulnerability was found in the upload-images.php file, where a remote user could upload a fake image file that is actually a malicious PHP payload, and gain remote code execution.

Technical Analysis

The vulnerable file (upload-images.php) is written as follows:

<?php defined('BLUDIT') or die('Bludit CMS.');
header('Content-Type: application/json');
/*
| Upload an image to a particular page
|
| @_POST['uuid']	string	Page uuid
|
| @return		array
*/
// $_POST
// ----------------------------------------------------------------------------
$uuid = empty($_POST['uuid']) ? false : $_POST['uuid'];
// ----------------------------------------------------------------------------
// Set upload directory
if ($uuid && IMAGE_RESTRICT) {
	$imageDirectory = PATH_UPLOADS_PAGES.$uuid.DS;
	$thumbnailDirectory = $imageDirectory.'thumbnails'.DS;
	if (!Filesystem::directoryExists($thumbnailDirectory)) {
		Filesystem::mkdir($thumbnailDirectory, true);
	}
} else {
	$imageDirectory = PATH_UPLOADS;
	$thumbnailDirectory = PATH_UPLOADS_THUMBNAILS;
}
$images = array();
foreach ($_FILES['images']['name'] as $uuid=>$filename) {
	// Check for errors
	if ($_FILES['images']['error'][$uuid] != 0) {
		$message = $L->g('Maximum load file size allowed:').' '.ini_get('upload_max_filesize');
		Log::set($message, LOG_TYPE_ERROR);
		ajaxResponse(1, $message);
	}
	// Convert URL characters such as spaces or quotes to characters
	$filename = urldecode($filename);
	// Move from PHP tmp file to Bludit tmp directory
	Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename);
	// Transform the image and generate the thumbnail
	$image = transformImage(PATH_TMP.$filename, $imageDirectory, $thumbnailDirectory);
	if ($image) {
		$filename = Filesystem::filename($image);
		array_push($images, $filename);
	} else {
		$message = $L->g('File type is not supported. Allowed types:').' '.implode(', ',$GLOBALS['ALLOWED_IMG_EXTENSION']);
		Log::set($message, LOG_TYPE_ERROR);
		ajaxResponse(1, $message);
	}
}
ajaxResponse(0, 'Images uploaded.', array(
	'images'=>$images
));
?>

The first thing that happens is that the code retrieves the โ€œuuidโ€ parameter from a POST request:

$uuid = empty($_POST['uuid']) ? false : $_POST['uuid'];

The uuid is used as part of the image directory path. If the path doesnโ€™t exist, then it will be automatically created:

if ($uuid && IMAGE_RESTRICT) {
	$imageDirectory = PATH_UPLOADS_PAGES.$uuid.DS;
	$thumbnailDirectory = $imageDirectory.'thumbnails'.DS;
	if (!Filesystem::directoryExists($thumbnailDirectory)) {
		Filesystem::mkdir($thumbnailDirectory, true);
	}

Next, the code starts uploading the file by accessing the $_FILES variables. In here, the content of the uploaded item isnโ€™t checked, which means even though the file expects an image file, it doesnโ€™t actually have to be. A malicious PHP payload could be uploaded instead:

foreach ($_FILES['images']['name'] as $uuid=>$filename) {
  // ... code ...

Finally, the file is moved from PHPโ€™s temp file to a custom tmp directory:

Filesystem::mv($_FILES['images']['tmp_name'][$uuid], PATH_TMP.$filename);

Even though the image upload is uploaded to Blueditโ€™s tmp directory, you can actually also upload a .htaccess file to allow the PHP payload to be accessed remotely, and gain remote code execution.

Assessed Attacker Value: 5
Assessed Attacker Value: 5Assessed Attacker Value: 5

0.937 High

EPSS

Percentile

99.1%