mirror of https://github.com/MISP/MISP
chg: [internal] Error handling when converting STIX2MISP
parent
54b156b378
commit
a2fa480568
|
@ -127,7 +127,7 @@ class ProcessTool
|
|||
{
|
||||
$logMessage = '[' . date("Y-m-d H:i:s") . ' ' . getmypid() . "] $message\n";
|
||||
if ($stderr) {
|
||||
$logMessage = $stderr . "\n" . $logMessage;
|
||||
$logMessage = rtrim($stderr) . "\n" . $logMessage;
|
||||
}
|
||||
file_put_contents(self::LOG_FILE, $logMessage, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
|
|
@ -5922,61 +5922,24 @@ class Event extends AppModel
|
|||
/**
|
||||
* @param array $user
|
||||
* @param string $file Path
|
||||
* @param string $stix_version
|
||||
* @param string $original_file
|
||||
* @param string $stixVersion
|
||||
* @param string $originalFile
|
||||
* @param bool $publish
|
||||
* @param int $distribution
|
||||
* @param int $sharingGroupId
|
||||
* @param bool $galaxiesAsTags
|
||||
* @param bool $debug
|
||||
* @return int|string|array
|
||||
* @throws JsonException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function upload_stix(array $user, $file, $stix_version, $original_file, $publish, $distribution, $sharingGroupId, $galaxiesAsTags, $debug = false)
|
||||
public function upload_stix(array $user, $file, $stixVersion, $originalFile, $publish, $distribution, $sharingGroupId, $galaxiesAsTags, $debug = false)
|
||||
{
|
||||
$scriptDir = APP . 'files' . DS . 'scripts';
|
||||
if ($stix_version == '2' || $stix_version == '2.0' || $stix_version == '2.1') {
|
||||
$scriptFile = $scriptDir . DS . 'stix2' . DS . 'stix2misp.py';
|
||||
$output_path = $file . '.out';
|
||||
$shell_command = [
|
||||
ProcessTool::pythonBin(),
|
||||
$scriptFile,
|
||||
'-i', $file,
|
||||
'--distribution', $distribution
|
||||
];
|
||||
if ($distribution == 4) {
|
||||
array_push($shell_command, '--sharing_group_id', $sharingGroupId);
|
||||
}
|
||||
if ($galaxiesAsTags) {
|
||||
$shell_command[] = '--galaxies_as_tags';
|
||||
}
|
||||
if ($debug) {
|
||||
$shell_command[] = '--debug';
|
||||
}
|
||||
$stix_version = "STIX 2.1";
|
||||
} elseif ($stix_version == '1' || $stix_version == '1.1' || $stix_version == '1.2') {
|
||||
$scriptFile = $scriptDir . DS . 'stix2misp.py';
|
||||
$output_path = $file . '.json';
|
||||
$shell_command = [
|
||||
ProcessTool::pythonBin(),
|
||||
$scriptFile,
|
||||
$file,
|
||||
Configure::read('MISP.default_event_distribution'),
|
||||
Configure::read('MISP.default_attribute_distribution'),
|
||||
$this->__getTagNamesFromSynonyms($scriptDir)
|
||||
];
|
||||
$stix_version = "STIX 1.1";
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid STIX version');
|
||||
}
|
||||
$decoded = $this->convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $debug);
|
||||
|
||||
$result = ProcessTool::execute($shell_command, null, true);
|
||||
$result = preg_split("/\r\n|\n|\r/", trim($result));
|
||||
$result = trim(end($result));
|
||||
$tempFile = file_get_contents($file);
|
||||
unlink($file);
|
||||
$decoded = JsonTool::decode($result);
|
||||
if (!empty($decoded['success'])) {
|
||||
$data = FileAccessTool::readAndDelete($output_path);
|
||||
$data = $this->jsonDecode($data);
|
||||
$data = JsonTool::decodeArray($decoded['converted']);
|
||||
if (empty($data['Event'])) {
|
||||
$data = array('Event' => $data);
|
||||
}
|
||||
|
@ -6000,15 +5963,13 @@ class Event extends AppModel
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!empty($decoded['stix_version'])) {
|
||||
$stix_version = 'STIX ' . $decoded['stix_version'];
|
||||
}
|
||||
$stixVersion = $decoded['stix_version'];
|
||||
$created_id = false;
|
||||
$validationIssues = false;
|
||||
$result = $this->_add($data, true, $user, '', null, false, null, $created_id, $validationIssues);
|
||||
if ($result === true) {
|
||||
if ($original_file) {
|
||||
$this->add_original_file($tempFile, $original_file, $created_id, $stix_version);
|
||||
if ($originalFile) {
|
||||
$this->add_original_file($decoded['original'], $originalFile, $created_id, $stixVersion);
|
||||
}
|
||||
if ($publish && $user['Role']['perm_publish']) {
|
||||
$this->publish($created_id);
|
||||
|
@ -6031,6 +5992,76 @@ class Event extends AppModel
|
|||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stixVersion
|
||||
* @param string $file
|
||||
* @param int $distribution
|
||||
* @param int $sharingGroupId
|
||||
* @param bool $galaxiesAsTags
|
||||
* @param bool $debug
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function convertStixToMisp($stixVersion, $file, $distribution, $sharingGroupId, $galaxiesAsTags, $debug)
|
||||
{
|
||||
$scriptDir = APP . 'files' . DS . 'scripts';
|
||||
if ($stixVersion === '2' || $stixVersion === '2.0' || $stixVersion === '2.1') {
|
||||
$scriptFile = $scriptDir . DS . 'stix2' . DS . 'stix2misp.py';
|
||||
$outputPath = $file . '.out';
|
||||
$shellCommand = [
|
||||
ProcessTool::pythonBin(),
|
||||
$scriptFile,
|
||||
'-i', $file,
|
||||
'--distribution', $distribution,
|
||||
];
|
||||
if ($distribution == 4) {
|
||||
array_push($shellCommand, '--sharing_group_id', $sharingGroupId);
|
||||
}
|
||||
if ($galaxiesAsTags) {
|
||||
$shellCommand[] = '--galaxies_as_tags';
|
||||
}
|
||||
if ($debug) {
|
||||
$shellCommand[] = '--debug';
|
||||
}
|
||||
$stixVersion = "STIX 2.1";
|
||||
} else if ($stixVersion === '1' || $stixVersion === '1.1' || $stixVersion === '1.2') {
|
||||
$scriptFile = $scriptDir . DS . 'stix2misp.py';
|
||||
$outputPath = $file . '.json';
|
||||
$shellCommand = [
|
||||
ProcessTool::pythonBin(),
|
||||
$scriptFile,
|
||||
$file,
|
||||
Configure::read('MISP.default_event_distribution'),
|
||||
Configure::read('MISP.default_attribute_distribution'),
|
||||
$this->__getTagNamesFromSynonyms($scriptDir)
|
||||
];
|
||||
$stixVersion = "STIX 1.1";
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid STIX version');
|
||||
}
|
||||
|
||||
try {
|
||||
$stdout = ProcessTool::execute($shellCommand, null, true);
|
||||
} catch (ProcessException $e) {
|
||||
$stdout = $e->stdout();
|
||||
}
|
||||
|
||||
$stdout = preg_split("/\r\n|\n|\r/", trim($stdout));
|
||||
$stdout = trim(end($stdout));
|
||||
$decoded = JsonTool::decode($stdout);
|
||||
|
||||
if (empty($decoded['stix_version'])) {
|
||||
$decoded['stix_version'] = $stixVersion;
|
||||
}
|
||||
|
||||
$decoded['original'] = FileAccessTool::readAndDelete($file);
|
||||
if (!empty($decoded['success'])) {
|
||||
$decoded['converted'] = FileAccessTool::readAndDelete($outputPath);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
private function __handleGalaxiesAndClusters($user, &$data)
|
||||
{
|
||||
if (!empty($data['Galaxy'])) {
|
||||
|
|
|
@ -44,7 +44,7 @@ def _handle_return_message(traceback):
|
|||
return '\n - '.join(traceback)
|
||||
|
||||
|
||||
def _process_stix_file(args: argparse.ArgumentParser):
|
||||
def _process_stix_file(args: argparse.Namespace):
|
||||
try:
|
||||
with open(args.input, 'rt', encoding='utf-8') as f:
|
||||
bundle = stix2_parser(
|
||||
|
@ -81,8 +81,11 @@ def _process_stix_file(args: argparse.ArgumentParser):
|
|||
file=sys.stderr
|
||||
)
|
||||
except Exception as e:
|
||||
print(json.dumps({'error': e.__str__()}))
|
||||
error = type(e).__name__ + ': ' + e.__str__()
|
||||
print(json.dumps({'error': error}))
|
||||
traceback.print_tb(e.__traceback__)
|
||||
print(error, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -109,8 +112,7 @@ if __name__ == '__main__':
|
|||
)
|
||||
try:
|
||||
args = argparser.parse_args()
|
||||
_process_stix_file(args)
|
||||
except SystemExit:
|
||||
except SystemExit as e:
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
|
@ -118,4 +120,6 @@ if __name__ == '__main__':
|
|||
}
|
||||
)
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
_process_stix_file(args)
|
|
@ -96,7 +96,7 @@ class StixParser():
|
|||
|
||||
# Convert the MISP event we create from the STIX document into json format
|
||||
# and write it in the output file
|
||||
def saveFile(self):
|
||||
def save_to_file(self):
|
||||
for attribute in self.misp_event.attributes:
|
||||
attribute_uuid = uuid.UUID(attribute.uuid) if isinstance(attribute.uuid, str) else attribute.uuid
|
||||
if attribute_uuid.version not in _RFC_UUID_VERSIONS:
|
||||
|
@ -1547,19 +1547,20 @@ def generate_event(filename, tries=0):
|
|||
return STIXPackage.from_xml(filename)
|
||||
except NamespaceNotFoundError:
|
||||
if tries == 1:
|
||||
print(json.dump({'error': 'Cannot handle STIX namespace'}))
|
||||
sys.exit()
|
||||
print(json.dumps({'error': 'Cannot handle STIX namespace'}))
|
||||
sys.exit(1)
|
||||
_update_namespaces()
|
||||
return generate_event(filename, 1)
|
||||
except NotImplementedError:
|
||||
print(json.dumps({'error': 'Missing python library: stix_edh'}))
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
try:
|
||||
import maec
|
||||
print(json.dumps({'error': f'Error while loading the STIX file: {e.__str__()}'}))
|
||||
except ImportError:
|
||||
print(json.dumps({'error': 'Missing python library: maec'}))
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def is_from_misp(event):
|
||||
|
@ -1567,7 +1568,7 @@ def is_from_misp(event):
|
|||
title = event.stix_header.title
|
||||
except AttributeError:
|
||||
return False
|
||||
return ('Export from ' in title and 'MISP' in title)
|
||||
return 'Export from ' in title and 'MISP' in title
|
||||
|
||||
|
||||
def main(args):
|
||||
|
@ -1578,11 +1579,16 @@ def main(args):
|
|||
stix_parser = StixFromMISPParser() if from_misp else ExternalStixParser()
|
||||
stix_parser.load_event(args[2:], filename, from_misp, event.version)
|
||||
stix_parser.build_misp_event(event)
|
||||
stix_parser.saveFile()
|
||||
stix_parser.save_to_file()
|
||||
print(json.dumps({'success': 1}))
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(json.dumps({'error': e.__str__()}))
|
||||
error = type(e).__name__ + ': ' + e.__str__()
|
||||
print(json.dumps({'error': error}))
|
||||
traceback.print_tb(e.__traceback__)
|
||||
print(error, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
|
|
Loading…
Reference in New Issue