forked from p15670423/monkey
Merge pull request #1483 from guardicore/incorrect-attack-report-msgs
Fix incorrect ATT&CK report messages
This commit is contained in:
commit
0839f04b1d
|
@ -15,9 +15,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "snippet",
|
"type": "snippet",
|
||||||
"path": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
|
||||||
"comments": [],
|
|
||||||
"firstLineNumber": 56,
|
|
||||||
"lines": [
|
"lines": [
|
||||||
" \"Removes the file afterwards.\",",
|
" \"Removes the file afterwards.\",",
|
||||||
" \"attack_techniques\": [\"T1166\"],",
|
" \"attack_techniques\": [\"T1166\"],",
|
||||||
|
@ -26,7 +23,7 @@
|
||||||
"+ # Swimmer: ADD DETAILS HERE!",
|
"+ # Swimmer: ADD DETAILS HERE!",
|
||||||
"* \"type\": \"string\",",
|
"* \"type\": \"string\",",
|
||||||
"* \"enum\": [\"ScheduleJobs\"],",
|
"* \"enum\": [\"ScheduleJobs\"],",
|
||||||
"* \"title\": \"Job scheduling\",",
|
"* \"title\": \"Job Scheduling\",",
|
||||||
"* \"safe\": True,",
|
"* \"safe\": True,",
|
||||||
"* \"info\": \"Attempts to create a scheduled job on the system and remove it.\",",
|
"* \"info\": \"Attempts to create a scheduled job on the system and remove it.\",",
|
||||||
"* \"attack_techniques\": [\"T1168\", \"T1053\"],",
|
"* \"attack_techniques\": [\"T1168\", \"T1053\"],",
|
||||||
|
@ -34,7 +31,10 @@
|
||||||
" {",
|
" {",
|
||||||
" \"type\": \"string\",",
|
" \"type\": \"string\",",
|
||||||
" \"enum\": [\"Timestomping\"],"
|
" \"enum\": [\"Timestomping\"],"
|
||||||
]
|
],
|
||||||
|
"firstLineNumber": 52,
|
||||||
|
"path": "monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py",
|
||||||
|
"comments": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
|
@ -42,11 +42,11 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"symbols": {},
|
"symbols": {},
|
||||||
"file_version": "2.0.1",
|
"file_version": "2.0.3",
|
||||||
"meta": {
|
"meta": {
|
||||||
"app_version": "0.4.1-1",
|
"app_version": "0.5.7-0",
|
||||||
"file_blobs": {
|
"file_blobs": {
|
||||||
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "ea9b18aba7f71da12c9c82ac39d8a0cf2c472a9c"
|
"monkey/monkey_island/cc/services/config_schema/definitions/post_breach_actions.py": "7d62ac36e875ca3c249d808250cb3268e4d3d68d"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,10 +77,9 @@
|
||||||
" \"attack_techniques\": [\"T1082\"],",
|
" \"attack_techniques\": [\"T1082\"],",
|
||||||
" },",
|
" },",
|
||||||
"* {",
|
"* {",
|
||||||
"+ # SWIMMER: Collector config goes here. Tip: Hostname collection relates to the T1082 and T1016 techniques.",
|
|
||||||
"* \"type\": \"string\",",
|
"* \"type\": \"string\",",
|
||||||
"* \"enum\": [HOSTNAME_COLLECTOR],",
|
"* \"enum\": [HOSTNAME_COLLECTOR],",
|
||||||
"* \"title\": \"Hostname collector\",",
|
"* \"title\": \"Hostname Collector\",",
|
||||||
"* \"safe\": True,",
|
"* \"safe\": True,",
|
||||||
"* \"info\": \"Collects machine's hostname.\",",
|
"* \"info\": \"Collects machine's hostname.\",",
|
||||||
"* \"attack_techniques\": [\"T1082\", \"T1016\"],",
|
"* \"attack_techniques\": [\"T1082\", \"T1016\"],",
|
||||||
|
@ -110,7 +109,7 @@
|
||||||
"type": "snippet",
|
"type": "snippet",
|
||||||
"path": "monkey/monkey_island/cc/services/config_schema/monkey.py",
|
"path": "monkey/monkey_island/cc/services/config_schema/monkey.py",
|
||||||
"comments": [],
|
"comments": [],
|
||||||
"firstLineNumber": 92,
|
"firstLineNumber": 91,
|
||||||
"lines": [
|
"lines": [
|
||||||
" \"default\": [",
|
" \"default\": [",
|
||||||
" ENVIRONMENT_COLLECTOR,",
|
" ENVIRONMENT_COLLECTOR,",
|
||||||
|
@ -195,14 +194,14 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"symbols": {},
|
"symbols": {},
|
||||||
"file_version": "2.0.1",
|
"file_version": "2.0.3",
|
||||||
"meta": {
|
"meta": {
|
||||||
"app_version": "0.4.4-0",
|
"app_version": "0.5.7-0",
|
||||||
"file_blobs": {
|
"file_blobs": {
|
||||||
"monkey/common/common_consts/system_info_collectors_names.py": "175a054e1408805a4cebbe27e2f9616db40988cf",
|
"monkey/common/common_consts/system_info_collectors_names.py": "175a054e1408805a4cebbe27e2f9616db40988cf",
|
||||||
"monkey/infection_monkey/system_info/collectors/hostname_collector.py": "0aeecd9fb7bde83cccd4501ec03e0da199ec5fc3",
|
"monkey/infection_monkey/system_info/collectors/hostname_collector.py": "0aeecd9fb7bde83cccd4501ec03e0da199ec5fc3",
|
||||||
"monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py": "9a4a39050eb088876df4fa629e14faf820e714a0",
|
"monkey/monkey_island/cc/services/config_schema/definitions/system_info_collector_classes.py": "072640352fc9d50fe09752cfc951dab7d99271af",
|
||||||
"monkey/monkey_island/cc/services/config_schema/monkey.py": "e745da5828c63e975625ac2e9b80ce9626324970",
|
"monkey/monkey_island/cc/services/config_schema/monkey.py": "da06123a95eebf7f0a68861815ee644bb37c8db6",
|
||||||
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py": "e2de4519cbd71bba70e81cf3ff61817437d95a21",
|
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/hostname.py": "e2de4519cbd71bba70e81cf3ff61817437d95a21",
|
||||||
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py": "7ce4b6fcfbce0d6cd8a60297213c5be1699b22df"
|
"monkey/monkey_island/cc/services/telemetry/processing/system_info_collectors/system_info_telemetry_dispatcher.py": "7ce4b6fcfbce0d6cd8a60297213c5be1699b22df"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Changed
|
### Changed
|
||||||
- The name of the "Communicate as new user" post-breach action to "Communicate
|
- The name of the "Communicate as new user" post-breach action to "Communicate
|
||||||
as backdoor user". #1410
|
as backdoor user". #1410
|
||||||
|
- ATT&CK report messages (more accurate now). #1483
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Internet access check on agent start. #1402
|
- Internet access check on agent start. #1402
|
||||||
|
|
|
@ -214,9 +214,10 @@ SCHEMA = {
|
||||||
"value": False,
|
"value": False,
|
||||||
"necessary": False,
|
"necessary": False,
|
||||||
"link": "https://attack.mitre.org/techniques/T1216",
|
"link": "https://attack.mitre.org/techniques/T1216",
|
||||||
"description": "Adversaries may use scripts signed with "
|
"description": "Adversaries may use scripts signed with trusted certificates "
|
||||||
"trusted certificates to "
|
"to proxy execution of malicious files on Windows systems. This behavior could "
|
||||||
"proxy execution of malicious files on Windows systems.",
|
"be abused by adversaries to execute malicious files that could bypass "
|
||||||
|
"application control and signature validation on systems.",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,6 +6,7 @@ from monkey_island.cc.services.reporting.report import ReportService
|
||||||
|
|
||||||
class T1003(AttackTechnique):
|
class T1003(AttackTechnique):
|
||||||
tech_id = "T1003"
|
tech_id = "T1003"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = (
|
unscanned_msg = (
|
||||||
"Monkey tried to obtain credentials from systems in the network but didn't "
|
"Monkey tried to obtain credentials from systems in the network but didn't "
|
||||||
"find any or failed."
|
"find any or failed."
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1005(AttackTechnique):
|
class T1005(AttackTechnique):
|
||||||
tech_id = "T1005"
|
tech_id = "T1005"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't gather any sensitive data from local system."
|
unscanned_msg = "Monkey didn't gather any sensitive data from local system."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey successfully gathered sensitive data from local system."
|
used_msg = "Monkey successfully gathered sensitive data from local system."
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1016(AttackTechnique):
|
class T1016(AttackTechnique):
|
||||||
tech_id = "T1016"
|
tech_id = "T1016"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't gather network configurations."
|
unscanned_msg = "Monkey didn't gather network configurations."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey gathered network configurations on systems in the network."
|
used_msg = "Monkey gathered network configurations on systems in the network."
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1018(AttackTechnique):
|
class T1018(AttackTechnique):
|
||||||
tech_id = "T1018"
|
tech_id = "T1018"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't find any machines on the network."
|
unscanned_msg = "Monkey didn't find any machines on the network."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey found machines on the network."
|
used_msg = "Monkey found machines on the network."
|
||||||
|
|
|
@ -6,6 +6,7 @@ from monkey_island.cc.services.attack.technique_reports.technique_report_tools i
|
||||||
|
|
||||||
class T1021(AttackTechnique):
|
class T1021(AttackTechnique):
|
||||||
tech_id = "T1021"
|
tech_id = "T1021"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to login to any remote services."
|
unscanned_msg = "Monkey didn't try to login to any remote services."
|
||||||
scanned_msg = "Monkey tried to login to remote services with valid credentials, but failed."
|
scanned_msg = "Monkey tried to login to remote services with valid credentials, but failed."
|
||||||
used_msg = "Monkey successfully logged into remote services on the network."
|
used_msg = "Monkey successfully logged into remote services on the network."
|
||||||
|
|
|
@ -3,10 +3,8 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
|
||||||
|
|
||||||
class T1035(UsageTechnique):
|
class T1035(UsageTechnique):
|
||||||
tech_id = "T1035"
|
tech_id = "T1035"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Windows"]
|
||||||
"Monkey didn't try to interact with Windows services since it didn't run on "
|
unscanned_msg = "Monkey didn't try to interact with Windows services."
|
||||||
"any Windows machines."
|
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried to interact with Windows services, but failed."
|
scanned_msg = "Monkey tried to interact with Windows services, but failed."
|
||||||
used_msg = "Monkey successfully interacted with Windows services."
|
used_msg = "Monkey successfully interacted with Windows services."
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1041(AttackTechnique):
|
class T1041(AttackTechnique):
|
||||||
tech_id = "T1041"
|
tech_id = "T1041"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't exfiltrate any info through command and control channel."
|
unscanned_msg = "Monkey didn't exfiltrate any info through command and control channel."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey exfiltrated info through command and control channel."
|
used_msg = "Monkey exfiltrated info through command and control channel."
|
||||||
|
|
|
@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1053(PostBreachTechnique):
|
class T1053(PostBreachTechnique):
|
||||||
tech_id = "T1053"
|
tech_id = "T1053"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Windows"]
|
||||||
"Monkey didn't try scheduling a job on Windows since it didn't run on any Windows machines."
|
unscanned_msg = "Monkey didn't try scheduling a job on any Windows system."
|
||||||
)
|
scanned_msg = "Monkey tried scheduling a job on a Windows system but failed."
|
||||||
scanned_msg = "Monkey tried scheduling a job on the Windows system but failed."
|
used_msg = "Monkey scheduled a job on a Windows system."
|
||||||
used_msg = "Monkey scheduled a job on the Windows system."
|
|
||||||
pba_names = [POST_BREACH_JOB_SCHEDULING]
|
pba_names = [POST_BREACH_JOB_SCHEDULING]
|
||||||
|
|
|
@ -5,7 +5,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1059(AttackTechnique):
|
class T1059(AttackTechnique):
|
||||||
tech_id = "T1059"
|
tech_id = "T1059"
|
||||||
unscanned_msg = "Monkey didn't exploit any machines to run commands at."
|
relevant_systems = ["Linux", "Windows"]
|
||||||
|
unscanned_msg = "Monkey didn't exploit any machines to run commands on."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey successfully ran commands on exploited machines in the network."
|
used_msg = "Monkey successfully ran commands on exploited machines in the network."
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
|
||||||
|
|
||||||
class T1064(UsageTechnique):
|
class T1064(UsageTechnique):
|
||||||
tech_id = "T1064"
|
tech_id = "T1064"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't run scripts or tried to run and failed."
|
unscanned_msg = "Monkey didn't run scripts or tried to run and failed."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey ran scripts on machines in the network."
|
used_msg = "Monkey ran scripts on machines in the network."
|
||||||
|
|
|
@ -6,6 +6,7 @@ from monkey_island.cc.services.config import ConfigService
|
||||||
|
|
||||||
class T1065(AttackTechnique):
|
class T1065(AttackTechnique):
|
||||||
tech_id = "T1065"
|
tech_id = "T1065"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = ""
|
unscanned_msg = ""
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = ""
|
used_msg = ""
|
||||||
|
|
|
@ -5,9 +5,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1075(AttackTechnique):
|
class T1075(AttackTechnique):
|
||||||
tech_id = "T1075"
|
tech_id = "T1075"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Windows"]
|
||||||
"Monkey didn't try to use pass the hash attack since it didn't run on any Windows machines."
|
unscanned_msg = "Monkey didn't try to use pass the hash attack."
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."
|
scanned_msg = "Monkey tried to use hashes while logging in but didn't succeed."
|
||||||
used_msg = "Monkey successfully used hashed credentials."
|
used_msg = "Monkey successfully used hashed credentials."
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1082(AttackTechnique):
|
class T1082(AttackTechnique):
|
||||||
tech_id = "T1082"
|
tech_id = "T1082"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't gather any system info on the network."
|
unscanned_msg = "Monkey didn't gather any system info on the network."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey gathered system info from machines in the network."
|
used_msg = "Monkey gathered system info from machines in the network."
|
||||||
|
|
|
@ -5,9 +5,10 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1086(AttackTechnique):
|
class T1086(AttackTechnique):
|
||||||
tech_id = "T1086"
|
tech_id = "T1086"
|
||||||
unscanned_msg = "Monkey didn't run powershell since it didn't run on any Windows machines."
|
relevant_systems = ["Windows"]
|
||||||
|
unscanned_msg = "Monkey didn't run PowerShell."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey successfully ran powershell commands on exploited machines in the network."
|
used_msg = "Monkey successfully ran PowerShell commands on exploited machines in the network."
|
||||||
|
|
||||||
query = [
|
query = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1087(PostBreachTechnique):
|
class T1087(PostBreachTechnique):
|
||||||
tech_id = "T1087"
|
tech_id = "T1087"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to get a listing of user accounts."
|
unscanned_msg = "Monkey didn't try to get a listing of user accounts."
|
||||||
scanned_msg = "Monkey tried to get a listing of user accounts but failed to do so."
|
scanned_msg = "Monkey tried to get a listing of user accounts but failed to do so."
|
||||||
used_msg = "Monkey got a listing of user accounts successfully."
|
used_msg = "Monkey got a listing of user accounts successfully."
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1090(AttackTechnique):
|
class T1090(AttackTechnique):
|
||||||
tech_id = "T1090"
|
tech_id = "T1090"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't use connection proxy."
|
unscanned_msg = "Monkey didn't use connection proxy."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey used connection proxy to communicate with machines on the network."
|
used_msg = "Monkey used connection proxy to communicate with machines on the network."
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1099(PostBreachTechnique):
|
class T1099(PostBreachTechnique):
|
||||||
tech_id = "T1099"
|
tech_id = "T1099"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try changing any file's time attributes."
|
unscanned_msg = "Monkey didn't try changing any file's time attributes."
|
||||||
scanned_msg = "Monkey tried changing a file's time attributes but failed."
|
scanned_msg = "Monkey tried changing a file's time attributes but failed."
|
||||||
used_msg = "Monkey successfully changed a file's time attributes."
|
used_msg = "Monkey successfully changed a file's time attributes."
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1105(AttackTechnique):
|
class T1105(AttackTechnique):
|
||||||
tech_id = "T1105"
|
tech_id = "T1105"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to copy files to any systems."
|
unscanned_msg = "Monkey didn't try to copy files to any systems."
|
||||||
scanned_msg = "Monkey tried to copy files, but failed."
|
scanned_msg = "Monkey tried to copy files, but failed."
|
||||||
used_msg = "Monkey successfully copied files to systems on the network."
|
used_msg = "Monkey successfully copied files to systems on the network."
|
||||||
|
|
|
@ -3,6 +3,7 @@ from monkey_island.cc.services.attack.technique_reports.usage_technique import U
|
||||||
|
|
||||||
class T1106(UsageTechnique):
|
class T1106(UsageTechnique):
|
||||||
tech_id = "T1106"
|
tech_id = "T1106"
|
||||||
|
relevant_systems = ["Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to directly use WinAPI."
|
unscanned_msg = "Monkey didn't try to directly use WinAPI."
|
||||||
scanned_msg = "Monkey tried to use WinAPI, but failed."
|
scanned_msg = "Monkey tried to use WinAPI, but failed."
|
||||||
used_msg = "Monkey successfully used WinAPI."
|
used_msg = "Monkey successfully used WinAPI."
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1107(AttackTechnique):
|
class T1107(AttackTechnique):
|
||||||
tech_id = "T1107"
|
tech_id = "T1107"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = ""
|
unscanned_msg = ""
|
||||||
scanned_msg = "Monkey tried to delete files on systems in the network, but failed."
|
scanned_msg = "Monkey tried to delete files on systems in the network, but failed."
|
||||||
used_msg = "Monkey successfully deleted files on systems in the network."
|
used_msg = "Monkey successfully deleted files on systems in the network."
|
||||||
|
|
|
@ -6,6 +6,7 @@ from monkey_island.cc.services.attack.technique_reports.technique_report_tools i
|
||||||
|
|
||||||
class T1110(AttackTechnique):
|
class T1110(AttackTechnique):
|
||||||
tech_id = "T1110"
|
tech_id = "T1110"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to brute force any services."
|
unscanned_msg = "Monkey didn't try to brute force any services."
|
||||||
scanned_msg = "Monkey tried to brute force some services, but failed."
|
scanned_msg = "Monkey tried to brute force some services, but failed."
|
||||||
used_msg = "Monkey successfully used brute force in the network."
|
used_msg = "Monkey successfully used brute force in the network."
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1136(PostBreachTechnique):
|
class T1136(PostBreachTechnique):
|
||||||
tech_id = "T1136"
|
tech_id = "T1136"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try creating a new user on the network's systems."
|
unscanned_msg = "Monkey didn't try creating a new user on the network's systems."
|
||||||
scanned_msg = "Monkey tried creating a new user on the network's systems, but failed."
|
scanned_msg = "Monkey tried creating a new user on the network's systems, but failed."
|
||||||
used_msg = "Monkey created a new user on the network's systems."
|
used_msg = "Monkey created a new user on the network's systems."
|
||||||
|
|
|
@ -5,9 +5,10 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1145(AttackTechnique):
|
class T1145(AttackTechnique):
|
||||||
tech_id = "T1145"
|
tech_id = "T1145"
|
||||||
unscanned_msg = "Monkey didn't find any shh keys."
|
relevant_systems = ["Linux", "Windows"]
|
||||||
|
unscanned_msg = "Monkey didn't find any SSH keys."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey found ssh keys on machines in the network."
|
used_msg = "Monkey found SSH keys on machines in the network."
|
||||||
|
|
||||||
# Gets data about ssh keys found
|
# Gets data about ssh keys found
|
||||||
query = [
|
query = [
|
||||||
|
|
|
@ -4,11 +4,13 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1146(PostBreachTechnique):
|
class T1146(PostBreachTechnique):
|
||||||
tech_id = "T1146"
|
tech_id = "T1146"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Linux"]
|
||||||
"Monkey didn't try clearing the command history since it didn't run on any Linux machines."
|
unscanned_msg = "Monkey didn't try clearing the command history on a Linux system."
|
||||||
|
scanned_msg = "Monkey tried clearing the command history on a Linux system but failed."
|
||||||
|
used_msg = (
|
||||||
|
"Monkey successfully cleared the command history on a Linux system (and then "
|
||||||
|
"restored it back)."
|
||||||
)
|
)
|
||||||
scanned_msg = "Monkey tried clearing the command history but failed."
|
|
||||||
used_msg = "Monkey successfully cleared the command history (and then restored it back)."
|
|
||||||
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
|
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -4,7 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1154(PostBreachTechnique):
|
class T1154(PostBreachTechnique):
|
||||||
tech_id = "T1154"
|
tech_id = "T1154"
|
||||||
unscanned_msg = "Monkey didn't use the trap command since it didn't run on any Linux machines."
|
relevant_systems = ["Linux"]
|
||||||
|
unscanned_msg = "Monkey didn't use the trap command."
|
||||||
scanned_msg = "Monkey tried using the trap command but failed."
|
scanned_msg = "Monkey tried using the trap command but failed."
|
||||||
used_msg = "Monkey used the trap command successfully."
|
used_msg = "Monkey used the trap command successfully."
|
||||||
pba_names = [POST_BREACH_TRAP_COMMAND]
|
pba_names = [POST_BREACH_TRAP_COMMAND]
|
||||||
|
|
|
@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1156(PostBreachTechnique):
|
class T1156(PostBreachTechnique):
|
||||||
tech_id = "T1156"
|
tech_id = "T1156"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Linux"]
|
||||||
"Monkey didn't try modifying bash startup files since it didn't run on any Linux machines."
|
unscanned_msg = "Monkey didn't try modifying bash startup files."
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried modifying bash startup files but failed."
|
scanned_msg = "Monkey tried modifying bash startup files but failed."
|
||||||
used_msg = "Monkey successfully modified bash startup files."
|
used_msg = "Monkey successfully modified bash startup files."
|
||||||
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
|
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
|
||||||
|
|
|
@ -4,6 +4,7 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1158(PostBreachTechnique):
|
class T1158(PostBreachTechnique):
|
||||||
tech_id = "T1158"
|
tech_id = "T1158"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try creating hidden files or folders."
|
unscanned_msg = "Monkey didn't try creating hidden files or folders."
|
||||||
scanned_msg = "Monkey tried creating hidden files and folders on the system but failed."
|
scanned_msg = "Monkey tried creating hidden files and folders on the system but failed."
|
||||||
used_msg = "Monkey created hidden files and folders on the system."
|
used_msg = "Monkey created hidden files and folders on the system."
|
||||||
|
|
|
@ -4,10 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1166(PostBreachTechnique):
|
class T1166(PostBreachTechnique):
|
||||||
tech_id = "T1166"
|
tech_id = "T1166"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Linux"]
|
||||||
"Monkey didn't try setting the setuid or setgid bits since it didn't run on "
|
unscanned_msg = "Monkey didn't try setting the setuid or setgid bits."
|
||||||
"any Linux machines."
|
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried setting the setuid or setgid bits but failed."
|
scanned_msg = "Monkey tried setting the setuid or setgid bits but failed."
|
||||||
used_msg = "Monkey successfully set the setuid or setgid bits."
|
used_msg = "Monkey successfully set the setuid or setgid bits."
|
||||||
pba_names = [POST_BREACH_SETUID_SETGID]
|
pba_names = [POST_BREACH_SETUID_SETGID]
|
||||||
|
|
|
@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1168(PostBreachTechnique):
|
class T1168(PostBreachTechnique):
|
||||||
tech_id = "T1168"
|
tech_id = "T1168"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Linux"]
|
||||||
"Monkey didn't try scheduling a job on Linux since it didn't run on any Linux machines."
|
unscanned_msg = "Monkey didn't try scheduling a job on Linux."
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried scheduling a job on the Linux system but failed."
|
scanned_msg = "Monkey tried scheduling a job on the Linux system but failed."
|
||||||
used_msg = "Monkey scheduled a job on the Linux system."
|
used_msg = "Monkey scheduled a job on the Linux system."
|
||||||
pba_names = [POST_BREACH_JOB_SCHEDULING]
|
pba_names = [POST_BREACH_JOB_SCHEDULING]
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1188(AttackTechnique):
|
class T1188(AttackTechnique):
|
||||||
tech_id = "T1188"
|
tech_id = "T1188"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't use multi-hop proxy."
|
unscanned_msg = "Monkey didn't use multi-hop proxy."
|
||||||
scanned_msg = ""
|
scanned_msg = ""
|
||||||
used_msg = "Monkey used multi-hop proxy."
|
used_msg = "Monkey used multi-hop proxy."
|
||||||
|
|
|
@ -4,9 +4,8 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1197(AttackTechnique):
|
class T1197(AttackTechnique):
|
||||||
tech_id = "T1197"
|
tech_id = "T1197"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Windows"]
|
||||||
"Monkey didn't try to use any bits jobs since it didn't run on any Windows machines."
|
unscanned_msg = "Monkey didn't try to use any bits jobs."
|
||||||
)
|
|
||||||
scanned_msg = "Monkey tried to use bits jobs but failed."
|
scanned_msg = "Monkey tried to use bits jobs but failed."
|
||||||
used_msg = "Monkey successfully used bits jobs at least once in the network."
|
used_msg = "Monkey successfully used bits jobs at least once in the network."
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1210(AttackTechnique):
|
class T1210(AttackTechnique):
|
||||||
tech_id = "T1210"
|
tech_id = "T1210"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = (
|
unscanned_msg = (
|
||||||
"Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
|
"Monkey didn't scan any remote services. Maybe it didn't find any machines on the network?"
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,24 +4,17 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1216(PostBreachTechnique):
|
class T1216(PostBreachTechnique):
|
||||||
tech_id = "T1216"
|
tech_id = "T1216"
|
||||||
|
relevant_systems = ["Windows"]
|
||||||
unscanned_msg = (
|
unscanned_msg = (
|
||||||
"Monkey didn't attempt to execute an arbitrary program with the help of a "
|
"Monkey didn't attempt to execute an arbitrary program with the help of a "
|
||||||
+ "pre-existing signed script since it didn't run on any Windows machines. "
|
"pre-existing signed script. "
|
||||||
+ "If successful, this behavior could be abused by adversaries to execute malicious "
|
|
||||||
"files that could " + "bypass application control and signature validation on "
|
|
||||||
"systems."
|
|
||||||
)
|
)
|
||||||
scanned_msg = (
|
scanned_msg = (
|
||||||
"Monkey attempted to execute an arbitrary program with the help of a "
|
"Monkey attempted to execute an arbitrary program with the help of a "
|
||||||
+ "pre-existing signed script on Windows but failed. "
|
"pre-existing signed script on Windows but failed. "
|
||||||
+ "If successful, this behavior could be abused by adversaries to execute malicious "
|
|
||||||
"files that could " + "bypass application control and signature validation on "
|
|
||||||
"systems."
|
|
||||||
)
|
)
|
||||||
used_msg = (
|
used_msg = (
|
||||||
"Monkey executed an arbitrary program with the help of a pre-existing signed script "
|
"Monkey executed an arbitrary program with the help of a pre-existing signed script "
|
||||||
"on Windows. "
|
"on Windows. "
|
||||||
+ "This behavior could be abused by adversaries to execute malicious files that could "
|
|
||||||
+ "bypass application control and signature validation on systems."
|
|
||||||
)
|
)
|
||||||
pba_names = [POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC]
|
pba_names = [POST_BREACH_SIGNED_SCRIPT_PROXY_EXEC]
|
||||||
|
|
|
@ -5,6 +5,7 @@ from monkey_island.cc.services.attack.technique_reports import AttackTechnique
|
||||||
|
|
||||||
class T1222(AttackTechnique):
|
class T1222(AttackTechnique):
|
||||||
tech_id = "T1222"
|
tech_id = "T1222"
|
||||||
|
relevant_systems = ["Linux", "Windows"]
|
||||||
unscanned_msg = "Monkey didn't try to change any file permissions."
|
unscanned_msg = "Monkey didn't try to change any file permissions."
|
||||||
scanned_msg = "Monkey tried to change file permissions, but failed."
|
scanned_msg = "Monkey tried to change file permissions, but failed."
|
||||||
used_msg = "Monkey successfully changed file permissions in network systems."
|
used_msg = "Monkey successfully changed file permissions in network systems."
|
||||||
|
|
|
@ -4,12 +4,10 @@ from monkey_island.cc.services.attack.technique_reports.pba_technique import Pos
|
||||||
|
|
||||||
class T1504(PostBreachTechnique):
|
class T1504(PostBreachTechnique):
|
||||||
tech_id = "T1504"
|
tech_id = "T1504"
|
||||||
unscanned_msg = (
|
relevant_systems = ["Windows"]
|
||||||
"Monkey didn't try modifying powershell startup files since it didn't run on "
|
unscanned_msg = "Monkey didn't try modifying PowerShell startup files."
|
||||||
"any Windows machines."
|
scanned_msg = "Monkey tried modifying PowerShell startup files but failed."
|
||||||
)
|
used_msg = "Monkey successfully modified PowerShell startup files."
|
||||||
scanned_msg = "Monkey tried modifying powershell startup files but failed."
|
|
||||||
used_msg = "Monkey successfully modified powershell startup files."
|
|
||||||
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
|
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
import abc
|
import abc
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
from common.utils.attack_utils import ScanStatus
|
from common.utils.attack_utils import ScanStatus
|
||||||
from common.utils.code_utils import abstractstatic
|
from common.utils.code_utils import abstractstatic
|
||||||
from monkey_island.cc.database import mongo
|
from monkey_island.cc.database import mongo
|
||||||
from monkey_island.cc.models.attack.attack_mitigations import AttackMitigations
|
from monkey_island.cc.models.attack.attack_mitigations import AttackMitigations
|
||||||
from monkey_island.cc.services.attack.attack_config import AttackConfig
|
from monkey_island.cc.services.attack.attack_config import AttackConfig
|
||||||
|
from monkey_island.cc.services.config_schema.config_schema import SCHEMA
|
||||||
|
from monkey_island.cc.services.config_schema.config_schema_per_attack_technique import (
|
||||||
|
get_config_schema_per_attack_technique,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -18,13 +23,15 @@ disabled_msg = (
|
||||||
class AttackTechnique(object, metaclass=abc.ABCMeta):
|
class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
""" Abstract class for ATT&CK report components """
|
""" Abstract class for ATT&CK report components """
|
||||||
|
|
||||||
|
config_schema_per_attack_technique = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def unscanned_msg(self):
|
def unscanned_msg(self):
|
||||||
"""
|
"""
|
||||||
:return: Message that will be displayed in case attack technique was not scanned.
|
:return: Message that will be displayed in case attack technique was not scanned.
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -32,7 +39,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
:return: Message that will be displayed in case attack technique was scanned.
|
:return: Message that will be displayed in case attack technique was scanned.
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -40,7 +47,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
:return: Message that will be displayed in case attack technique was used by the scanner.
|
:return: Message that will be displayed in case attack technique was used by the scanner.
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
|
@ -48,7 +55,17 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
:return: Id of attack technique. E.g. T1003
|
:return: Id of attack technique. E.g. T1003
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
|
@property
|
||||||
|
@abc.abstractmethod
|
||||||
|
def relevant_systems(self) -> List[str]:
|
||||||
|
"""
|
||||||
|
:return: systems on which the technique is relevant
|
||||||
|
(examples: 1. "Trap Command" PBA (technique T1154) is Linux only.
|
||||||
|
2. "Job Scheduling" PBA has different techniques for Windows and Linux.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@abstractstatic
|
@abstractstatic
|
||||||
|
@ -56,7 +73,7 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
:return: Report data aggregated from the database.
|
:return: Report data aggregated from the database.
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def technique_status(cls):
|
def technique_status(cls):
|
||||||
|
@ -104,12 +121,52 @@ class AttackTechnique(object, metaclass=abc.ABCMeta):
|
||||||
if status == ScanStatus.DISABLED.value:
|
if status == ScanStatus.DISABLED.value:
|
||||||
return disabled_msg
|
return disabled_msg
|
||||||
if status == ScanStatus.UNSCANNED.value:
|
if status == ScanStatus.UNSCANNED.value:
|
||||||
return cls.unscanned_msg
|
if not cls.config_schema_per_attack_technique:
|
||||||
|
cls.config_schema_per_attack_technique = get_config_schema_per_attack_technique(
|
||||||
|
SCHEMA
|
||||||
|
)
|
||||||
|
unscanned_msg = cls._get_unscanned_msg_with_reasons(
|
||||||
|
cls.unscanned_msg, cls.config_schema_per_attack_technique
|
||||||
|
)
|
||||||
|
return unscanned_msg
|
||||||
elif status == ScanStatus.SCANNED.value:
|
elif status == ScanStatus.SCANNED.value:
|
||||||
return cls.scanned_msg
|
return cls.scanned_msg
|
||||||
else:
|
else:
|
||||||
return cls.used_msg
|
return cls.used_msg
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_unscanned_msg_with_reasons(
|
||||||
|
cls, unscanned_msg: str, config_schema_per_attack_technique: Dict
|
||||||
|
):
|
||||||
|
reasons = []
|
||||||
|
if len(cls.relevant_systems) == 1:
|
||||||
|
reasons.append(f"- Monkey did not run on any {cls.relevant_systems[0]} systems.")
|
||||||
|
if cls.tech_id in config_schema_per_attack_technique:
|
||||||
|
reasons.append(
|
||||||
|
"- The following configuration options were disabled:<br/>"
|
||||||
|
f"{cls._get_relevant_config_values(config_schema_per_attack_technique)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if reasons:
|
||||||
|
unscanned_msg = (
|
||||||
|
unscanned_msg.strip(".")
|
||||||
|
+ " due to one of the following reasons:\n"
|
||||||
|
+ "\n".join(reasons)
|
||||||
|
)
|
||||||
|
|
||||||
|
return unscanned_msg
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_relevant_config_values(cls, config_schema_per_attack_technique: Dict):
|
||||||
|
config_options = ""
|
||||||
|
for config_type in config_schema_per_attack_technique[cls.tech_id]:
|
||||||
|
config_options += (
|
||||||
|
f"- {config_type} — "
|
||||||
|
f"{', '.join(config_schema_per_attack_technique[cls.tech_id][config_type])}<br/>"
|
||||||
|
)
|
||||||
|
|
||||||
|
return config_options
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def technique_title(cls):
|
def technique_title(cls):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -15,7 +15,7 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
:return: names of post breach action
|
:return: names of post breach action
|
||||||
"""
|
"""
|
||||||
pass
|
...
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_pba_query(cls, post_breach_action_names):
|
def get_pba_query(cls, post_breach_action_names):
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_schema_per_attack_technique(schema: Dict) -> Dict[str, Dict[str, List[str]]]:
|
||||||
|
"""
|
||||||
|
:return: dictionary mapping each attack technique to relevant config fields; example -
|
||||||
|
{
|
||||||
|
"T1003": {
|
||||||
|
"System Info Collectors": [
|
||||||
|
"Mimikatz collector",
|
||||||
|
"Azure credential collector"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
reverse_schema = {}
|
||||||
|
|
||||||
|
definitions = schema["definitions"]
|
||||||
|
for definition in definitions:
|
||||||
|
definition_type = definitions[definition]["title"]
|
||||||
|
for field in definitions[definition]["anyOf"]:
|
||||||
|
config_field = field["title"]
|
||||||
|
for attack_technique in field.get("attack_techniques", []):
|
||||||
|
_add_config_field_to_reverse_schema(
|
||||||
|
definition_type, config_field, attack_technique, reverse_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
return reverse_schema
|
||||||
|
|
||||||
|
|
||||||
|
def _add_config_field_to_reverse_schema(
|
||||||
|
definition_type: str, config_field: str, attack_technique: str, reverse_schema: Dict
|
||||||
|
) -> None:
|
||||||
|
reverse_schema.setdefault(attack_technique, {})
|
||||||
|
reverse_schema[attack_technique].setdefault(definition_type, [])
|
||||||
|
reverse_schema[attack_technique][definition_type].append(config_field)
|
|
@ -1,7 +1,7 @@
|
||||||
from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN
|
from monkey_island.cc.services.utils.typographic_symbols import WARNING_SIGN
|
||||||
|
|
||||||
EXPLOITER_CLASSES = {
|
EXPLOITER_CLASSES = {
|
||||||
"title": "Exploit class",
|
"title": "Exploiters",
|
||||||
"description": "Click on exploiter to get more information about it."
|
"description": "Click on exploiter to get more information about it."
|
||||||
+ WARNING_SIGN
|
+ WARNING_SIGN
|
||||||
+ " Note that using unsafe exploits may cause crashes of the exploited "
|
+ " Note that using unsafe exploits may cause crashes of the exploited "
|
||||||
|
@ -163,7 +163,7 @@ EXPLOITER_CLASSES = {
|
||||||
"computers.",
|
"computers.",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"link": "https://www.guardicore.com/infectionmonkey"
|
"link": "https://www.guardicore.com/infectionmonkey"
|
||||||
"/docs/reference/exploiters/", # TODO: Change link once documentation is updated
|
"/docs/reference/exploiters/powershell",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FINGER_CLASSES = {
|
FINGER_CLASSES = {
|
||||||
"title": "Fingerprint class",
|
"title": "Fingerprinters",
|
||||||
"description": "Fingerprint modules collect info about external services "
|
"description": "Fingerprint modules collect info about external services "
|
||||||
"Infection Monkey scans.",
|
"Infection Monkey scans.",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -7,7 +7,7 @@ FINGER_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["SMBFinger"],
|
"enum": ["SMBFinger"],
|
||||||
"title": "SMBFinger",
|
"title": "SMB Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Figures out if SMB is running and what's the version of it.",
|
"info": "Figures out if SMB is running and what's the version of it.",
|
||||||
"attack_techniques": ["T1210"],
|
"attack_techniques": ["T1210"],
|
||||||
|
@ -15,7 +15,7 @@ FINGER_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["SSHFinger"],
|
"enum": ["SSHFinger"],
|
||||||
"title": "SSHFinger",
|
"title": "SSH Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Figures out if SSH is running.",
|
"info": "Figures out if SSH is running.",
|
||||||
"attack_techniques": ["T1210"],
|
"attack_techniques": ["T1210"],
|
||||||
|
@ -23,21 +23,21 @@ FINGER_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["PingScanner"],
|
"enum": ["PingScanner"],
|
||||||
"title": "PingScanner",
|
"title": "Ping Scanner",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Tries to identify if host is alive and which OS it's running by ping scan.",
|
"info": "Tries to identify if host is alive and which OS it's running by ping scan.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["HTTPFinger"],
|
"enum": ["HTTPFinger"],
|
||||||
"title": "HTTPFinger",
|
"title": "HTTP Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Checks if host has HTTP/HTTPS ports open.",
|
"info": "Checks if host has HTTP/HTTPS ports open.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["MySQLFinger"],
|
"enum": ["MySQLFinger"],
|
||||||
"title": "MySQLFinger",
|
"title": "MySQL Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Checks if MySQL server is running and tries to get it's version.",
|
"info": "Checks if MySQL server is running and tries to get it's version.",
|
||||||
"attack_techniques": ["T1210"],
|
"attack_techniques": ["T1210"],
|
||||||
|
@ -45,7 +45,7 @@ FINGER_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["MSSQLFinger"],
|
"enum": ["MSSQLFinger"],
|
||||||
"title": "MSSQLFinger",
|
"title": "MSSQL Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Checks if Microsoft SQL service is running and tries to gather "
|
"info": "Checks if Microsoft SQL service is running and tries to gather "
|
||||||
"information about it.",
|
"information about it.",
|
||||||
|
@ -54,7 +54,7 @@ FINGER_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["ElasticFinger"],
|
"enum": ["ElasticFinger"],
|
||||||
"title": "ElasticFinger",
|
"title": "Elastic Fingerprinter",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Checks if ElasticSearch is running and attempts to find it's " "version.",
|
"info": "Checks if ElasticSearch is running and attempts to find it's " "version.",
|
||||||
"attack_techniques": ["T1210"],
|
"attack_techniques": ["T1210"],
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
POST_BREACH_ACTIONS = {
|
POST_BREACH_ACTIONS = {
|
||||||
"title": "Post breach actions",
|
"title": "Post-Breach Actions",
|
||||||
"description": "Runs scripts/commands on infected machines. These actions safely simulate what "
|
"description": "Runs scripts/commands on infected machines. These actions safely simulate what "
|
||||||
"an adversary"
|
"an adversary might do after breaching a new machine. Used in ATT&CK and Zero trust reports.",
|
||||||
"might do after breaching a new machine. Used in ATT&CK and Zero trust reports.",
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["CommunicateAsBackdoorUser"],
|
"enum": ["CommunicateAsBackdoorUser"],
|
||||||
"title": "Communicate as backdoor user",
|
"title": "Communicate as Backdoor User",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Attempts to create a new user, create HTTPS requests as that "
|
"info": "Attempts to create a new user, create HTTPS requests as that "
|
||||||
"user and delete the user "
|
"user and delete the user "
|
||||||
|
@ -18,7 +17,7 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["ModifyShellStartupFiles"],
|
"enum": ["ModifyShellStartupFiles"],
|
||||||
"title": "Modify shell startup files",
|
"title": "Modify Shell Startup Files",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Attempts to modify shell startup files, like ~/.profile, "
|
"info": "Attempts to modify shell startup files, like ~/.profile, "
|
||||||
"~/.bashrc, ~/.bash_profile "
|
"~/.bashrc, ~/.bash_profile "
|
||||||
|
@ -29,7 +28,7 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["HiddenFiles"],
|
"enum": ["HiddenFiles"],
|
||||||
"title": "Hidden files and directories",
|
"title": "Hidden Files and Directories",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Attempts to create a hidden file and remove it afterward.",
|
"info": "Attempts to create a hidden file and remove it afterward.",
|
||||||
"attack_techniques": ["T1158"],
|
"attack_techniques": ["T1158"],
|
||||||
|
@ -37,11 +36,10 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["TrapCommand"],
|
"enum": ["TrapCommand"],
|
||||||
"title": "Trap",
|
"title": "Trap Command",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "On Linux systems, attempts to trap a terminate signal in order "
|
"info": "On Linux systems, attempts to trap a terminate signal in order "
|
||||||
"to execute a command "
|
"to execute a command upon receiving that signal. Removes the trap afterwards.",
|
||||||
"upon receiving that signal. Removes the trap afterwards.",
|
|
||||||
"attack_techniques": ["T1154"],
|
"attack_techniques": ["T1154"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -57,7 +55,7 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["ScheduleJobs"],
|
"enum": ["ScheduleJobs"],
|
||||||
"title": "Job scheduling",
|
"title": "Job Scheduling",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Attempts to create a scheduled job on the system and remove it.",
|
"info": "Attempts to create a scheduled job on the system and remove it.",
|
||||||
"attack_techniques": ["T1168", "T1053"],
|
"attack_techniques": ["T1168", "T1053"],
|
||||||
|
@ -74,7 +72,7 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["SignedScriptProxyExecution"],
|
"enum": ["SignedScriptProxyExecution"],
|
||||||
"title": "Signed script proxy execution",
|
"title": "Signed Script Proxy Execution",
|
||||||
"safe": False,
|
"safe": False,
|
||||||
"info": "On Windows systems, attempts to execute an arbitrary file "
|
"info": "On Windows systems, attempts to execute an arbitrary file "
|
||||||
"with the help of a pre-existing signed script.",
|
"with the help of a pre-existing signed script.",
|
||||||
|
@ -91,7 +89,7 @@ POST_BREACH_ACTIONS = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["ClearCommandHistory"],
|
"enum": ["ClearCommandHistory"],
|
||||||
"title": "Clear command history",
|
"title": "Clear Command History",
|
||||||
"safe": False,
|
"safe": False,
|
||||||
"info": "Attempts to clear the command history.",
|
"info": "Attempts to clear the command history.",
|
||||||
"attack_techniques": ["T1146"],
|
"attack_techniques": ["T1146"],
|
||||||
|
|
|
@ -15,7 +15,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [ENVIRONMENT_COLLECTOR],
|
"enum": [ENVIRONMENT_COLLECTOR],
|
||||||
"title": "Environment collector",
|
"title": "Environment Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Collects information about machine's environment (on " "premise/GCP/AWS).",
|
"info": "Collects information about machine's environment (on " "premise/GCP/AWS).",
|
||||||
"attack_techniques": ["T1082"],
|
"attack_techniques": ["T1082"],
|
||||||
|
@ -23,7 +23,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [MIMIKATZ_COLLECTOR],
|
"enum": [MIMIKATZ_COLLECTOR],
|
||||||
"title": "Mimikatz collector",
|
"title": "Mimikatz Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Collects credentials from Windows credential manager.",
|
"info": "Collects credentials from Windows credential manager.",
|
||||||
"attack_techniques": ["T1003", "T1005"],
|
"attack_techniques": ["T1003", "T1005"],
|
||||||
|
@ -31,7 +31,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [AWS_COLLECTOR],
|
"enum": [AWS_COLLECTOR],
|
||||||
"title": "AWS collector",
|
"title": "AWS Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "If on AWS, collects more information about the AWS instance "
|
"info": "If on AWS, collects more information about the AWS instance "
|
||||||
"currently running on.",
|
"currently running on.",
|
||||||
|
@ -40,7 +40,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [HOSTNAME_COLLECTOR],
|
"enum": [HOSTNAME_COLLECTOR],
|
||||||
"title": "Hostname collector",
|
"title": "Hostname Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Collects machine's hostname.",
|
"info": "Collects machine's hostname.",
|
||||||
"attack_techniques": ["T1082", "T1016"],
|
"attack_techniques": ["T1082", "T1016"],
|
||||||
|
@ -48,7 +48,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [PROCESS_LIST_COLLECTOR],
|
"enum": [PROCESS_LIST_COLLECTOR],
|
||||||
"title": "Process list collector",
|
"title": "Process List Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Collects a list of running processes on the machine.",
|
"info": "Collects a list of running processes on the machine.",
|
||||||
"attack_techniques": ["T1082"],
|
"attack_techniques": ["T1082"],
|
||||||
|
@ -56,7 +56,7 @@ SYSTEM_INFO_COLLECTOR_CLASSES = {
|
||||||
{
|
{
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [AZURE_CRED_COLLECTOR],
|
"enum": [AZURE_CRED_COLLECTOR],
|
||||||
"title": "Azure credential collector",
|
"title": "Azure Credential Collector",
|
||||||
"safe": True,
|
"safe": True,
|
||||||
"info": "Collects password credentials from Azure VMs",
|
"info": "Collects password credentials from Azure VMs",
|
||||||
"attack_techniques": ["T1003", "T1005"],
|
"attack_techniques": ["T1003", "T1005"],
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from common.utils.attack_utils import ScanStatus
|
||||||
|
from monkey_island.cc.services.attack.technique_reports.__init__ import (
|
||||||
|
AttackTechnique,
|
||||||
|
disabled_msg,
|
||||||
|
)
|
||||||
|
|
||||||
|
FAKE_CONFIG_SCHEMA_PER_ATTACK_TECHNIQUE = {
|
||||||
|
"T0000": {
|
||||||
|
"Definition Type 1": ["Config Option 1", "Config Option 2"],
|
||||||
|
"Definition Type 2": ["Config Option 5", "Config Option 6"],
|
||||||
|
},
|
||||||
|
"T0001": {
|
||||||
|
"Definition Type 1": ["Config Option 1"],
|
||||||
|
"Definition Type 2": ["Config Option 5"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function", autouse=True)
|
||||||
|
def mock_config_schema_per_attack_technique(monkeypatch, fake_schema):
|
||||||
|
monkeypatch.setattr(
|
||||||
|
("monkey_island.cc.services.attack.technique_reports." "__init__.SCHEMA"),
|
||||||
|
fake_schema,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class FakeAttackTechnique_TwoRelevantSystems(AttackTechnique):
|
||||||
|
tech_id = "T0001"
|
||||||
|
relevant_systems = ["System 1", "System 2"]
|
||||||
|
unscanned_msg = "UNSCANNED"
|
||||||
|
scanned_msg = "SCANNED"
|
||||||
|
used_msg = "USED"
|
||||||
|
|
||||||
|
def get_report_data():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ExpectedMsgs_TwoRelevantSystems(Enum):
|
||||||
|
UNSCANNED: str = (
|
||||||
|
"UNSCANNED due to one of the following reasons:\n"
|
||||||
|
"- The following configuration options were disabled:<br/>"
|
||||||
|
"- Definition Type 1 — Config Option 1<br/>"
|
||||||
|
"- Definition Type 2 — Config Option 5<br/>"
|
||||||
|
)
|
||||||
|
SCANNED: str = "SCANNED"
|
||||||
|
USED: str = "USED"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeAttackTechnique_OneRelevantSystem(AttackTechnique):
|
||||||
|
tech_id = "T0001"
|
||||||
|
relevant_systems = ["System 1"]
|
||||||
|
unscanned_msg = "UNSCANNED"
|
||||||
|
scanned_msg = "SCANNED"
|
||||||
|
used_msg = "USED"
|
||||||
|
|
||||||
|
def get_report_data():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ExpectedMsgs_OneRelevantSystem(Enum):
|
||||||
|
UNSCANNED: str = (
|
||||||
|
"UNSCANNED due to one of the following reasons:\n"
|
||||||
|
"- Monkey did not run on any System 1 systems.\n"
|
||||||
|
"- The following configuration options were disabled:<br/>"
|
||||||
|
"- Definition Type 1 — Config Option 1<br/>"
|
||||||
|
"- Definition Type 2 — Config Option 5<br/>"
|
||||||
|
)
|
||||||
|
SCANNED: str = "SCANNED"
|
||||||
|
USED: str = "USED"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_disabled_two_relevant_systems():
|
||||||
|
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
|
||||||
|
ScanStatus.DISABLED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == disabled_msg
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_unscanned_two_relevant_systems():
|
||||||
|
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
|
||||||
|
ScanStatus.UNSCANNED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.UNSCANNED.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_scanned_two_relevant_systems():
|
||||||
|
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
|
||||||
|
ScanStatus.SCANNED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.SCANNED.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_used_two_relevant_systems():
|
||||||
|
technique_msg = FakeAttackTechnique_TwoRelevantSystems.get_message_by_status(
|
||||||
|
ScanStatus.USED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_TwoRelevantSystems.USED.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_disabled_one_relevant_system():
|
||||||
|
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
|
||||||
|
ScanStatus.DISABLED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == disabled_msg
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_unscanned_one_relevant_system():
|
||||||
|
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
|
||||||
|
ScanStatus.UNSCANNED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_OneRelevantSystem.UNSCANNED.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_scanned_one_relevant_system():
|
||||||
|
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
|
||||||
|
ScanStatus.SCANNED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_OneRelevantSystem.SCANNED.value
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_message_by_status_used_one_relevant_system():
|
||||||
|
technique_msg = FakeAttackTechnique_OneRelevantSystem.get_message_by_status(
|
||||||
|
ScanStatus.USED.value
|
||||||
|
)
|
||||||
|
assert technique_msg == ExpectedMsgs_OneRelevantSystem.USED.value
|
|
@ -0,0 +1,18 @@
|
||||||
|
from monkey_island.cc.services.config_schema.config_schema_per_attack_technique import (
|
||||||
|
get_config_schema_per_attack_technique,
|
||||||
|
)
|
||||||
|
|
||||||
|
REVERSE_FAKE_SCHEMA = {
|
||||||
|
"T0000": {
|
||||||
|
"Definition Type 1": ["Config Option 1", "Config Option 2"],
|
||||||
|
"Definition Type 2": ["Config Option 5", "Config Option 6"],
|
||||||
|
},
|
||||||
|
"T0001": {
|
||||||
|
"Definition Type 1": ["Config Option 1"],
|
||||||
|
"Definition Type 2": ["Config Option 5"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_config_schema_per_attack_technique(monkeypatch, fake_schema):
|
||||||
|
assert get_config_schema_per_attack_technique(fake_schema) == REVERSE_FAKE_SCHEMA
|
|
@ -20,3 +20,51 @@ def config(monkeypatch, IPS, PORT):
|
||||||
monkeypatch.setattr(Environment, "_ISLAND_PORT", PORT)
|
monkeypatch.setattr(Environment, "_ISLAND_PORT", PORT)
|
||||||
config = ConfigService.get_default_config(True)
|
config = ConfigService.get_default_config(True)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fake_schema():
|
||||||
|
return {
|
||||||
|
"definitions": {
|
||||||
|
"definition_type_1": {
|
||||||
|
"title": "Definition Type 1",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"title": "Config Option 1",
|
||||||
|
"attack_techniques": ["T0000", "T0001"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 2",
|
||||||
|
"attack_techniques": ["T0000"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 3",
|
||||||
|
"attack_techniques": [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 4",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"definition_type_2": {
|
||||||
|
"title": "Definition Type 2",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"title": "Config Option 5",
|
||||||
|
"attack_techniques": ["T0000", "T0001"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 6",
|
||||||
|
"attack_techniques": ["T0000"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 7",
|
||||||
|
"attack_techniques": [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Config Option 8",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue