assemblyline-v4-service 4.5.1.dev232__py3-none-any.whl → 4.5.1.dev233__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of assemblyline-v4-service might be problematic. Click here for more details.

@@ -1 +1 @@
1
- 4.5.1.dev232
1
+ 4.5.1.dev233
@@ -1,9 +1,10 @@
1
1
  import json
2
2
  import os
3
3
  from collections import defaultdict
4
- from typing import Dict, Optional
4
+ from typing import Any, Dict, Optional, List, Tuple
5
5
 
6
6
  from assemblyline_v4_service.common import helper
7
+ from assemblyline_v4_service.common.result import HEUR_LIST, ResultSection
7
8
 
8
9
  from assemblyline.common import forge
9
10
  from assemblyline.common.dict_utils import flatten, get_dict_fingerprint_hash, unflatten
@@ -18,9 +19,30 @@ ONTOLOGY_CLASS_TO_FIELD = {
18
19
  NetworkConnection: "netflow"
19
20
  }
20
21
 
22
+ if not HEUR_LIST:
23
+ # Get heuristics of service if not already set
24
+ HEUR_LIST = helper.get_heuristics()
25
+
21
26
  Classification = forge.get_classification()
22
27
 
23
28
 
29
+ # Cleanup invalid tagging from service results
30
+ def validate_tags(tag_map: Dict[str, List[str]]) -> Dict[str, List[str]]:
31
+ tag_map, _ = construct_safe(Tagging, unflatten(tag_map))
32
+ tag_map = flatten(tag_map.as_primitives(strip_null=True))
33
+ return tag_map
34
+
35
+ # Merge tags
36
+ def merge_tags(tag_a: Dict[str, List[str]], tag_b: Dict[str, List[str]]) -> Dict[str, List[str]]:
37
+ if not tag_a:
38
+ return tag_b
39
+
40
+ elif not tag_b:
41
+ return tag_a
42
+
43
+ all_keys = list(tag_a.keys()) + list(tag_b.keys())
44
+ return {key: list(set(tag_a.get(key, []) + tag_b.get(key, []))) for key in all_keys}
45
+
24
46
  class OntologyHelper:
25
47
  def __init__(self, logger, service_name) -> None:
26
48
  self.log = logger
@@ -84,32 +106,12 @@ class OntologyHelper:
84
106
 
85
107
  ontology['results'].update(self.results)
86
108
 
87
- def _attach_ontology(self, request, working_dir) -> Optional[str]:
88
- # Get heuristics of service
89
- heuristics = helper.get_heuristics()
90
-
91
- def preprocess_result_for_dump(sections, current_max, heur_tag_map, tag_map):
109
+ def _preprocess_result_for_dump(self, sections: List[ResultSection], current_max: str,
110
+ heur_tag_map: Dict[str, Dict[str, Any]], tag_map: Dict[str, List[str]], score: int) -> Tuple[str, Dict[str, Dict[str, Any]], Dict[str, List[str]], int]:
92
111
  for section in sections:
93
112
  # Determine max classification of the overall result
94
113
  current_max = Classification.max_classification(section.classification, current_max)
95
114
 
96
- # Cleanup invalid tagging from service results
97
- def validate_tags(tag_map):
98
- tag_map, _ = construct_safe(Tagging, unflatten(tag_map))
99
- tag_map = flatten(tag_map.as_primitives(strip_null=True))
100
- return tag_map
101
-
102
- # Merge tags
103
- def merge_tags(tag_a, tag_b):
104
- if not tag_a:
105
- return tag_b
106
-
107
- elif not tag_b:
108
- return tag_a
109
-
110
- all_keys = list(tag_a.keys()) + list(tag_b.keys())
111
- return {key: list(set(tag_a.get(key, []) + tag_b.get(key, []))) for key in all_keys}
112
-
113
115
  # Append tags raised by the service, if any
114
116
  section_tags = validate_tags(section.tags)
115
117
  if section_tags:
@@ -117,8 +119,8 @@ class OntologyHelper:
117
119
 
118
120
  # Append tags associated to heuristics raised by the service, if any
119
121
  if section.heuristic:
120
- heur = heuristics[section.heuristic.heur_id]
121
- key = f'{request.task.service_name.upper()}_{heur.heur_id}'
122
+ heur = HEUR_LIST[section.heuristic.heur_id]
123
+ key = f'{self.service.upper()}_{heur.heur_id}'
122
124
  heur_tag_map[key].update({
123
125
  "heur_id": key,
124
126
  "name": heur.name,
@@ -126,24 +128,27 @@ class OntologyHelper:
126
128
  "score": heur.score,
127
129
  "times_raised": heur_tag_map[key]["times_raised"] + 1
128
130
  })
131
+ score += section.heuristic.score
129
132
 
130
133
  # Recurse through subsections
131
134
  if section.subsections:
132
- current_max, heur_tag_map, tag_map = preprocess_result_for_dump(
133
- section.subsections, current_max, heur_tag_map, tag_map)
135
+ current_max, heur_tag_map, tag_map = self._preprocess_result_for_dump(
136
+ section.subsections, current_max, heur_tag_map, tag_map, score)
134
137
 
135
- return current_max, heur_tag_map, tag_map
138
+ return current_max, heur_tag_map, tag_map, score
136
139
 
140
+ def _attach_ontology(self, request, working_dir) -> Optional[str]:
137
141
  if not request.result or not request.result.sections:
138
142
  # No service results, therefore no ontological output
139
143
  return
140
144
 
141
- max_result_classification, heur_tag_map, tag_map = preprocess_result_for_dump(
145
+ max_result_classification, heur_tag_map, tag_map, score = self._preprocess_result_for_dump(
142
146
  sections=request.result.sections,
143
147
  current_max=Classification.max_classification(request.task.min_classification,
144
148
  request.task.service_default_result_classification),
145
149
  heur_tag_map=defaultdict(lambda: {"tags": dict(), "times_raised": int()}),
146
- tag_map=defaultdict(list))
150
+ tag_map=defaultdict(list),
151
+ score=0)
147
152
 
148
153
  if not heur_tag_map and not tag_map and not self._result_parts:
149
154
  # No heuristics, tagging, or ontologies found, therefore informational results
@@ -168,7 +173,8 @@ class OntologyHelper:
168
173
  },
169
174
  "results": {
170
175
  "tags": tag_map,
171
- "heuristics": list(heur_tag_map.values())
176
+ "heuristics": list(heur_tag_map.values()),
177
+ "score": score
172
178
  }
173
179
  }
174
180
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: assemblyline-v4-service
3
- Version: 4.5.1.dev232
3
+ Version: 4.5.1.dev233
4
4
  Summary: Assemblyline 4 - Service base
5
5
  Home-page: https://github.com/CybercentreCanada/assemblyline-v4-service/
6
6
  Author: CCCS Assemblyline development team
@@ -1,4 +1,4 @@
1
- assemblyline_v4_service/VERSION,sha256=SKe4bEiWAVHRKVwsXso5Rp0XOe-qhtnReZqhrTTGYE0,13
1
+ assemblyline_v4_service/VERSION,sha256=Z6ozwNHb47WpLFd4QhbnMbJ7bL5wRoGPPh3JUf5voM4,13
2
2
  assemblyline_v4_service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  assemblyline_v4_service/healthz.py,sha256=sS1cFkDLw8hUPMpj7tbHXFv8ZmHcazrwZ0l6oQDwwkQ,1575
4
4
  assemblyline_v4_service/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -9,7 +9,7 @@ assemblyline_v4_service/common/api.py,sha256=Xzp8j4HCCfjPvNSGKiZl5ttH2_Itg47cjlH
9
9
  assemblyline_v4_service/common/base.py,sha256=4rnK_183qsSfkRkuVp_0wy-haW49umx4jJIC0OalGDM,14218
10
10
  assemblyline_v4_service/common/helper.py,sha256=xs9quuf-M1JOdKieBqOmWaOece0CtzXFhhe85xQYmuY,3289
11
11
  assemblyline_v4_service/common/ocr.py,sha256=3fV0PyY3oui_ucAM9dkolP0VRYKACKJuGY4M64DudIE,8841
12
- assemblyline_v4_service/common/ontology_helper.py,sha256=4YW_iqwX3PFMc9efknxzBHNxep64tEaVASYS8WFZTHw,7924
12
+ assemblyline_v4_service/common/ontology_helper.py,sha256=kiYI0ecQJc1zxEHePWTX73mAWTEdv4v3wpSk6ONQTsE,8270
13
13
  assemblyline_v4_service/common/request.py,sha256=W7fqC2xQE3i5i2jlCDyUDp3ZqJQQqSshNW0mQfJMkFg,11792
14
14
  assemblyline_v4_service/common/result.py,sha256=9AqM6qCYiia_Bpyn_fBFhzNQMcqJbtFSiGjp57fXW2E,32713
15
15
  assemblyline_v4_service/common/task.py,sha256=dJsvRpW0x88CCF_LW6w87jQ_UKTVaOs2Gb117IDNiU8,14233
@@ -33,13 +33,13 @@ test/test_common/test_api.py,sha256=7wlo7wgB12T23zMLbwjJ3GIomLHqE_Qvs3xkibSsR1U,
33
33
  test/test_common/test_base.py,sha256=fuJSSlPxIDHq6HU1xbvaMFitw2z1spOZNHD2SJ4UUic,13346
34
34
  test/test_common/test_helper.py,sha256=sO6YAiBhKTqaxlpLhFYDuy2ZdbuF2cg07Ylzo83ZzQs,2575
35
35
  test/test_common/test_ocr.py,sha256=mt_PgElgwQKJmNrp2nRVx9NjfMedVk40I6IV317vATI,1753
36
- test/test_common/test_ontology_helper.py,sha256=KhHEBg_ecJyQbDw79NMT4FzUyA4C1Aak3HEQCwBfM2s,7914
36
+ test/test_common/test_ontology_helper.py,sha256=a_bX1MPQnwV1QILGgrUSNsgMgCnl663fAB40cw3ElHI,10237
37
37
  test/test_common/test_request.py,sha256=Ceyds8BNO1O0f1kH1VEb84faJcaupvSjVKIrGdHexsc,11842
38
38
  test/test_common/test_result.py,sha256=6BiOKxEPrKBjOY44jv3TY-yiXm0qI1ok_CZBnjP9TM4,45447
39
39
  test/test_common/test_task.py,sha256=P44mNcSe-3tJgDk9ppN3KbM7oN4LBVIuhONG-Gveh74,19007
40
40
  test/test_common/test_utils.py,sha256=TbnBxqpS_ZC5ptXR9XJX3xtbItD0mTbtiBxxdyP8J5k,5904
41
- assemblyline_v4_service-4.5.1.dev232.dist-info/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
42
- assemblyline_v4_service-4.5.1.dev232.dist-info/METADATA,sha256=XPH7OTtdAKk7QHLCNCoirljClEHVbN5LztIQsTp7o5o,9493
43
- assemblyline_v4_service-4.5.1.dev232.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
44
- assemblyline_v4_service-4.5.1.dev232.dist-info/top_level.txt,sha256=LpTOEaVCatkrvbVq3EZseMSIa2PQZU-2rhuO_FTpZgY,29
45
- assemblyline_v4_service-4.5.1.dev232.dist-info/RECORD,,
41
+ assemblyline_v4_service-4.5.1.dev233.dist-info/LICENCE.md,sha256=NSkYo9EH8h5oOkzg4VhjAHF4339MqPP2cQ8msTPgl-c,1396
42
+ assemblyline_v4_service-4.5.1.dev233.dist-info/METADATA,sha256=q1LCbQQGOjZUK2eAqnpTpZefohsJQB6M-ysdVYjXQw4,9493
43
+ assemblyline_v4_service-4.5.1.dev233.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
44
+ assemblyline_v4_service-4.5.1.dev233.dist-info/top_level.txt,sha256=LpTOEaVCatkrvbVq3EZseMSIa2PQZU-2rhuO_FTpZgY,29
45
+ assemblyline_v4_service-4.5.1.dev233.dist-info/RECORD,,
@@ -7,7 +7,7 @@ from test.test_common import setup_module
7
7
  setup_module()
8
8
 
9
9
  import pytest
10
- from assemblyline_v4_service.common.ontology_helper import *
10
+ from assemblyline_v4_service.common.ontology_helper import OntologyHelper, validate_tags, merge_tags
11
11
  from assemblyline_v4_service.common.result import ResultSection
12
12
 
13
13
  from assemblyline.odm.models.ontology.ontology import ODM_VERSION
@@ -224,15 +224,75 @@ def test_attach_ontology(dummy_request_class):
224
224
  'odm_type': 'Assemblyline Result Ontology',
225
225
  'odm_version': ODM_VERSION,
226
226
  'results': {'heuristics': [],
227
- 'tags': {'network.static.domain': ['blah.com']}},
227
+ 'tags': {'network.static.domain': ['blah.com']},
228
+ 'score': 0},
228
229
  'service': {'name': 'blah',
229
230
  'tool_version': 'blah',
230
- 'version': '4.0.0'},
231
+ 'version': '4.0.0'}
231
232
  }
232
233
 
233
- # TODO
234
- # Test nested methods preprocess_result_for_dump, validate_tags and merge_tags
234
+ # Assign a heuristic to the section and check to see if the score gets updated correctly
235
+ req.result.sections[0].set_heuristic(1)
236
+ req.result.sections.append(req.result.sections[0])
237
+ req.task.supplementary = []
238
+ assert oh._attach_ontology(req, working_dir) is None
239
+ assert oh.results == {}
240
+ assert req.task.supplementary == [
241
+ {
242
+ 'classification': 'TLP:C',
243
+ 'description': 'Result Ontology from blah',
244
+ 'name': 'blah_blah.ontology',
245
+ 'path': os.path.join(working_dir, "blah.ontology")
246
+ }
247
+ ]
235
248
 
249
+ with open(os.path.join(working_dir, "blah.ontology"), "r") as f:
250
+ file_contents = json.loads(f.read())
251
+ # The sum of the overall result should be 500 points since the heuristic was raised twice with a score of 250 per section
252
+ assert file_contents == {
253
+ 'classification': 'TLP:C',
254
+ 'file': {'md5': 'blah',
255
+ 'names': ['blah'],
256
+ 'sha1': 'blah',
257
+ 'sha256': 'blah',
258
+ 'size': 123,
259
+ 'type': None},
260
+ 'odm_type': 'Assemblyline Result Ontology',
261
+ 'odm_version': ODM_VERSION,
262
+ 'results': {'heuristics': [{'tags': {'network.static.domain': ['blah.com']}, 'times_raised': 2, 'heur_id': 'BLAH_1', 'name': 'blah', 'score': 250}],
263
+ 'tags': {'network.static.domain': ['blah.com']},
264
+ 'score': 500},
265
+ 'service': {'name': 'blah',
266
+ 'tool_version': 'blah',
267
+ 'version': '4.0.0'}
268
+ }
269
+
270
+
271
+ def test_validate_tags():
272
+ # Valid tag
273
+ assert validate_tags({'network.static.domain':['blah.com']})
274
+
275
+ # Invalid tag
276
+ assert not validate_tags({'blah':['blah.com']})
277
+
278
+ def test_merge_tags():
279
+ # Merge with null should yield the tag map with value
280
+ assert merge_tags({'abc':['xyz']}, None) == {'abc':['xyz']}
281
+ assert merge_tags(None, {'abc':['xyz']}) == {'abc':['xyz']}
282
+
283
+ # Merge with mutually exclusive keys
284
+ assert merge_tags({'abc':['xyz']}, {'def':['xyz']}) == {
285
+ 'abc':['xyz'],
286
+ 'def':['xyz']
287
+ }
288
+
289
+ # Merge with non-mutually exclusive keys
290
+ merged_tags = merge_tags({'abc':['xyz'], 'def':['tuv']}, {'def':['xyz']})
291
+ merged_tags['def'] = sorted(merged_tags['def'])
292
+ merged_tags == {
293
+ 'abc':['xyz'],
294
+ 'def':['tuv', 'xyz']
295
+ }
236
296
 
237
297
  def test_reset():
238
298
  oh = OntologyHelper(None, "blah")