forked from p15670423/monkey
Island, UT: remove credential processing from exploit telemetry
Credentials should be sent via credential telemetry, not exploit telemetry. This will remove the need to maintain duplicate code of credential extraction
This commit is contained in:
parent
4f58a69c54
commit
52c0413797
|
@ -276,6 +276,8 @@ class ZerologonExploiter(HostExploiter):
|
|||
)
|
||||
|
||||
def add_extracted_creds_to_exploit_info(self, user: str, lmhash: str, nthash: str) -> None:
|
||||
# TODO exploit_info["credentials"] is discontinued,
|
||||
# refactor to send a credential telemetry
|
||||
self.exploit_info["credentials"].update(
|
||||
{
|
||||
user: {
|
||||
|
|
|
@ -4,7 +4,6 @@ import dateutil
|
|||
|
||||
from monkey_island.cc.models import Monkey
|
||||
from monkey_island.cc.server_utils.encryption import get_datastore_encryptor
|
||||
from monkey_island.cc.services.config import ConfigService
|
||||
from monkey_island.cc.services.edge.displayed_edge import EdgeService
|
||||
from monkey_island.cc.services.node import NodeService
|
||||
from monkey_island.cc.services.telemetry.processing.utils import (
|
||||
|
@ -20,7 +19,6 @@ def process_exploit_telemetry(telemetry_json):
|
|||
edge = get_edge_by_scan_or_exploit_telemetry(telemetry_json)
|
||||
update_network_with_exploit(edge, telemetry_json)
|
||||
update_node_credentials_from_successful_attempts(edge, telemetry_json)
|
||||
add_exploit_extracted_creds_to_config(telemetry_json)
|
||||
|
||||
check_machine_exploited(
|
||||
current_monkey=Monkey.get_single_monkey_by_guid(telemetry_json["monkey_guid"]),
|
||||
|
@ -31,19 +29,6 @@ def process_exploit_telemetry(telemetry_json):
|
|||
)
|
||||
|
||||
|
||||
def add_exploit_extracted_creds_to_config(telemetry_json):
|
||||
if "credentials" in telemetry_json["data"]["info"]:
|
||||
creds = telemetry_json["data"]["info"]["credentials"]
|
||||
for user in creds:
|
||||
ConfigService.creds_add_username(creds[user]["username"])
|
||||
if "password" in creds[user] and creds[user]["password"]:
|
||||
ConfigService.creds_add_password(creds[user]["password"])
|
||||
if "lm_hash" in creds[user] and creds[user]["lm_hash"]:
|
||||
ConfigService.creds_add_lm_hash(creds[user]["lm_hash"])
|
||||
if "ntlm_hash" in creds[user] and creds[user]["ntlm_hash"]:
|
||||
ConfigService.creds_add_ntlm_hash(creds[user]["ntlm_hash"])
|
||||
|
||||
|
||||
def update_node_credentials_from_successful_attempts(edge: EdgeService, telemetry_json):
|
||||
for attempt in telemetry_json["data"]["attempts"]:
|
||||
if attempt["result"]:
|
||||
|
|
|
@ -1,13 +1,137 @@
|
|||
from tests.unit_tests.monkey_island.cc.services.reporting.test_report import (
|
||||
NODE_DICT,
|
||||
NODE_DICT_DUPLICATE_EXPLOITS,
|
||||
NODE_DICT_FAILED_EXPLOITS,
|
||||
)
|
||||
import datetime
|
||||
from copy import deepcopy
|
||||
|
||||
from bson import ObjectId
|
||||
|
||||
from monkey_island.cc.services.reporting.exploitations.monkey_exploitation import (
|
||||
get_exploits_used_on_node,
|
||||
)
|
||||
|
||||
TELEM_ID = {
|
||||
"exploit_creds": ObjectId(b"123456789000"),
|
||||
"system_info_creds": ObjectId(b"987654321000"),
|
||||
"no_creds": ObjectId(b"112233445566"),
|
||||
"monkey": ObjectId(b"665544332211"),
|
||||
}
|
||||
MONKEY_GUID = "67890"
|
||||
USER = "user-name"
|
||||
PWD = "password123"
|
||||
LM_HASH = "e52cac67419a9a22664345140a852f61"
|
||||
NT_HASH = "a9fdfa038c4b75ebc76dc855dd74f0da"
|
||||
VICTIM_IP = "0.0.0.0"
|
||||
VICTIM_DOMAIN_NAME = "domain-name"
|
||||
HOSTNAME = "name-of-host"
|
||||
|
||||
# Below telem constants only contain fields relevant to current tests
|
||||
|
||||
EXPLOIT_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["exploit_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "exploit",
|
||||
"data": {
|
||||
"machine": {
|
||||
"ip_addr": VICTIM_IP,
|
||||
"domain_name": VICTIM_DOMAIN_NAME,
|
||||
},
|
||||
"info": {
|
||||
"credentials": {
|
||||
USER: {
|
||||
"username": USER,
|
||||
"lm_hash": LM_HASH,
|
||||
"ntlm_hash": NT_HASH,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
SYSTEM_INFO_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["system_info_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "system_info",
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"command_control_channel": {
|
||||
"src": "192.168.56.1",
|
||||
"dst": "192.168.56.2",
|
||||
},
|
||||
"data": {
|
||||
"credentials": {
|
||||
USER: {
|
||||
"password": PWD,
|
||||
"lm_hash": LM_HASH,
|
||||
"ntlm_hash": NT_HASH,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
NO_CREDS_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["no_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "exploit",
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"command_control_channel": {
|
||||
"src": "192.168.56.1",
|
||||
"dst": "192.168.56.2",
|
||||
},
|
||||
"data": {
|
||||
"machine": {
|
||||
"ip_addr": VICTIM_IP,
|
||||
"domain_name": VICTIM_DOMAIN_NAME,
|
||||
},
|
||||
"info": {"credentials": {}},
|
||||
},
|
||||
}
|
||||
|
||||
MONKEY_TELEM = {"_id": TELEM_ID["monkey"], "guid": MONKEY_GUID, "hostname": HOSTNAME}
|
||||
|
||||
NODE_DICT = {
|
||||
"id": "602f62118e30cf35830ff8e4",
|
||||
"label": "WinDev2010Eval.mshome.net",
|
||||
"group": "monkey_windows",
|
||||
"os": "windows",
|
||||
"dead": True,
|
||||
"exploits": [
|
||||
{
|
||||
"exploitation_result": True,
|
||||
"exploiter": "DrupalExploiter",
|
||||
"info": {
|
||||
"display_name": "Drupal Server",
|
||||
"started": datetime.datetime(2021, 2, 19, 9, 0, 14, 950000),
|
||||
"finished": datetime.datetime(2021, 2, 19, 9, 0, 14, 950000),
|
||||
"vulnerable_urls": [],
|
||||
"vulnerable_ports": [],
|
||||
"executed_cmds": [],
|
||||
},
|
||||
"attempts": [],
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"origin": "MonkeyIsland : 192.168.56.1",
|
||||
},
|
||||
{
|
||||
"exploitation_result": True,
|
||||
"exploiter": "ZerologonExploiter",
|
||||
"info": {
|
||||
"display_name": "Zerologon",
|
||||
"started": datetime.datetime(2021, 2, 19, 9, 0, 15, 16000),
|
||||
"finished": datetime.datetime(2021, 2, 19, 9, 0, 15, 17000),
|
||||
"vulnerable_urls": [],
|
||||
"vulnerable_ports": [],
|
||||
"executed_cmds": [],
|
||||
},
|
||||
"attempts": [],
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 15, 60000),
|
||||
"origin": "MonkeyIsland : 192.168.56.1",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
NODE_DICT_DUPLICATE_EXPLOITS = deepcopy(NODE_DICT)
|
||||
NODE_DICT_DUPLICATE_EXPLOITS["exploits"][1] = NODE_DICT_DUPLICATE_EXPLOITS["exploits"][0]
|
||||
|
||||
NODE_DICT_FAILED_EXPLOITS = deepcopy(NODE_DICT)
|
||||
NODE_DICT_FAILED_EXPLOITS["exploits"][0]["exploitation_result"] = False
|
||||
NODE_DICT_FAILED_EXPLOITS["exploits"][1]["exploitation_result"] = False
|
||||
|
||||
|
||||
def test_get_exploits_used_on_node__2_exploits():
|
||||
exploits = get_exploits_used_on_node(NODE_DICT)
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
import datetime
|
||||
from copy import deepcopy
|
||||
|
||||
import mongoengine
|
||||
import pytest
|
||||
from bson import ObjectId
|
||||
|
||||
from monkey_island.cc.models.telemetries import save_telemetry
|
||||
from monkey_island.cc.services.reporting.report import ReportService
|
||||
|
||||
TELEM_ID = {
|
||||
"exploit_creds": ObjectId(b"123456789000"),
|
||||
"system_info_creds": ObjectId(b"987654321000"),
|
||||
"no_creds": ObjectId(b"112233445566"),
|
||||
"monkey": ObjectId(b"665544332211"),
|
||||
}
|
||||
MONKEY_GUID = "67890"
|
||||
USER = "user-name"
|
||||
PWD = "password123"
|
||||
LM_HASH = "e52cac67419a9a22664345140a852f61"
|
||||
NT_HASH = "a9fdfa038c4b75ebc76dc855dd74f0da"
|
||||
VICTIM_IP = "0.0.0.0"
|
||||
VICTIM_DOMAIN_NAME = "domain-name"
|
||||
HOSTNAME = "name-of-host"
|
||||
|
||||
# Below telem constants only contain fields relevant to current tests
|
||||
|
||||
EXPLOIT_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["exploit_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "exploit",
|
||||
"data": {
|
||||
"machine": {
|
||||
"ip_addr": VICTIM_IP,
|
||||
"domain_name": VICTIM_DOMAIN_NAME,
|
||||
},
|
||||
"info": {
|
||||
"credentials": {
|
||||
USER: {
|
||||
"username": USER,
|
||||
"lm_hash": LM_HASH,
|
||||
"ntlm_hash": NT_HASH,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
SYSTEM_INFO_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["system_info_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "system_info",
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"command_control_channel": {
|
||||
"src": "192.168.56.1",
|
||||
"dst": "192.168.56.2",
|
||||
},
|
||||
"data": {
|
||||
"credentials": {
|
||||
USER: {
|
||||
"password": PWD,
|
||||
"lm_hash": LM_HASH,
|
||||
"ntlm_hash": NT_HASH,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
NO_CREDS_TELEMETRY_TELEM = {
|
||||
"_id": TELEM_ID["no_creds"],
|
||||
"monkey_guid": MONKEY_GUID,
|
||||
"telem_category": "exploit",
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"command_control_channel": {
|
||||
"src": "192.168.56.1",
|
||||
"dst": "192.168.56.2",
|
||||
},
|
||||
"data": {
|
||||
"machine": {
|
||||
"ip_addr": VICTIM_IP,
|
||||
"domain_name": VICTIM_DOMAIN_NAME,
|
||||
},
|
||||
"info": {"credentials": {}},
|
||||
},
|
||||
}
|
||||
|
||||
MONKEY_TELEM = {"_id": TELEM_ID["monkey"], "guid": MONKEY_GUID, "hostname": HOSTNAME}
|
||||
|
||||
NODE_DICT = {
|
||||
"id": "602f62118e30cf35830ff8e4",
|
||||
"label": "WinDev2010Eval.mshome.net",
|
||||
"group": "monkey_windows",
|
||||
"os": "windows",
|
||||
"dead": True,
|
||||
"exploits": [
|
||||
{
|
||||
"exploitation_result": True,
|
||||
"exploiter": "DrupalExploiter",
|
||||
"info": {
|
||||
"display_name": "Drupal Server",
|
||||
"started": datetime.datetime(2021, 2, 19, 9, 0, 14, 950000),
|
||||
"finished": datetime.datetime(2021, 2, 19, 9, 0, 14, 950000),
|
||||
"vulnerable_urls": [],
|
||||
"vulnerable_ports": [],
|
||||
"executed_cmds": [],
|
||||
},
|
||||
"attempts": [],
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 14, 984000),
|
||||
"origin": "MonkeyIsland : 192.168.56.1",
|
||||
},
|
||||
{
|
||||
"exploitation_result": True,
|
||||
"exploiter": "ZerologonExploiter",
|
||||
"info": {
|
||||
"display_name": "Zerologon",
|
||||
"started": datetime.datetime(2021, 2, 19, 9, 0, 15, 16000),
|
||||
"finished": datetime.datetime(2021, 2, 19, 9, 0, 15, 17000),
|
||||
"vulnerable_urls": [],
|
||||
"vulnerable_ports": [],
|
||||
"executed_cmds": [],
|
||||
},
|
||||
"attempts": [],
|
||||
"timestamp": datetime.datetime(2021, 2, 19, 9, 0, 15, 60000),
|
||||
"origin": "MonkeyIsland : 192.168.56.1",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
NODE_DICT_DUPLICATE_EXPLOITS = deepcopy(NODE_DICT)
|
||||
NODE_DICT_DUPLICATE_EXPLOITS["exploits"][1] = NODE_DICT_DUPLICATE_EXPLOITS["exploits"][0]
|
||||
|
||||
NODE_DICT_FAILED_EXPLOITS = deepcopy(NODE_DICT)
|
||||
NODE_DICT_FAILED_EXPLOITS["exploits"][0]["exploitation_result"] = False
|
||||
NODE_DICT_FAILED_EXPLOITS["exploits"][1]["exploitation_result"] = False
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_mongo(monkeypatch):
|
||||
mongo = mongoengine.connection.get_connection()
|
||||
monkeypatch.setattr("monkey_island.cc.services.reporting.report.mongo", mongo)
|
||||
monkeypatch.setattr("monkey_island.cc.models.telemetries.telemetry_dal.mongo", mongo)
|
||||
monkeypatch.setattr("monkey_island.cc.services.node.mongo", mongo)
|
||||
return mongo
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("uses_database")
|
||||
def test_get_stolen_creds_exploit(fake_mongo):
|
||||
fake_mongo.db.telemetry.insert_one(EXPLOIT_TELEMETRY_TELEM)
|
||||
|
||||
stolen_creds_exploit = ReportService.get_stolen_creds()
|
||||
expected_stolen_creds_exploit = [
|
||||
{"origin": VICTIM_DOMAIN_NAME, "type": "LM hash", "username": USER},
|
||||
{"origin": VICTIM_DOMAIN_NAME, "type": "NTLM hash", "username": USER},
|
||||
]
|
||||
|
||||
assert expected_stolen_creds_exploit == stolen_creds_exploit
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.usefixtures("uses_database", "uses_encryptor")
|
||||
def test_get_stolen_creds_from_db(fake_mongo):
|
||||
fake_mongo.db.monkey.insert_one(MONKEY_TELEM)
|
||||
save_telemetry(SYSTEM_INFO_TELEMETRY_TELEM)
|
||||
|
||||
stolen_creds_system_info = ReportService.get_stolen_creds()
|
||||
expected_stolen_creds_from_db = [
|
||||
{"origin": HOSTNAME, "type": "Clear Password", "username": USER},
|
||||
{"origin": HOSTNAME, "type": "LM hash", "username": USER},
|
||||
{"origin": HOSTNAME, "type": "NTLM hash", "username": USER},
|
||||
]
|
||||
|
||||
assert expected_stolen_creds_from_db == stolen_creds_system_info
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("uses_database")
|
||||
def test_get_stolen_creds_no_creds(fake_mongo):
|
||||
fake_mongo.db.monkey.insert_one(MONKEY_TELEM)
|
||||
save_telemetry(NO_CREDS_TELEMETRY_TELEM)
|
||||
|
||||
stolen_creds_no_creds = ReportService.get_stolen_creds()
|
||||
expected_stolen_creds_no_creds = []
|
||||
|
||||
assert expected_stolen_creds_no_creds == stolen_creds_no_creds
|
Loading…
Reference in New Issue