Skip to content

Commit

Permalink
Merge pull request #102 from CybercentreCanada/dev
Browse files Browse the repository at this point in the history
Add sub-verdict heuristic and gene percentage
  • Loading branch information
cccs-nafihasan authored Oct 10, 2024
2 parents 4c7980d + 9578745 commit bace1cb
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 10 deletions.
52 changes: 51 additions & 1 deletion intezer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"sha256",
"verdict",
"family_id",
"sub_verdict"
]
UNINTERESTING_SUBANALYSIS_KEYS = [
"source",
Expand All @@ -54,6 +55,17 @@
"size_in_bytes",
"ssdeep",
]
UNINTERESTING_SUBVERDICT_KEYS = [
"analysis_id",
"analysis_time",
"analysis_url",
"family_id",
"family_name",
"file_name",
"is_private",
"sha256",
"verdict",
]
UNINTERESTING_FAMILY_KEYS = ["family_id"]

FAMILIES_TO_NOT_TAG = ["application", "library"]
Expand Down Expand Up @@ -555,6 +567,7 @@ def execute(self, request: ServiceRequest) -> None:
main_api_result = main_api_result_from_retrieval

verdict = main_api_result.get("verdict")
subverdict = main_api_result.get("sub_verdict")
verdict = self._massage_verdict(request, result, main_api_result, verdict)
if not verdict:
return
Expand All @@ -569,6 +582,7 @@ def execute(self, request: ServiceRequest) -> None:
main_kv_section = ResultKeyValueSection("Intezer analysis report")
processed_main_api_result = self._process_details(main_api_result.copy(), UNINTERESTING_ANALYSIS_KEYS)
main_kv_section.update_items(processed_main_api_result)

if "family_name" in main_api_result and main_api_result["family_name"] not in [GENERIC_MALWARE, NOT_APPLICABLE]:
# Don't tag administration tool families
if verdict != Verdicts.ADMINISTRATION_TOOL.value:
Expand All @@ -590,8 +604,15 @@ def execute(self, request: ServiceRequest) -> None:
verdict = file_verdict_map[sha256]
self._set_heuristic_by_verdict(main_kv_section, verdict)

sub_verdict_kv_section = ResultKeyValueSection("Intezer sub-verdict")
processed_main_api_sub_verdict_result = self._process_details(main_api_result.copy(), UNINTERESTING_SUBVERDICT_KEYS)
sub_verdict_kv_section.update_items(processed_main_api_sub_verdict_result)
self._set_heuristic_by_sub_verdict(sub_verdict_kv_section, subverdict)

if main_kv_section.subsections or main_kv_section.heuristic:
result.add_section(main_kv_section)
if sub_verdict_kv_section.subsections or sub_verdict_kv_section.heuristic:
result.add_section(sub_verdict_kv_section)
request.result = result

def _get_analysis_metadata(self, analysis_id: str, sha256: str) -> Dict[str, str]:
Expand Down Expand Up @@ -751,6 +772,31 @@ def _set_heuristic_by_verdict(self, result_section: ResultSection, verdict: Opti
elif verdict in Verdicts.FAMILY_TYPE_OF_INTEREST_VERDICTS.value:
result_section.set_heuristic(3)

def _set_heuristic_by_sub_verdict(self, result_section: ResultSection, subverdict: Optional[str]) -> None:
"""
This method sets the heuristic of the result section based on the verdict
:param result_section: The result section that will have its heuristic set
:param verdict: The verdict of the file
:return: None
"""
if not subverdict:
return

if subverdict in Verdicts.MALICIOUS.value:
result_section.set_heuristic(13)
elif subverdict in Verdicts.KNOWN_MALICIOUS.value:
result_section.set_heuristic(14)
elif subverdict in Verdicts.SUSPICIOUS.value:
result_section.set_heuristic(15)
elif subverdict in Verdicts.UNIQUE.value:
result_section.set_heuristic(16)
elif subverdict in Verdicts.TRUSTED.value:
result_section.set_heuristic(17)
elif subverdict in Verdicts.ADMINISTRATION_TOOL.value:
result_section.set_heuristic(18)
elif subverdict in Verdicts.KNOWN_ADMINISTRATION_TOOL.value:
result_section.set_heuristic(19)

def _process_iocs(
self,
analysis_id: str,
Expand Down Expand Up @@ -1034,9 +1080,13 @@ def _process_families(
:return: None
"""
family_section = ResultTableSection("Family Details")
family_section.set_column_order(["family_name", "family_type", "reused_code_count"])
family_section.set_column_order(["family_name", "family_type", "reused_code_count", "gene_percentage"])
total_genes = 0
for family in families:
total_genes += family["reused_gene_count"]
for family in families:
processed_family = self._process_details(family.copy(), UNINTERESTING_FAMILY_KEYS)
processed_family["gene_percentage"] = str(round((family["reused_gene_count"] / total_genes) * 100, 2)) + "%"
family_section.add_row(TableRow(**processed_family))
family_type = family["family_type"]
family_name = family["family_name"]
Expand Down
35 changes: 35 additions & 0 deletions service_manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,41 @@ heuristics:
score: 0
filetype: .*
description: Intezer has detected reused malware genes
- heur_id: 13
name: Intezer found a subverdict malicious
score: 1000
filetype: .*
description: Intezer has found this submission as malicious
- heur_id: 14
name: Intezer found a subverdict known malicious
score: 1000
filetype: .*
description: Intezer has found this submission as known malicious
- heur_id: 15
name: Intezer found a subverdict suspicious
score: 500
filetype: .*
description: Intezer has found this submission as suspicious
- heur_id: 16
name: Intezer found a subverdict unique
score: 50
filetype: .*
description: Intezer has found this submission as unique
- heur_id: 17
name: Intezer found a subverdict trusted
score: 0
filetype: .*
description: Intezer has found this submission as trusted
- heur_id: 18
name: Intezer found a subverdict administration_tool
score: 100
filetype: .*
description: Intezer has found this submission as administration_tool
- heur_id: 19
name: Intezer found a subverdict known_administration_tool
score: 100
filetype: .*
description: Intezer has found this submission as known_administration_tool

docker_config:
allow_internet_access: true
Expand Down
18 changes: 9 additions & 9 deletions tests/test_intezer.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,39 +604,39 @@ def test_handle_subanalyses(
"families, file_verdict_map, correct_fvp",
[
([], {}, {}),
([{"blah": "blah", "family_type": "blah", "family_name": "blah", "reused_gene_count": 4}], {}, {}),
([{"family_id": "blah", "family_type": "blah", "family_name": "blah", "reused_gene_count": 4}], {}, {}),
([{"blah": "blah", "family_type": "blah", "family_name": "blah", "reused_gene_count": 4, "gene_percentage": "100.0%"}], {}, {}),
([{"family_id": "blah", "family_type": "blah", "family_name": "blah", "reused_gene_count": 4, "gene_percentage": "100.0%"}], {}, {}),
(
[{"family_id": "blah", "family_type": "application", "family_name": "blah", "reused_gene_count": 6}],
[{"family_id": "blah", "family_type": "application", "family_name": "blah", "reused_gene_count": 6, "gene_percentage": "100.0%"}],
{},
{},
),
(
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 6}],
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 6, "gene_percentage": "100.0%"}],
{},
{"blah": "malicious"},
),
(
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 6}],
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 6, "gene_percentage": "100.0%"}],
{"blah": "blah"},
{"blah": "malicious"},
),
(
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 66}],
[{"family_id": "blah", "family_type": "malware", "family_name": "blah", "reused_gene_count": 66, "gene_percentage": "100.0%"}],
{"blah": "malicious"},
{"blah": "malicious"},
),
(
[{"family_id": "blah", "family_type": "packer", "family_name": "blah", "reused_gene_count": 6}],
[{"family_id": "blah", "family_type": "packer", "family_name": "blah", "reused_gene_count": 6, "gene_percentage": "100.0%"}],
{},
{"blah": "interesting"},
),
(
[{"family_id": "blah", "family_type": "packer", "family_name": "blah", "reused_gene_count": 6}],
[{"family_id": "blah", "family_type": "packer", "family_name": "blah", "reused_gene_count": 6, "gene_percentage": "100.0%"}],
{"blah": "malicious"},
{"blah": "malicious"},
),
([{"family_id": "blah", "family_type": "packer", "family_name": "UPX", "reused_gene_count": 6}], {}, {}),
([{"family_id": "blah", "family_type": "packer", "family_name": "UPX", "reused_gene_count": 6, "gene_percentage": "100.0%"}], {}, {}),
],
)
def test_process_families(families, file_verdict_map, correct_fvp, intezer_class_instance):
Expand Down

0 comments on commit bace1cb

Please sign in to comment.