shell bypass 403
<?
App::uses('Controller', 'Controller');
App::uses('File', 'Utility');
class DownloaderController extends Controller {
public $components = array('App');
public function downloadImagen() {
$archivo = $this->params->entidad . '/' . $this->params->entidad_id . '/' . ((!empty($this->params->directorio)) ? $this->params->directorio . '/' : '') . $this->params->archivo;
$src = ROOT . '/app/webroot/blobs/' . $archivo;
//Comprobamos si la imagen existe en el sistema de ficheros
$file = new File($src);
if (!$file->exists()) {
header('HTTP/1.0 404 Not Found');
return;
}
$fileInfo = $file->info();
//Dependiendo del tipo de fichero enviamos las cabeceras adecuadas...
$fp = fopen($src, 'rb');
switch ($fileInfo['mime']) {
case 'image/jpeg':
case 'image/gif':
case 'image/png':
case 'application/pdf':
case 'application/x-pdf':
header('Content-type: ' . $fileInfo['mime']);
header('Content-Length: ' . $fileInfo['filesize']);
header('Content-Disposition: attachment; filename=' . $archivo);
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
break;
}
fpassthru($fp);
}
public function getImagen() {
$out = null;
$archivo = $this->params->entidad . '/' . $this->params->entidad_id . '/' . ((!empty($this->params->directorio)) ? $this->params->directorio . '/' : '') . $this->params->archivo;
$src = ROOT . '/app/webroot/blobs/' . $archivo;
//Comprobamos si la imagen existe en el sistema de ficheros
$file = new File($src);
if ($file->exists()) { //imagen encontrada
$srcInfo = $this->srcInfo($src);
//Obtenemos la ruta donde se guardará la imagen
$out = ROOT . '/app/webroot/i/' . $srcInfo['w'] . '-' . $srcInfo['h'] . '/' . $archivo;
//Path /i/w-h/entidad/entidad_id/archivo
$fileInfo = $file->info();
$outDir = str_replace('/' . $fileInfo['basename'], '', $out);
CakeLog::write('error', "Ruta download" . $outDir, 'payment');
if (!is_dir($outDir)) {
mkdir($outDir, 0777, true);
}
} else { //imagen de vacío
$src = ROOT . '/app/webroot' . Configure::read('App.vacio');
$srcInfo = $this->srcInfo($src);
}
//Color de fondo
$bgColor = (!empty($this->request->query['bg'])) ? $this->request->query['bg'] : null;
$this->getImageresizeThenCrop($src, $out, $srcInfo['size'], $srcInfo['w'], $srcInfo['h'], $bgColor, false);
die;
}
private function getImageresizeThenCrop($filein, $fileout, $srcSize, $w, $h, $bgColor, $water) {
try {
$format = $srcSize['mime'];
$widthOrig = $srcSize[0];
$heightOrig = $srcSize[1];
$width = $w;
$height = $h;
if ($widthOrig < $heightOrig) {
$height = ($w / $widthOrig) * $heightOrig;
} else {
$width = ($h / $heightOrig) * $widthOrig;
}
if ($width < $w) {
$width = $w;
$height = ($w / $widthOrig) * $heightOrig;
}
if ($height < $h) {
$height = $h;
$width = ($h / $heightOrig) * $widthOrig;
}
switch ($format) {
case 'image/jpeg':
$imageInFunc = 'imagecreatefromjpeg';
$imageOutFunc = 'imagejpeg';
$imageQuality = 90;
break;
case 'image/gif':
$imageAlphaBlending = (!empty($bgColor)) ? true : false;
$imageInFunc = 'imagecreatefromgif';
$imageOutFunc = 'imagegif';
break;
case 'image/png':
$imageAlphaBlending = false;
$imageInFunc = 'imagecreatefrompng';
$imageOutFunc = 'imagepng';
$imageOutArgs = PNG_NO_FILTER;
$imageQuality = 9;
break;
}
//Imagen
if(isset($imageInFunc)) {
$image = $imageInFunc($filein);
}else {
$image = 'imagecreatefromjpeg';
$imageOutFunc = 'imagejpeg';
}
//Aplicamos la marca de agua
if ($water) {
$water = imagecreatefrompng(ROOT . Configure::read('App.agua'));
imagecopy($image, $water, 15, 10, 0, 0, imagesx($water), imagesy($water));
}
//Convertimos el color de fondo recibido en rgb para usarlo en las diferentes funciones...
$alpha = (empty($bgColor) && in_array($format, array('image/gif', 'image/png'))) ? 127 : 0;
$bgColor = $this->hex2rgb($bgColor);
//thumb
$thumb = imagecreatetruecolor($width, $height);
if ($format != 'image/jpeg') {
$bg = imagecolorallocatealpha($thumb, $bgColor['r'], $bgColor['g'], $bgColor['b'], $alpha);
if ($format == 'image/gif') {
imagefill($thumb, 0, 0, $bg);
}
imagealphablending($thumb, $imageAlphaBlending);
imagesavealpha($thumb, true);
ImageFilledRectangle($thumb, 0, 0, $width, $height, $bg);
}
imagecopyresampled($thumb, $image, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig);
//thumb2
$thumb2 = imagecreatetruecolor($w, $h);
if ($format != 'image/jpeg') {
$bg = imagecolorallocatealpha($thumb2, $bgColor['r'], $bgColor['g'], $bgColor['b'], $alpha);
if ($format == 'image/gif') {
imagefill($thumb2, 0, 0, $bg);
}
imagealphablending($thumb2, $imageAlphaBlending);
imagesavealpha($thumb2, true);
ImageFilledRectangle($thumb2, 0, 0, $w, $h, $bg);
}
$w1 = ($width / 2) - ($w / 2);
$h1 = ($height / 2) - ($h / 2);
imagecopyresampled($thumb2, $thumb, 0, 0, $w1, $h1, $w, $h, $w, $h);
//Guardamos en el sistema de ficheros la imagen generada
if (!empty($fileout)) {
$args = array($thumb2, $fileout);
if (!empty($imageQuality)) {
$args[] = $imageQuality;
}
if (!empty($imageOutArgs)) {
$args[] = $imageOutArgs;
}
call_user_func_array($imageOutFunc, $args);
}
//Mostramos por pantalla la imagen generada
header('Content-type: ' . $format . '');
$args = array($thumb2, NULL);
if (!empty($imageQuality)) {
$args[] = $imageQuality;
}
if (!empty($imageOutArgs)) {
$args[] = $imageOutArgs;
}
call_user_func_array($imageOutFunc, $args);
}catch(Exception $e){
CakeLog::write('error', "Excepción: " . $e->getMessage(), '');
CakeLog::write('error', "Excepción: " . $e->getLine(), '');
}
}
//http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/
private function hex2rgb($hex) {
$hex = str_replace('#', '', $hex);
if (strlen($hex) == 3) {
$r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1));
$g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1));
$b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1));
} else {
$r = hexdec(substr($hex, 0, 2));
$g = hexdec(substr($hex, 2, 2));
$b = hexdec(substr($hex, 4, 2));
}
return array('r' => $r, 'g' => $g, 'b' => $b); // returns an array with the rgb values
}
private function srcInfo($src) {
$out = array();
//Datos de la imagen
$out['size'] = getimagesize($src);
//Redimensión
if (!empty($this->request->query['w']) && !empty($this->request->query['h'])) {
$out['w'] = $this->request->query['w'];
$out['h'] = $this->request->query['h'];
} else {
$out['w'] = $out['size'][0];
$out['h'] = $out['size'][1];
}
return $out;
}
}