Merge branch 'hotfix-2.3.105' into develop

pull/542/merge
Iglocska 2015-08-07 12:07:08 +02:00
commit 00b7fb215b
7 changed files with 170 additions and 4 deletions

View File

@ -1 +1 @@
{"major":2, "minor":3, "hotfix":104}
{"major":2, "minor":3, "hotfix":105}

View File

@ -116,6 +116,7 @@ class AppController extends Controller {
unset($user);
}
}
if ($this->Auth->user() == null) throw new ForbiddenException('Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header.');
} else if(!$this->Session->read(AuthComponent::$sessionKey)) {
// load authentication plugins from Configure::read('Security.auth')
$auth = Configure::read('Security.auth');

View File

@ -2071,4 +2071,121 @@ class AttributesController extends AppController {
return '';
}
// download a sample by passing along an md5
public function downloadSample($hash=false, $allSamples = false) {
if (!$this->userRole['perm_auth']) throw new MethodNotAllowedException('This functionality requires API key access.');
//if (!$this->request->is('post')) throw new MethodNotAllowedException('Please POST the samples as described on the automation page.');
$isJson = false;
$error = false;
if ($this->response->type() === 'application/json') {
$isJson = true;
$data = $this->request->input('json_decode', true);
} elseif ($this->response->type() === 'application/xml') {
$data = $this->request->data;
} else {
throw new BadRequestException('This action is for the API only. Please refer to the automation page for information on how to use it.');
}
if (!$hash && isset($data['request']['hash'])) $hash = $data['request']['hash'];
if (!$allSamples && isset($data['request']['hash'])) $allSamples = $data['request']['allSamples'];
$validTypes = $this->Attribute->resolveHashType($hash);
$types = array();
if ($allSamples) {
if (empty($validTypes)) {
$error = 'Invalid hash format (valid options are ' . implode(', ', array_keys($this->Attribute->hashTypes)) . ')';
}
else {
foreach ($validTypes as $t) {
if ($t == 'md5') $types = array_merge($types, array('malware-sample', 'filename|md5', 'md5'));
else $types = array_merge($types, array('filename|' . $t, $t));
}
}
if (empty($error)) {
$event_ids = $this->Attribute->find('list', array(
'recursive' => -1,
'contain' => array('Event'),
'fields' => array('Event.id'),
'conditions' => array(
'OR' => array(
'AND' => array(
'LOWER(Attribute.value1) LIKE' => strtolower($hash),
'Attribute.value2' => '',
),
'LOWER(Attribute.value2) LIKE' => strtolower($hash)
)
),
));
$searchConditions = array(
'Event.id' => array_values($event_ids)
);
if (empty($event_ids)) $error = 'No hits on the passed hash.';
}
} else {
if (!in_array('md5', $validTypes)) $error = 'Only MD5 hashes can be used to fetch malware samples at this point in time.';
if (empty($error)) {
$types = array('malware-sample', 'filename|md5');
$searchConditions = array(
'LOWER(Attribute.value2) LIKE' => strtolower($hash)
);
}
}
if (empty($error)) {
$distributionConditions = array();
if (!$this->_isSiteAdmin()) {
$distributionConditions = array("OR" =>
array(
array('Event.org =' => $this->Auth->user('org')),
array("AND" =>
array('Event.org !=' => $this->Auth->user('org')),
array('Event.distribution !=' => 0),
array('Attribute.distribution !=' => 0),
Configure::read('MISP.unpublishedprivate') ? array('Event.published =' => 1) : array(),
)
)
);
}
$attributes = $this->Attribute->find('all', array(
'recursive' => -1,
'contain' => array('Event'),
'fields' => array('Attribute.event_id', 'Attribute.id', 'Attribute.value1', 'Attribute.value2', 'Event.info'),
'conditions' => array(
'AND' => array(
$searchConditions,
$distributionConditions,
array('Attribute.type' => 'malware-sample')
))));
if (empty($attributes)) $error = 'No hits on the passed hash.';
$results = array();
foreach ($attributes as $attribute) {
$found = false;
foreach ($results as $previous) {
if ($previous['md5'] == $attribute['Attribute']['value2']) $found = true;
}
if (!$found) {
$results[] = array(
'md5' => $attribute['Attribute']['value2'],
'base64' => $this->Attribute->base64EncodeAttachment($attribute['Attribute']),
'filename' => $attribute['Attribute']['value1'],
'attribute_id' => $attribute['Attribute']['id'],
'event_id' => $attribute['Attribute']['event_id'],
'event_info' => $attribute['Event']['info'],
);
}
}
if ($error) {
$this->set('error', $error);
$this->set('_serialize', array('error'));
} else {
$this->set('result', $results);
$this->set('_serialize', array('result'));
}
} else {
$this->set('error', $error);
$this->set('_serialize', array('error'));
}
}
}

View File

@ -1607,6 +1607,7 @@ class EventsController extends AppController {
$this->loadModel('Server');
$rpzSettings = $this->Server->retrieveCurrentSettings('Plugin', 'RPZ_');
$this->set('rpzSettings', $rpzSettings);
$this->set('hashTypes', array_keys($this->Event->Attribute->hashTypes));
}
public function export() {

View File

@ -59,7 +59,7 @@ class ComplexTypeTool {
}
public function checkFreeText($input) {
$iocArray = preg_split("/\r\n|\n|\r|\s|\s+|,/", $input);
$iocArray = preg_split("/\r\n|\n|\r|\s|\s+|,|;/", $input);
$resultArray = array();
foreach ($iocArray as $ioc) {
$ioc = trim($ioc);

View File

@ -161,7 +161,7 @@ class Attribute extends AppModel {
'Payload delivery' => array(
'desc' => 'Information about how the malware is delivered',
'formdesc' => 'Information about the way the malware payload is initially delivered, for example information about the email or web-site, vulnerability used, originating IP etc. Malware sample itself should be attached here.',
'types' => array('md5', 'sha1', 'sha256','filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'ip-src', 'ip-dst', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'ip-dst', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'vulnerability', 'other')
'types' => array('md5', 'sha1', 'sha256','filename', 'filename|md5', 'filename|sha1', 'filename|sha256', 'ip-src', 'ip-dst', 'hostname', 'domain', 'email-src', 'email-dst', 'email-subject', 'email-attachment', 'url', 'user-agent', 'AS', 'pattern-in-file', 'pattern-in-traffic', 'yara', 'attachment', 'malware-sample', 'link', 'comment', 'text', 'vulnerability', 'other')
),
'Artifacts dropped' => array(
'desc' => 'Any artifact (files, registry keys etc.) dropped by the malware or other modifications to the system',
@ -357,6 +357,24 @@ class Attribute extends AppModel {
'counterCache' => true
)
);
public $hashTypes = array(
'md5' => array(
'length' => 32,
'pattern' => '#^[0-9a-f]{32}$#',
'lowerCase' => true,
),
'sha1' => array(
'length' => 40,
'pattern' => '#^[0-9a-f]{40}$#',
'lowerCase' => true,
),
'sha256' => array(
'length' => 64,
'pattern' => '#^[0-9a-f]{64}$#',
'lowerCase' => true,
)
);
/**
* beforeSave
@ -1652,4 +1670,15 @@ class Attribute extends AppModel {
}
return $fn;
}
public function resolveHashType($hash) {
$hashTypes = $this->hashTypes;
$validTypes = array();
$length = strlen($hash);
foreach ($hashTypes as $k => $hashType) {
$temp = $hashType['lowerCase'] ? strtolower($hash) : $hash;
if ($hashType['length'] == $length && preg_match($hashType['pattern'], $temp)) $validTypes[] = $k;
}
return $validTypes;
}
}

View File

@ -311,7 +311,25 @@ For example, to get all IDS signature attributes of type md5 and sha256, but not
echo Configure::read('MISP.baseurl').'/attributes/downloadAttachment/download/[Attribute_id]';
?>
</pre>
<h3>Download malware sample by hash</h3>
<p>You can also download samples by knowing its MD5 hash. Simply pass the hash along as a JSON/XML object or in the URL (with the URL having overruling the passed objects) to receive a JSON/XML object back with the zipped sample base64 encoded along with some contextual information.</p>
<p>You can also use this API to get all samples from events that contain the passed hash. For this functionality, just pass the "allSamples" flag along. Note that if you are getting all samples from matching events, you can use all supported hash types (<?php echo h(implode(', ', $hashTypes)); ?>) for the lookup.</p>
<pre>
<?php
echo Configure::read('MISP.baseurl').'/attributes/downloadSample/[hash]/[allSamples]';
?>
</pre>
<p>POST message payload (XML):</p>
<p><code>
<?php echo h("<request><hash>7c12772809c1c0c3deda6103b10fdfa0</hash><allSamples>1</allSamples></request>"); ?>
</code></p>
<p>POST message payload (json):</p>
<p><code>
{"request": {"hash": "7c12772809c1c0c3deda6103b10fdfa0", "allSamples": 1}}
</code></p>
<p>A quick description of all the parameters in the passed object:</p>
<b>hash</b>: A hash in MD5 format. If allSamples is set, this can be any one of the following: <?php echo h(implode(', ', $hashTypes)); ?><br />
<b>allSamples</b>: If set, it will return all samples from events that have a match for the hash provided above.<br />
<h3>Upload malware samples using the "Upload Sample" API</h3>
<pre>
<?php