forked from p15670423/monkey
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:
commit
c3ea714977
|
@ -48,6 +48,10 @@ Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
the config successfully now.) #1490
|
the config successfully now.) #1490
|
||||||
- Mimikatz collector no longer fails if Azure credential collector is disabled. #1512 #1493
|
- 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
|
- 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
|
### Security
|
||||||
|
|
|
@ -2,6 +2,7 @@ import socket
|
||||||
|
|
||||||
from common.common_consts.telem_categories import TelemCategoryEnum
|
from common.common_consts.telem_categories import TelemCategoryEnum
|
||||||
from infection_monkey.telemetry.base_telem import BaseTelem
|
from infection_monkey.telemetry.base_telem import BaseTelem
|
||||||
|
from infection_monkey.utils.environment import is_windows_os
|
||||||
|
|
||||||
|
|
||||||
class PostBreachTelem(BaseTelem):
|
class PostBreachTelem(BaseTelem):
|
||||||
|
@ -25,6 +26,7 @@ class PostBreachTelem(BaseTelem):
|
||||||
"name": self.pba.name,
|
"name": self.pba.name,
|
||||||
"hostname": self.hostname,
|
"hostname": self.hostname,
|
||||||
"ip": self.ip,
|
"ip": self.ip,
|
||||||
|
"os": PostBreachTelem._get_os(),
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -36,3 +38,7 @@ class PostBreachTelem(BaseTelem):
|
||||||
hostname = "Unknown"
|
hostname = "Unknown"
|
||||||
ip = "Unknown"
|
ip = "Unknown"
|
||||||
return hostname, ip
|
return hostname, ip
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_os():
|
||||||
|
return "Windows" if is_windows_os() else "Linux"
|
||||||
|
|
|
@ -12,24 +12,3 @@ class T1146(PostBreachTechnique):
|
||||||
"restored it back)."
|
"restored it back)."
|
||||||
)
|
)
|
||||||
pba_names = [POST_BREACH_CLEAR_CMD_HISTORY]
|
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",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
|
@ -9,30 +9,3 @@ class T1156(PostBreachTechnique):
|
||||||
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]
|
||||||
|
|
||||||
@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"}}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
|
@ -9,26 +9,3 @@ class T1504(PostBreachTechnique):
|
||||||
scanned_msg = "Monkey tried modifying PowerShell startup files but failed."
|
scanned_msg = "Monkey tried modifying PowerShell startup files but failed."
|
||||||
used_msg = "Monkey successfully modified PowerShell startup files."
|
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
|
|
||||||
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"}}},
|
|
||||||
]
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
|
||||||
...
|
...
|
||||||
|
|
||||||
@classmethod
|
@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
|
:param post_breach_action_names: Names of post-breach actions with which the technique is
|
||||||
associated
|
associated
|
||||||
|
@ -29,14 +29,20 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
"$match": {
|
"$match": {
|
||||||
"telem_category": "post_breach",
|
"$and": [
|
||||||
"$or": [{"data.name": pba_name} for pba_name in post_breach_action_names],
|
{"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": {
|
"$project": {
|
||||||
"_id": 0,
|
"_id": 0,
|
||||||
"machine": {"hostname": "$data.hostname", "ips": ["$data.ip"]},
|
"machine": {
|
||||||
|
"hostname": {"$arrayElemAt": ["$data.hostname", 0]},
|
||||||
|
"ips": [{"$arrayElemAt": ["$data.ip", 0]}],
|
||||||
|
},
|
||||||
"result": "$data.result",
|
"result": "$data.result",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -50,13 +56,18 @@ class PostBreachTechnique(AttackTechnique, metaclass=abc.ABCMeta):
|
||||||
|
|
||||||
@cls.is_status_disabled
|
@cls.is_status_disabled
|
||||||
def get_technique_status_and_data():
|
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
|
status = ScanStatus.UNSCANNED.value
|
||||||
if info:
|
if info:
|
||||||
successful_PBAs = mongo.db.telemetry.count(
|
successful_PBAs = mongo.db.telemetry.count(
|
||||||
{
|
{
|
||||||
"$or": [{"data.name": pba_name} for pba_name in cls.pba_names],
|
"$and": [
|
||||||
"data.result.1": True,
|
{"$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
|
status = ScanStatus.USED.value if successful_PBAs else ScanStatus.SCANNED.value
|
||||||
|
|
|
@ -6,6 +6,7 @@ from infection_monkey.telemetry.post_breach_telem import PostBreachTelem
|
||||||
|
|
||||||
HOSTNAME = "hostname"
|
HOSTNAME = "hostname"
|
||||||
IP = "0.0.0.0"
|
IP = "0.0.0.0"
|
||||||
|
OS = "operating system"
|
||||||
PBA_COMMAND = "run some pba"
|
PBA_COMMAND = "run some pba"
|
||||||
PBA_NAME = "some pba"
|
PBA_NAME = "some pba"
|
||||||
RESULT = False
|
RESULT = False
|
||||||
|
@ -21,6 +22,7 @@ class StubSomePBA:
|
||||||
def post_breach_telem_test_instance(monkeypatch):
|
def post_breach_telem_test_instance(monkeypatch):
|
||||||
PBA = StubSomePBA()
|
PBA = StubSomePBA()
|
||||||
monkeypatch.setattr(PostBreachTelem, "_get_hostname_and_ip", lambda: (HOSTNAME, IP))
|
monkeypatch.setattr(PostBreachTelem, "_get_hostname_and_ip", lambda: (HOSTNAME, IP))
|
||||||
|
monkeypatch.setattr(PostBreachTelem, "_get_os", lambda: OS)
|
||||||
return PostBreachTelem(PBA, RESULT)
|
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,
|
"name": PBA_NAME,
|
||||||
"hostname": HOSTNAME,
|
"hostname": HOSTNAME,
|
||||||
"ip": IP,
|
"ip": IP,
|
||||||
|
"os": OS,
|
||||||
}
|
}
|
||||||
expected_data = json.dumps(expected_data, cls=post_breach_telem_test_instance.json_encoder)
|
expected_data = json.dumps(expected_data, cls=post_breach_telem_test_instance.json_encoder)
|
||||||
assert spy_send_telemetry.data == expected_data
|
assert spy_send_telemetry.data == expected_data
|
||||||
|
|
Loading…
Reference in New Issue