fix: Refactor of the bro export to always create a zip archive with separate files if "all" types are queried

pull/1544/head
Iglocska 2016-09-16 16:49:54 +02:00
parent 1991f7a208
commit 6d822ee45e
4 changed files with 58 additions and 44 deletions

View File

@ -339,38 +339,13 @@ class EventShell extends AppShell
$types = array('ip', 'email', 'domain', 'filename', 'filehash', 'certhash', 'software', 'url'); //Bro types
$typeCount = count($types);
$dir = new Folder(APP . DS . '/tmp/cached_exports/' . $format, true, 0750);
if ($user['Role']['perm_site_admin']) {
$zipname = DS . 'misp.bro.ADMIN.intel.zip';
} else {
$zipname = DS . 'misp.bro.' . $user['Organisation']['name'] . '.intel.zip';
}
$random_component = $this->Event->generateRandomFileName();
$tmpZipname = DS . "bro_export_tmp_" . $random_component . ".zip";
$zip = new File($dir->pwd() . $tmpZipname);
foreach ($types as $k => $type) {
$final = $this->Attribute->bro($user, $type);
$filename = $type . '.intel';
$file = new File($dir->pwd() . DS . $filename);
$file->write($broHeader);
foreach ($final as $attribute) {
$file->append($attribute . "\n");
}
$file->close();
$execRetval = '';
$execOutput = array();
exec('zip -gj ' . $zip->path . ' ' . $dir->pwd() . '/' . $filename,
$execOutput, $execRetval);
if ($execRetval != 0) { // not EXIT_SUCCESS
throw new Exception('An error has occured while attempting to zip the intel files.');
}
$file->delete(); // delete the original non-zipped-file
$this->Job->saveField('progress', $k / $typeCount * 100);
}
$zip->close();
rename($dir->pwd() . $tmpZipname, $dir->pwd() . $zipname);
$tmpZipname = $this->Attribute->brozip($user, false, false, false, false, false, false, $id);
rename($tmpZipname[0] . $tmpZipname[1], $dir->pwd() . $zipname);
$this->Job->saveField('progress', 100);
$this->Job->saveField('message', 'Job done.');
}

View File

@ -1870,17 +1870,24 @@ class AttributesController extends AppController {
throw new UnauthorizedException('You have to be logged in to do that.');
}
}
$this->response->type('txt'); // set the content type
$filename = 'misp.' . $type . '.intel';
if ($eventId) {
$filename = 'misp.' . $type . '.event_' . $eventId . '.intel';
}
$this->header('Content-Disposition: download; filename="' . $filename . '"');
$this->layout = 'text/default';
$attributes = array("#fields indicator\tindicator_type\tmeta.source\tmeta.url\tmeta.do_notice\tmeta.if_in");
$attributes = array_merge($attributes, $this->Attribute->bro($this->Auth->user(), $type, $tags, $eventId, $allowNonIDS, $from, $to, $last));
$this->set('attributes', $attributes);
$this->render('/Attributes/bro');
if ($type != 'all') {
$responseFile = implode(PHP_EOL, $this->Attribute->bro($this->Auth->user(), $type, $tags, $eventId, $allowNonIDS, $from, $to, $last)) . PHP_EOL;
$this->response->body($responseFile);
$this->response->type('txt');
} else {
$tmpZipname = $this->Attribute->brozip($this->Auth->user(), $tags, $eventId, $allowNonIDS, $from, $to, $last);
$this->response->body(file_get_contents($tmpZipname[0] . $tmpZipname[1]));
$this->response->type('zip');
$folder = new Folder($tmpZipname[0]);
$folder->delete();
$filename .= '.zip';
}
$this->response->download($filename);
return $this->response;
}
}

View File

@ -4,6 +4,8 @@ class BroExport {
public $rules = array();
public $header = "#fields indicator\tindicator_type\tmeta.source\tmeta.url\tmeta.do_notice\tmeta.if_in";
// mapping from misp attribute type to the bro intel type
// alternative mechanisms are:
// - alternate: array containing a detection regex and a replacement bro type
@ -33,7 +35,7 @@ class BroExport {
// export group to misp type mapping
// the mapped type is in an array format, first value being the misp type, second being the value field used
private $__mispTypes = array(
public $mispTypes = array(
'ip' => array(
array('ip-src', 1),
array('ip-dst', 1),
@ -160,14 +162,8 @@ class BroExport {
public function getMispTypes($type) {
$mispTypes = array();
if ($type !== 'all') {
if (isset($this->__mispTypes[$type])) {
$mispTypes = $this->__mispTypes[$type];
}
} else {
foreach ($this->__mispTypes as $mispType) {
$mispTypes = array_merge($mispTypes, $mispType);
}
if (isset($this->mispTypes[$type])) {
$mispTypes = $this->mispTypes[$type];
}
return $mispTypes;
}

View File

@ -1449,7 +1449,7 @@ class Attribute extends AppModel {
}
}
$mispTypes = $export->getMispTypes($type);
$intel = array();
$intel = array($export->header);
foreach($mispTypes as $mispType) {
$conditions['AND']['Attribute.type'] = $mispType[0];
$intel = $this->__bro($intel, $user, $conditions, $mispType[1], $export, $this->whitelist, $instanceString);
@ -1472,6 +1472,42 @@ class Attribute extends AppModel {
));
return $export->export($attributes, $orgs, $valueField, $intel, $whitelist, $instanceString);
}
public function brozip($user, $tags, $eventId, $allowNonIDS, $from, $to, $last, $jobId = false) {
App::uses('BroExport', 'Export');
$export = new BroExport();
$types = array_keys($export->mispTypes);
$typeCount = count($types);
if ($jobId) {
$this->Job = ClassRegistry::init('Job');
$this->Job->id = $jobId;
if (!$this->Job->exists()) {
$jobId = false;
}
}
$dir = new Folder(APP . 'tmp/files/' . $this->Event->generateRandomFileName(), true, 0750);
$tmpZipname = DS . "bro_export_tmp.zip";
$zip = new File($dir->pwd() . $tmpZipname);
foreach ($types as $k => $type) {
$final = $this->bro($user, $type, $tags, $eventId, $allowNonIDS, $from, $to, $last);
$filename = $type . '.intel';
$file = new File($dir->pwd() . DS . $filename);
$file->write(implode(PHP_EOL, $final));
$file->close();
$execRetval = '';
$execOutput = array();
exec('zip -gj ' . $zip->path . ' ' . $dir->pwd() . '/' . $filename, $execOutput, $execRetval);
if ($execRetval != 0) { // not EXIT_SUCCESS
throw new Exception('An error has occured while attempting to zip the intel files.');
}
$file->delete(); // delete the original non-zipped-file
if ($jobId) {
$this->Job->saveField('progress', $k / $typeCount * 100);
}
}
$zip->close();
return array($dir->pwd(), $tmpZipname);
}
public function generateCorrelation($jobId = false, $startPercentage = 0) {
$this->Correlation = ClassRegistry::init('Correlation');