这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 0 additions & 99 deletions src/helperFunctions/ccp_tresholds.py

This file was deleted.

49 changes: 48 additions & 1 deletion src/helperFunctions/tag.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
class TagColor:

GRAY = 'default'
BLUE = 'primary'
GREEN = 'success'
LIGHT_BLUE = 'info'
ORANGE = 'warning'
RED = 'danger'


def check_tags(file_object, analysis_name):
tags, root_uid = None, None
if analysis_name in file_object.processed_analysis and 'tags' in file_object.processed_analysis[analysis_name]:
try:
root_uid = file_object.processed_analysis[analysis_name]['tags'].pop('root_uid')
except (KeyError, AttributeError):
return dict(notags=True)
tags = file_object.processed_analysis[analysis_name]['tags']
return dict(notags=False, tags=tags, plugin=analysis_name, uid=root_uid) if root_uid else dict(notags=True)


def add_tags_to_object(file_object, analysis_name):
if analysis_name in file_object.processed_analysis and 'tags' in file_object.processed_analysis[analysis_name]:
tags = file_object.processed_analysis[analysis_name]['tags']
file_object.analysis_tags[analysis_name] = tags
return file_object


def update_tags(old_tags, plugin_name, tag_name, tag):
tag_is_stable, message = check_tag_integrity(tag)

if not tag_is_stable:
raise ValueError(message)

if plugin_name not in old_tags:
old_tags[plugin_name] = {tag_name: tag}

old_tags[plugin_name][tag_name] = tag

return old_tags


def check_tag_integrity(tag):
if any(key not in tag for key in ['value', 'color', 'propagate']):
return False, 'missing key'

if tag['color'] not in [TagColor.GREEN, TagColor.GRAY, TagColor.BLUE, TagColor.LIGHT_BLUE, TagColor.ORANGE, TagColor.RED]:
return False, 'bad tag color'

if not isinstance(tag['value'], str):
return False, 'tag value has to be a string'

if tag['propagate'] not in [True, False]:
return False, 'tag propagate key has to be a boolean'

return True, 'empty'
1 change: 1 addition & 0 deletions src/objects/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self, binary=None, file_name=None, file_path=None, scheduled_analys
self.comments = []
self.parent_firmware_uids = set()
self.temporary_data = {}
self.analysis_tags = {}
if binary is not None:
self.set_binary(binary)
else:
Expand Down
15 changes: 14 additions & 1 deletion src/plugins/analysis/crypto_material/code/crypto_material.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from analysis.YaraPluginBase import YaraBasePlugin
from helperFunctions.parsing import read_asn1_key, read_pkcs_cert, read_ssl_cert
from helperFunctions.tag import TagColor


class AnalysisPlugin(YaraBasePlugin):
Expand All @@ -8,7 +9,7 @@ class AnalysisPlugin(YaraBasePlugin):
'''
NAME = 'crypto_material'
DESCRIPTION = 'detects crypto material like SSH keys and SSL certificates'
VERSION = '0.5'
VERSION = '0.5.1'
FILE = __file__
STARTEND = ['PgpPublicKeyBlock', 'PgpPrivateKeyBlock', 'PgpPublicKeyBlock_GnuPG', 'genericPublicKey',
'SshRsaPrivateKeyBlock', 'SSLPrivateKey']
Expand Down Expand Up @@ -37,6 +38,7 @@ def process_object(self, file_object):
self.store_current_match_in_result(file_object=file_object, match=match, result=analysis_result, parsing_function=self.get_ssl_cert)

file_object.processed_analysis[self.NAME] = analysis_result
self._add_private_key_tag(file_object, analysis_result)
return file_object

def store_current_match_in_result(self, file_object, match, result, parsing_function):
Expand Down Expand Up @@ -98,3 +100,14 @@ def get_offset_pairs(strings=[]):
end_index = strings[index + 2][0] + len(strings[index + 2][2])
pairs.append((strings[index][0], end_index))
return pairs

def _add_private_key_tag(self, file_object, result):
if any('private' in key.lower() for key in result):
file_object.processed_analysis[self.NAME]['tags'] = {
'private_key_inside': {
'value': 'Private Key Found',
'color': TagColor.ORANGE,
'propagate': True,
},
'root_uid': file_object.get_root_uid()
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ def test_ssh_public(self):
self._rule_match('id_rsa.pub', 'SshRsaPublicKeyBlock')

def test_ssh_private(self):
self._rule_match('id_rsa', 'SshRsaPrivateKeyBlock')
self._rule_match('id_rsa', 'SshRsaPrivateKeyBlock', expected_number_of_rules=2)

def test_PKCS8(self):
self._rule_match('pkcs', 'Pkcs8PrivateKey')
self._rule_match('pkcs', 'Pkcs8PrivateKey', expected_number_of_rules=2)

def test_PKCS12(self):
self._rule_match('pkcs12', 'Pkcs12Certificate')

def test_SSL_key(self):
self._rule_match('ssl.key', 'SSLPrivateKey')
self._rule_match('ssl.key', 'SSLPrivateKey', expected_number_of_rules=2)

def test_SSL_cert(self):
self._rule_match('ssl.crt', 'SSLCertificate')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{% block analysis_result_details %}

{% for key in firmware.processed_analysis[selected_analysis] %}
{% if key not in ['summary', 'plugin_version', 'analysis_date'] %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change should be applied to src/web_interface/templates/analysis_plugins/generic.html as well

{% if key not in ['summary', 'plugin_version', 'analysis_date', 'tags'] %}
<tr>
<td class="active"> Description:</td>
<td class="active"> {{ key }} </td>
Expand Down
8 changes: 8 additions & 0 deletions src/scheduler/Analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from helperFunctions.parsing import bcolors
from helperFunctions.plugin import import_plugins
from helperFunctions.process import ExceptionSafeProcess, terminate_process_and_childs
from helperFunctions.tag import check_tags, add_tags_to_object
from storage.db_interface_backend import BackEndDbInterface


Expand All @@ -26,6 +27,7 @@ def __init__(self, config=None, post_analysis=None, db_interface=None):
self.load_plugins()
self.stop_condition = Value('i', 0)
self.process_queue = Queue()
self.tag_queue = Queue()
self.db_backend_service = db_interface if db_interface else BackEndDbInterface(config=config)
self.post_analysis = self.db_backend_service.add_object if post_analysis is None else post_analysis
self.start_scheduling_process()
Expand All @@ -46,6 +48,7 @@ def shutdown(self):
e.submit(self.analysis_plugins[plugin].shutdown)
if getattr(self.db_backend_service, 'shutdown', False):
self.db_backend_service.shutdown()
self.tag_queue.close()
self.process_queue.close()
logging.info('Analysis System offline')

Expand Down Expand Up @@ -157,6 +160,7 @@ def result_collector(self):
for plugin in self.analysis_plugins:
try:
fw = self.analysis_plugins[plugin].out_queue.get_nowait()
fw = self._handle_analysis_tags(fw, plugin)
except Empty:
pass
else:
Expand All @@ -165,6 +169,10 @@ def result_collector(self):
if nop:
sleep(int(self.config['ExpertSettings']['block_delay']))

def _handle_analysis_tags(self, fw, plugin):
self.tag_queue.put(check_tags(fw, plugin))
return add_tags_to_object(fw, plugin)

def check_further_process_or_complete(self, fw_object):
if not fw_object.scheduled_analysis:
logging.info('Analysis Completed:\n{}'.format(fw_object))
Expand Down
49 changes: 49 additions & 0 deletions src/scheduler/analysis_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import logging
from queue import Empty
from multiprocessing import Value
from helperFunctions.process import ExceptionSafeProcess


class TaggingDaemon:
def __init__(self, analysis_scheduler=None, db_interface=None):
self.parent = analysis_scheduler
self.config = self.parent.config
self.db_interface = db_interface if db_interface else self.parent.db_backend_service
self.stop_condition = Value('i', 0)

self.start_tagging_process()
logging.info('Tagging daemon online')

def shutdown(self):
self.stop_condition.value = 1
self.tagging_process.join()
logging.info('Tagging daemon offline')

def start_tagging_process(self):
self.tagging_process = ExceptionSafeProcess(target=self._analysis_tag_scheduler_main)
self.tagging_process.start()

def _analysis_tag_scheduler_main(self):
while self.stop_condition.value == 0:
self._fetch_next_tag()

def _fetch_next_tag(self):
try:
tags = self.parent.tag_queue.get(timeout=int(self.config['ExpertSettings']['block_delay']))
except Empty:
return

if not tags['notags']:
if self.db_interface.existence_quick_check(tags['uid']):
self._process_tags(tags)
else:
self.parent.tag_queue.put(tags)

def _process_tags(self, tags):
uid = tags['uid']
plugin_name = tags['plugin']
for tag_name, tag in tags['tags'].items():
if tag['propagate']:
# Tags should be deleted as well, how ?
self.db_interface.update_analysis_tags(uid=uid, plugin_name=plugin_name, tag_name=tag_name, tag=tag)
logging.debug('Tag {} set for plugin {} and uid {}'.format(tag_name, plugin_name, uid))
3 changes: 3 additions & 0 deletions src/start_fact_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from scheduler.Analysis import AnalysisScheduler
from scheduler.Compare import CompareScheduler
from scheduler.Unpacking import UnpackingScheduler
from scheduler.analysis_tag import TaggingDaemon
from statistic.work_load import WorkLoadStatistic

PROGRAM_NAME = 'FACT Backend'
Expand All @@ -46,6 +47,7 @@ def shutdown(signum, frame):
if __name__ == '__main__':
args, config = program_setup(PROGRAM_NAME, PROGRAM_DESCRIPTION)
analysis_service = AnalysisScheduler(config=config)
tagging_service = TaggingDaemon(analysis_scheduler=analysis_service)
unpacking_service = UnpackingScheduler(config=config, post_unpack=analysis_service.add_task, analysis_workload=analysis_service.get_scheduled_workload)
compare_service = CompareScheduler(config=config)
intercom = InterComBackEndBinding(config=config, analysis_service=analysis_service, compare_service=compare_service, unpacking_service=unpacking_service)
Expand All @@ -65,6 +67,7 @@ def shutdown(signum, frame):
intercom.shutdown()
compare_service.shutdown()
unpacking_service.shutdown()
tagging_service.shutdown()
analysis_service.shutdown()
if not args.testing:
complete_shutdown()
Loading