add: [stix2 export] Exporting user-account objects

pull/4861/head
chrisr3d 2019-07-08 16:29:18 +02:00
parent ca3dca42aa
commit 4dd780c25d
No known key found for this signature in database
GPG Key ID: 6BBED1B63A6D639F
2 changed files with 59 additions and 0 deletions

View File

@ -198,6 +198,8 @@ class StixBuilder():
'stix2': {'pattern': self.resolve_stix2_pattern},
'url': {'observable': self.resolve_url_observable,
'pattern': self.resolve_url_pattern},
'user-account': {'observable': self.resolve_user_account_observable,
'pattern': self.resolve_user_account_pattern},
'x509': {'observable': self.resolve_x509_observable,
'pattern': self.resolve_x509_pattern}
}
@ -1261,6 +1263,52 @@ class StixBuilder():
pattern.append(objectsMapping[mapping]['pattern'].format(stix_type, attribute['value']))
return "[{}]".format(" AND ".join(pattern))
def resolve_user_account_observable(self, attributes, object_id):
attributes = self.parse_user_account_attributes(attributes, object_id)
observable = {'type': 'user-account'}
extension = {}
for relation, value in attributes.items():
try:
observable[userAccountMapping[relation]] = value
except KeyError:
try:
extension[unixAccountExtensionMapping[relation]] = value
except KeyError:
continue
if extension:
observable['extensions']['unix-account-ext'] = extension
return {'0': observable}
def resolve_user_account_pattern(self, attributes, object_id):
mapping = objectsMapping['user-account']['to_call']
attributes = self.parse_user_account_attributes(attributes, object_id)
pattern = []
for relation, value in attributes.items():
try:
pattern_part = mapping.format(userAccountMapping[relation], value)
except KeyError:
try:
pattern_part = mapping.format('extensions.unix-account-ext.{}'.format(unixAccountExtensionMapping[relation]), value)
except KeyError:
continue
pattern.append(pattern_part)
return "[{}]".format(' AND '.join(pattern))
def parse_user_account_attributes(self, attributes, object_id):
tmp_attributes = defaultdict(list)
for attribute in attributes:
self.parse_galaxies(attribute['Galaxy'], object_id)
relation = attribute['object_relation']
if relation == 'group':
tmp_attributes[relation].append(attribute['value'])
else:
tmp_attributes[relation] = attribute['value']
if 'user-id' not in tmp_attributes and 'username' in tmp_attributes:
tmp_attributes['user-id'] = tmp_attributes.pop('username')
if 'text' in tmp_attributes:
tmp_attributes.pop('text')
return tmp_attributes
def resolve_x509_observable(self, attributes, object_id):
observable = {'type': 'x509-certificate'}
hashes = {}

View File

@ -307,6 +307,8 @@ objectsMapping = {'asn': {'to_call': 'handle_usual_object_name',
'url': {'to_call': 'handle_usual_object_name',
'observable': {'0': {'type': 'url'}},
'pattern': "url:{0} = '{1}'"},
'user-account': {'to_call': 'handle_usual_object_name',
'pattern': "user-account:{0} = '{1}'"},
'vulnerability': {'to_call': 'add_object_vulnerability'},
'x509': {'to_call': 'handle_usual_object_name',
'pattern': "x509-certificate:{0} = '{1}' AND "}
@ -352,6 +354,15 @@ regkeyMapping = {'data-type': 'data_type', 'data': 'data', 'name': 'name',
urlMapping = {'url': 'value', 'domain': 'value', 'port': 'dst_port'}
userAccountMapping = {'account-type': 'account_type', 'can_escalate_privs': 'can_escalate_privs',
'created': 'account_created', 'disabled': 'is_disabled', 'display-name': 'display_name',
'expires': 'account_expires', 'first_login': 'account_first_login',
'is_service_account': 'is_service_account', 'last_login': 'account_last_login',
'password': 'credential', 'password_last_changed': 'credential_last_changed',
'privileged': 'is_privileged', 'username': 'account_login', 'user-id': 'user_id'}
unixAccountExtensionMapping = {'group': 'groups', 'group-id': 'gid', 'home_dir': 'home_dir', 'shell': 'shell'}
x509mapping = {'pubkey-info-algorithm': 'subject_public_key_algorithm', 'subject': 'subject',
'pubkey-info-exponent': 'subject_public_key_exponent', 'issuer': 'issuer',
'pubkey-info-modulus': 'subject_public_key_modulus', 'serial-number': 'serial_number',