Merge pull request #1514 from guardicore/pba-attack-telemetry

Fix ATT&CK report bug: showed a different technique's results under a technique if the PBA behind them was the same
This commit is contained in:
Mike Salvatore 2021-10-06 12:12:28 -04:00 committed by GitHub
commit c3ea714977
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 31 additions and 78 deletions

View File

@ -48,6 +48,10 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
the config successfully now.) #1490
- Mimikatz collector no longer fails if Azure credential collector is disabled. #1512 #1493
- Unhandled error when "modify shell startup files PBA" is unable to find regular users. #1507
- ATT&CK report bug that showed different techniques' results under a technique if the PBA behind
them was the same. #1514
- ATT&CK report bug that said that the technique "`.bash_profile` and `.bashrc`" was not attempted
when it actually was attempted but failed. #1511
### Security

View File

@ -2,6 +2,7 @@ import socket
from common.common_consts.telem_categories import TelemCategoryEnum
from infection_monkey.telemetry.base_telem import BaseTelem
from infection_monkey.utils.environment import is_windows_os
class PostBreachTelem(BaseTelem):
@ -25,6 +26,7 @@ class PostBreachTelem(BaseTelem):
"name": self.pba.name,
"hostname": self.hostname,
"ip": self.ip,
"os": PostBreachTelem._get_os(),
}
@staticmethod
@ -36,3 +38,7 @@ class PostBreachTelem(BaseTelem):
hostname = "Unknown"
ip = "Unknown"
return hostname, ip
@staticmethod
def _get_os():
return "Windows" if is_windows_os() else "Linux"

View File

@ -12,24 +12,3 @@ class T1146(PostBreachTechnique):
"restored it back)."
)
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
@staticmethod
def get_pba_query(*args):
return [
{
"$match": {
"telem_category": "post_breach",
"data.name": POST_BREACH_CLEAR_CMD_HISTORY,
}
},
{
"$project": {
"_id": 0,
"machine": {
"hostname": {"$arrayElemAt": ["$data.hostname", 0]},
"ips": [{"$arrayElemAt": ["$data.ip", 0]}],
},
"result": "$data.result",
}
},
]

View File

@ -9,30 +9,3 @@ class T1156(PostBreachTechnique):
scanned_msg = "Monkey tried modifying bash startup files but failed."
used_msg = "Monkey successfully modified bash startup files."
pba_names = [POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION]
@staticmethod
def get_pba_query(*args):
return [
{
"$match": {
"telem_category": "post_breach",
"data.name": POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION,
}
},
{
"$project": {
"_id": 0,
"machine": {
"hostname": {"$arrayElemAt": ["$data.hostname", 0]},
"ips": [{"$arrayElemAt": ["$data.ip", 0]}],
},
"result": "$data.result",
}
},
{"$unwind": "$result"},
{
"$match": {
"$or": [{"result": {"$regex": r"\.bash"}}, {"result": {"$regex": r"\.profile"}}]
}
},
]

View File

@ -9,26 +9,3 @@ class T1504(PostBreachTechnique):
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]
@staticmethod
def get_pba_query(*args):
return [
{
"$match": {
"telem_category": "post_breach",
"data.name": POST_BREACH_SHELL_STARTUP_FILE_MODIFICATION,
}
},
{
"$project": {
"_id": 0,
"machine": {
"hostname": {"$arrayElemAt": ["$data.hostname", 0]},
"ips": [{"$arrayElemAt": ["$data.ip", 0]}],
},
"result": "$data.result",
}
},
{"$unwind": "$result"},
{"$match": {"result": {"$regex": r"profile\.ps1"}}},
]

View File

@ -18,7 +18,7 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
...
@classmethod
def get_pba_query(cls, post_breach_action_names):
def get_pba_query(cls, post_breach_action_names, relevant_systems):
"""
:param post_breach_action_names: Names of post-breach actions with which the technique is
associated
@ -29,14 +29,20 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
return [
{
"$match": {
"telem_category": "post_breach",
"$or": [{"data.name": pba_name} for pba_name in post_breach_action_names],
"$and": [
{"telem_category": "post_breach"},
{"$or": [{"data.name": pba_name} for pba_name in post_breach_action_names]},
{"$or": [{"data.os": os} for os in relevant_systems]},
]
}
},
{
"$project": {
"_id": 0,
"machine": {"hostname": "$data.hostname", "ips": ["$data.ip"]},
"machine": {
"hostname": {"$arrayElemAt": ["$data.hostname", 0]},
"ips": [{"$arrayElemAt": ["$data.ip", 0]}],
},
"result": "$data.result",
}
},
@ -50,13 +56,18 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
@cls.is_status_disabled
def get_technique_status_and_data():
info = list(mongo.db.telemetry.aggregate(cls.get_pba_query(cls.pba_names)))
info = list(
mongo.db.telemetry.aggregate(cls.get_pba_query(cls.pba_names, cls.relevant_systems))
)
status = ScanStatus.UNSCANNED.value
if info:
successful_PBAs = mongo.db.telemetry.count(
{
"$or": [{"data.name": pba_name} for pba_name in cls.pba_names],
"data.result.1": True,
"$and": [
{"$or": [{"data.name": pba_name} for pba_name in cls.pba_names]},
{"$or": [{"data.os": os} for os in cls.relevant_systems]},
{"data.result.1": True},
]
}
)
status = ScanStatus.USED.value if successful_PBAs else ScanStatus.SCANNED.value

View File

@ -6,6 +6,7 @@ from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
HOSTNAME = "hostname"
IP = "0.0.0.0"
OS = "operating system"
PBA_COMMAND = "run some pba"
PBA_NAME = "some pba"
RESULT = False
@ -21,6 +22,7 @@ class StubSomePBA:
def post_breach_telem_test_instance(monkeypatch):
PBA = StubSomePBA()
monkeypatch.setattr(PostBreachTelem, "_get_hostname_and_ip", lambda: (HOSTNAME, IP))
monkeypatch.setattr(PostBreachTelem, "_get_os", lambda: OS)
return PostBreachTelem(PBA, RESULT)
@ -32,6 +34,7 @@ def test_post_breach_telem_send(post_breach_telem_test_instance, spy_send_teleme
"name": PBA_NAME,
"hostname": HOSTNAME,
"ip": IP,
"os": OS,
}
expected_data = json.dumps(expected_data, cls=post_breach_telem_test_instance.json_encoder)
assert spy_send_telemetry.data == expected_data