diff --git a/INSTALL/old/INSTALL.ubuntu1604.with.webmin.txt b/INSTALL/old/INSTALL.ubuntu1604.with.webmin.txt
index 42fb87062..277937f9a 100644
--- a/INSTALL/old/INSTALL.ubuntu1604.with.webmin.txt
+++ b/INSTALL/old/INSTALL.ubuntu1604.with.webmin.txt
@@ -36,7 +36,7 @@ sudo mysql_secure_installation
# Install PHP and dependencies
-sudo apt-get install libapache2-mod-php php php-cli php-crypt-gpg php-dev php-json php-mysql php-opcache php-readline php-redis php-xml
+sudo apt-get install libapache2-mod-php php php-cli php-crypt-gpg php-dev php-json php-mysql php-opcache php-readline php-redis php-xml php-gd
# Apply all changes
sudo systemctl restart apache2
diff --git a/app/Controller/AppController.php b/app/Controller/AppController.php
index 6973b288d..47b150e1c 100755
--- a/app/Controller/AppController.php
+++ b/app/Controller/AppController.php
@@ -46,7 +46,7 @@ class AppController extends Controller
public $helpers = array('Utility', 'OrgImg', 'FontAwesome');
- private $__queryVersion = '64';
+ private $__queryVersion = '65';
public $pyMispVersion = '2.4.103';
public $phpmin = '7.0';
public $phprec = '7.2';
diff --git a/app/Controller/AttributesController.php b/app/Controller/AttributesController.php
index e9c8b0128..4f743dcc4 100644
--- a/app/Controller/AttributesController.php
+++ b/app/Controller/AttributesController.php
@@ -1174,15 +1174,15 @@ class AttributesController extends AppController
if (!$this->Attribute->exists()) {
throw new NotFoundException('Invalid attribute');
}
+ $conditions = array('conditions' => array('Attribute.id' => $id), 'withAttachments' => true, 'flatten' => true);
+ $conditions['includeAllTags'] = false;
+ $conditions['includeAttributeUuid'] = true;
+ $attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $conditions);
+ if (empty($attribute)) {
+ throw new MethodNotAllowedException('Invalid attribute');
+ }
+ $attribute = $attribute[0];
if ($this->_isRest()) {
- $conditions = array('conditions' => array('Attribute.id' => $id), 'withAttachments' => true, 'flatten' => true);
- $conditions['includeAllTags'] = false;
- $conditions['includeAttributeUuid'] = true;
- $attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $conditions);
- if (empty($attribute)) {
- throw new MethodNotAllowedException('Invalid attribute');
- }
- $attribute = $attribute[0];
if (isset($attribute['AttributeTag'])) {
foreach ($attribute['AttributeTag'] as $k => $tag) {
$attribute['Attribute']['Tag'][$k] = $tag['Tag'];
@@ -1193,7 +1193,94 @@ class AttributesController extends AppController
$this->set('Attribute', $attribute['Attribute']);
$this->set('_serialize', array('Attribute'));
} else {
- $this->redirect('/events/view/' . $this->Attribute->data['Attribute']['event_id']);
+ $this->redirect('/events/view/' . $attribute['Attribute']['event_id']);
+ }
+ }
+
+ public function viewPicture($id, $thumbnail=false, $width=200, $height=200)
+ {
+ if (Validation::uuid($id)) {
+ $temp = $this->Attribute->find('first', array(
+ 'recursive' => -1,
+ 'conditions' => array('Attribute.uuid' => $id),
+ 'fields' => array('Attribute.id', 'Attribute.uuid')
+ ));
+ if (empty($temp)) {
+ throw new NotFoundException(__('Invalid attribute'));
+ }
+ $id = $temp['Attribute']['id'];
+ } elseif (!is_numeric($id)) {
+ throw new NotFoundException(__('Invalid attribute id.'));
+ }
+ $this->Attribute->id = $id;
+ if (!$this->Attribute->exists()) {
+ throw new NotFoundException('Invalid attribute');
+ }
+ $conditions = array(
+ 'conditions' => array(
+ 'Attribute.id' => $id,
+ 'Attribute.type' => 'attachment'
+ ),
+ 'withAttachments' => true,
+ 'includeAllTags' => false,
+ 'includeAttributeUuid' => true,
+ 'flatten' => true
+ );
+ $attribute = $this->Attribute->fetchAttributes($this->Auth->user(), $conditions);
+ if (empty($attribute)) {
+ throw new MethodNotAllowedException('Invalid attribute');
+ }
+ $attribute = $attribute[0];
+
+ if ($this->_isRest()) {
+ return $this->RestResponse->viewData($attribute['Attribute']['data'], $this->response->type());
+ } else {
+ $extension = explode('.', $attribute['Attribute']['value']);
+ $extension = end($extension);
+ if (extension_loaded('gd')) {
+ $image = ImageCreateFromString(base64_decode($attribute['Attribute']['data']));
+ if (!$thumbnail) {
+ ob_start ();
+ switch ($extension) {
+ case 'gif':
+ imagegif($image);
+ break;
+ case 'jpg':
+ case 'jpeg':
+ imagejpeg($image);
+ break;
+ case 'png':
+ imagepng($image);
+ break;
+ default:
+ break;
+ }
+ $image_data = $extension != 'gif' ? ob_get_contents() : base64_decode($attribute['Attribute']['data']);
+ ob_end_clean ();
+ imagedestroy($image);
+ } else { // thumbnail requested, resample picture with desired dimension
+ $width = isset($this->request->params['named']['width']) ? $this->request->params['named']['width'] : 150;
+ $height = isset($this->request->params['named']['height']) ? $this->request->params['named']['height'] : 150;
+ if ($extension == 'gif') {
+ $image_data = base64_decode($attribute['Attribute']['data']);
+ } else {
+ $extension = 'jpg';
+ $imageTC = ImageCreateTrueColor($width, $height);
+ ImageCopyResampled($imageTC, $image, 0, 0, 0, 0, $width, $height, ImageSX($image), ImageSY($image));
+ ob_start ();
+ imagejpeg ($imageTC);
+ $image_data = ob_get_contents();
+ ob_end_clean ();
+ imagedestroy($image);
+ imagedestroy($imageTC);
+ }
+ }
+ } else {
+ $image_data = base64_decode($attribute['Attribute']['data']);
+ }
+ $this->response->type(strtolower(h($extension)));
+ $this->response->body($image_data);
+ $this->autoRender = false;
}
}
diff --git a/app/Controller/Component/ACLComponent.php b/app/Controller/Component/ACLComponent.php
index 1154761d9..f7a25ff46 100644
--- a/app/Controller/Component/ACLComponent.php
+++ b/app/Controller/Component/ACLComponent.php
@@ -68,6 +68,7 @@ class ACLComponent extends Component
'toggleToIDS' => array('perm_add'),
'updateAttributeValues' => array('perm_add'),
'view' => array('*'),
+ 'viewPicture' => array('*'),
),
'eventBlacklists' => array(
'add' => array(),
diff --git a/app/Model/Event.php b/app/Model/Event.php
index 12536c5c0..1f5bbd432 100755
--- a/app/Model/Event.php
+++ b/app/Model/Event.php
@@ -4811,10 +4811,15 @@ class Event extends AppModel
if (!empty($object['data'])) {
$object['image'] = $object['data'];
} else {
- if ($object['objectType'] === 'proposal') {
- $object['image'] = $this->ShadowAttribute->base64EncodeAttachment($object);
+ if (extension_loaded('gd')) {
+ // if extention is loaded, the data is not passed to the view because it is asynchronously fetched
+ $object['image'] = true; // tell the view that it is an image despite not having the actual data
} else {
- $object['image'] = $this->Attribute->base64EncodeAttachment($object);
+ if ($object['objectType'] === 'proposal') {
+ $object['image'] = $this->ShadowAttribute->base64EncodeAttachment($object);
+ } else {
+ $object['image'] = $this->Attribute->base64EncodeAttachment($object);
+ }
}
}
}
diff --git a/app/Model/Server.php b/app/Model/Server.php
index 073b476cb..525770a35 100644
--- a/app/Model/Server.php
+++ b/app/Model/Server.php
@@ -4521,7 +4521,7 @@ class Server extends AppModel
public function extensionDiagnostics()
{
$results = array();
- $extensions = array('redis');
+ $extensions = array('redis', 'gd');
foreach ($extensions as $extension) {
$results['web']['extensions'][$extension] = extension_loaded($extension);
}
diff --git a/app/View/Elements/Events/View/value_field.ctp b/app/View/Elements/Events/View/value_field.ctp
index 40b746348..9b748d083 100644
--- a/app/View/Elements/Events/View/value_field.ctp
+++ b/app/View/Elements/Events/View/value_field.ctp
@@ -2,10 +2,16 @@
$sigDisplay = $object['value'];
if ('attachment' == $object['type'] || 'malware-sample' == $object['type'] ) {
if ($object['type'] == 'attachment' && isset($object['image'])) {
- $extension = explode('.', $object['value']);
- $extension = end($extension);
- $uri = 'data:image/' . strtolower(h($extension)) . ';base64,' . h($object['image']);
- echo '';
+ if (extension_loaded('gd')) {
+ $img = '
';
+function screenshotPopup(url, title) {
+ if (!url.startsWith('data:image/')) {
+ url = url.slice(0, -1);
+ }
+ popupHtml = '