improving human readable documents by adding results of the attack

pull/12/head
Thorsten Sick 3 years ago
parent 10fa4a97d8
commit 7e6ff60e25

@ -5,9 +5,10 @@
import json
import datetime
from random import randint
from typing import Optional
def __mitre_fix_ttp__(ttp):
def __mitre_fix_ttp__(ttp: Optional[str]) -> str:
""" enforce some systematic naming scheme for MITRE TTPs """
if ttp is None:
@ -22,12 +23,12 @@ def __mitre_fix_ttp__(ttp):
class AttackLog():
""" A specific logger class to log the progress of the attack steps """
def __init__(self, verbosity=0):
def __init__(self, verbosity: int = 0):
"""
@param verbosity: verbosity setting from 0 to 3 for stdout printing
"""
self.log = []
self.log: list[dict] = []
self.verbosity = verbosity
# TODO. As soon as someone wants custom timestamps, make the format variable
@ -41,12 +42,12 @@ class AttackLog():
self.log.append(item)
def __get_timestamp__(self):
def __get_timestamp__(self) -> str:
""" Get the timestamp to add to the log entries. Currently not configurable """
return datetime.datetime.now().strftime(self.datetime_format)
def get_caldera_default_name(self, ability_id):
def get_caldera_default_name(self, ability_id: str):
""" Returns the default name for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": "whoami"}
if ability_id not in data:
@ -54,7 +55,7 @@ class AttackLog():
return data[ability_id]
def get_caldera_default_description(self, ability_id):
def get_caldera_default_description(self, ability_id: str):
""" Returns the default description for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": "Obtain user from current session"}
@ -63,16 +64,16 @@ class AttackLog():
return data[ability_id]
def get_caldera_default_tactics(self, ability_id):
def get_caldera_default_tactics(self, ability_id: str):
""" Returns the default tactics for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": " System Owner/User Discovery"}
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": "System Owner/User Discovery"}
if ability_id not in data:
return None
return data[ability_id]
def get_caldera_default_tactics_id(self, ability_id):
def get_caldera_default_tactics_id(self, ability_id: str):
""" Returns the default name for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": "T1033"}
@ -81,7 +82,7 @@ class AttackLog():
return data[ability_id]
def get_caldera_default_situation_description(self, ability_id):
def get_caldera_default_situation_description(self, ability_id: str):
""" Returns the default situation description for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": None}
@ -90,7 +91,7 @@ class AttackLog():
return data[ability_id]
def get_caldera_default_countermeasure(self, ability_id):
def get_caldera_default_countermeasure(self, ability_id: str):
""" Returns the default countermeasure for this ability based on a db """
data = {"bd527b63-9f9e-46e0-9816-b8434d2b8989": None}
@ -99,7 +100,7 @@ class AttackLog():
return data[ability_id]
def start_caldera_attack(self, source, paw, group, ability_id, ttp=None, **kwargs):
def start_caldera_attack(self, source: str, paw: str, group: str, ability_id: str, ttp: str = None, **kwargs):
""" Mark the start of a caldera attack
@param source: source of the attack. Attack IP
@ -131,6 +132,7 @@ class AttackLog():
"countermeasure": kwargs.get("countermeasure", self.get_caldera_default_countermeasure(ability_id)), # Set by the attack
"obfuscator": kwargs.get("obfuscator", "default"),
"jitter": kwargs.get("jitter", "default"),
"result": None,
}
self.__add_to_log__(data)
@ -141,7 +143,7 @@ class AttackLog():
# TODO: Add config
# TODO: Add results
def stop_caldera_attack(self, source, paw, group, ability_id, ttp=None, **kwargs):
def stop_caldera_attack(self, source: str, paw: str, group: str, ability_id: str, ttp: str = None, **kwargs):
""" Mark the end of a caldera attack
@param source: source of the attack. Attack IP
@ -168,11 +170,12 @@ class AttackLog():
"description": kwargs.get("description", ""),
"obfuscator": kwargs.get("obfuscator", "default"),
"jitter": kwargs.get("jitter", "default"),
"logid": kwargs.get("logid", None)
"logid": kwargs.get("logid", None),
"result": kwargs.get("result", None),
}
self.__add_to_log__(data)
def start_file_write(self, source, target, file_name):
def start_file_write(self, source: str, target: str, file_name: str):
""" Mark the start of a file being written to the target (payload !)
@param source: source of the attack. Attack IP (empty if written from controller)
@ -196,7 +199,7 @@ class AttackLog():
self.__add_to_log__(data)
return logid
def stop_file_write(self, source, target, file_name, **kwargs):
def stop_file_write(self, source: str, target: str, file_name: str, **kwargs):
""" Mark the stop of a file being written to the target (payload !)
@param source: source of the attack. Attack IP (empty if written from controller)
@ -220,12 +223,12 @@ class AttackLog():
self.__add_to_log__(data)
def start_execute_payload(self, source, target, command):
def start_execute_payload(self, source: str, target: str, command: str):
""" Mark the start of a payload being executed
@param source: source of the attack. Attack IP (empty if written from controller)
@param target: Target machine of the attack
@param command: Name of the file being written
@param command:
"""
timestamp = self.__get_timestamp__()
@ -245,7 +248,7 @@ class AttackLog():
return logid
def stop_execute_payload(self, source, target, command, **kwargs):
def stop_execute_payload(self, source: str, target: str, command: str, **kwargs):
""" Mark the stop of a payload being executed
@param source: source of the attack. Attack IP (empty if written from controller)
@ -266,7 +269,7 @@ class AttackLog():
}
self.__add_to_log__(data)
def start_kali_attack(self, source, target, attack_name, ttp=None, **kwargs):
def start_kali_attack(self, source: str, target: str, attack_name: str, ttp: str = None, **kwargs):
""" Mark the start of a Kali based attack
@param source: source of the attack. Attack IP
@ -295,6 +298,7 @@ class AttackLog():
"description": kwargs.get("description", None), # Generic description for this attack. Set by the attack
"situation_description": kwargs.get("situation_description", None), # Description for the situation this attack was run in. Set by the plugin or attacker emulation
"countermeasure": kwargs.get("countermeasure", None), # Set by the attack
"result": None,
}
self.__add_to_log__(data)
@ -304,7 +308,7 @@ class AttackLog():
# TODO: Add config
# TODO: Add results
def stop_kali_attack(self, source, target, attack_name, ttp=None, **kwargs):
def stop_kali_attack(self, source: str, target: str, attack_name: str, ttp: str = None, **kwargs):
""" Mark the end of a Kali based attack
@param source: source of the attack. Attack IP
@ -321,11 +325,12 @@ class AttackLog():
"target": target,
"kali_name": attack_name,
"hunting_tag": __mitre_fix_ttp__(ttp),
"logid": kwargs.get("logid", None)
"logid": kwargs.get("logid", None),
"result": kwargs.get("result", None),
}
self.__add_to_log__(data)
def start_narration(self, text):
def start_narration(self, text: str):
""" Add some user defined narration. Can be used in plugins to describe the situation before and after the attack, ...
At the moment there is no stop narration command. I do not think we need one. But I want to stick to the structure
@ -344,6 +349,42 @@ class AttackLog():
self.__add_to_log__(data)
return logid
def start_attack_step(self, text: str):
""" Mark the start of an attack step (several attacks in a chunk)
@param text: description of the attack step being started
"""
timestamp = self.__get_timestamp__()
logid = timestamp + "_" + str(randint(1, 100000))
data = {"timestamp": timestamp,
"timestamp_end": None,
"event": "start",
"type": "attack_step",
"sub_type": "user defined attack step",
"text": text,
"logid": logid,
}
self.__add_to_log__(data)
return logid
def stop_attack_step(self, text: str, **kwargs):
""" Mark the end of an attack step (several attacks in a chunk)
@param text: description of the attack step being stopped
"""
data = {"timestamp": self.__get_timestamp__(),
"event": "stop",
"type": "attack_step",
"sub_type": "user defined attack step",
"text": text,
"logid": kwargs.get("logid", None)
}
self.__add_to_log__(data)
def start_build(self, **kwargs):
""" Mark the start of a tool building/compilation process
@ -401,7 +442,7 @@ class AttackLog():
}
self.__add_to_log__(data)
def start_metasploit_attack(self, source, target, metasploit_command, ttp=None, **kwargs):
def start_metasploit_attack(self, source: str, target: str, metasploit_command: str, ttp: str = None, **kwargs):
""" Mark the start of a Metasploit based attack
@param source: source of the attack. Attack IP
@ -429,12 +470,13 @@ class AttackLog():
"description": kwargs.get("description", None), # Generic description for this attack. Set by the attack
"situation_description": kwargs.get("situation_description", None), # Description for the situation this attack was run in. Set by the plugin or attacker emulation
"countermeasure": kwargs.get("countermeasure", None), # Set by the attack
"result": None
}
self.__add_to_log__(data)
return logid
def stop_metasploit_attack(self, source, target, metasploit_command, ttp=None, **kwargs):
def stop_metasploit_attack(self, source: str, target: str, metasploit_command: str, ttp: str = None, **kwargs):
""" Mark the start of a Metasploit based attack
@param source: source of the attack. Attack IP
@ -451,11 +493,12 @@ class AttackLog():
"target": target,
"metasploit_command": metasploit_command,
"hunting_tag": __mitre_fix_ttp__(ttp),
"logid": kwargs.get("logid", None)
"logid": kwargs.get("logid", None),
"result": kwargs.get("result", None)
}
self.__add_to_log__(data)
def start_attack_plugin(self, source, target, plugin_name, ttp=None):
def start_attack_plugin(self, source: str, target: str, plugin_name: str, ttp: str = None):
""" Mark the start of an attack plugin
@param source: source of the attack. Attack IP
@ -485,7 +528,7 @@ class AttackLog():
# TODO: Add config
# TODO: Add results
def stop_attack_plugin(self, source, target, plugin_name, **kwargs):
def stop_attack_plugin(self, source: str, target: str, plugin_name: str, **kwargs):
""" Mark the end of an attack plugin
@param source: source of the attack. Attack IP
@ -507,7 +550,7 @@ class AttackLog():
}
self.__add_to_log__(data)
def write_json(self, filename):
def write_json(self, filename: str):
""" Write the json data for this log
@param filename: Name of the json file
@ -526,6 +569,9 @@ class AttackLog():
if replace_entry["event"] == "start" and "logid" in replace_entry and replace_entry["logid"] == logid:
# Found matching start event. Updating it
replace_entry["timestamp_end"] = entry["timestamp"]
if "result" in entry:
replace_entry["result"] = entry["result"]
def get_dict(self):
""" Return logged data in dict format """
@ -540,7 +586,7 @@ class AttackLog():
# TODO: Return full doc
def vprint(self, text, verbosity):
def vprint(self, text: str, verbosity: int):
""" verbosity based stdout printing
0: Errors only

@ -625,7 +625,7 @@ class CalderaControl():
self.add_adversary(adversary_name, ability_id)
adid = self.get_adversary(adversary_name)["adversary_id"]
self.attack_logger.start_caldera_attack(source=self.url,
logid = self.attack_logger.start_caldera_attack(source=self.url,
paw=paw,
group=group,
ability_id=ability_id,
@ -682,9 +682,11 @@ class CalderaControl():
except CalderaError:
pass
outp=""
if output is None:
output = str(self.get_operation_by_id(opid))
self.attack_logger.vprint(f"{CommandlineColors.FAIL}Failed getting operation data. We just have: {output} from get_operation_by_id{CommandlineColors.ENDC}", 0)
outp = str(self.get_operation_by_id(opid))
self.attack_logger.vprint(f"{CommandlineColors.FAIL}Failed getting operation data. We just have: {outp} from get_operation_by_id{CommandlineColors.ENDC}", 0)
else:
outp = str(output)
self.attack_logger.vprint(f"{CommandlineColors.BACKGROUND_GREEN} Output: {outp} {CommandlineColors.ENDC}", 2)
@ -704,7 +706,9 @@ class CalderaControl():
name=self.get_ability(ability_id)[0]["name"],
description=self.get_ability(ability_id)[0]["description"],
obfuscator=obfuscator,
jitter=jitter
jitter=jitter,
logid=logid,
result=[outp]
)
return True

@ -438,7 +438,8 @@ class MetasploitInstant(Metasploit):
target=target.get_ip(),
metasploit_command=command,
ttp=ttp,
logid=logid)
logid=logid,
result=res)
return res
def migrate(self, target, user=None, name=None, arch=None):
@ -472,7 +473,8 @@ class MetasploitInstant(Metasploit):
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res
def arp_network_discovery(self, target, **kwargs):
@ -505,7 +507,8 @@ class MetasploitInstant(Metasploit):
target=target.get_ip(),
metasploit_command=command,
ttp=ttp,
logid=logid)
logid=logid,
result=res)
return res
def nslookup(self, target, target2, **kwargs):
@ -542,7 +545,8 @@ class MetasploitInstant(Metasploit):
target=target.get_ip(),
metasploit_command=command,
ttp=ttp,
logid=logid)
logid=logid,
result=res)
return res
def getsystem(self, target, **kwargs):
@ -580,7 +584,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
target=target.get_ip(),
metasploit_command=command,
ttp=ttp,
logid=logid)
logid=logid,
result=res)
return res
def clearev(self, target):
@ -601,7 +606,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res
def screengrab(self, target):
@ -628,7 +634,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res
def keylogging(self, target, monitoring_time):
@ -660,7 +667,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res
def getuid(self, target):
@ -683,7 +691,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res[0]
def sysinfo(self, target):
@ -706,7 +715,8 @@ Elevate privileges from local administrator to SYSTEM. Three ways to do that wil
self.attack_logger.stop_metasploit_attack(source=self.attacker.get_ip(),
target=target.get_ip(),
metasploit_command=command,
ttp=ttp)
ttp=ttp,
result=res)
return res[0]
def upload(self, target, src, dst, **kwargs):
@ -745,5 +755,6 @@ Uploading new files to the target. Can be config files, tools, implants, ...
target=target.get_ip(),
metasploit_command=command,
ttp=ttp,
logid=logid)
logid=logid,
result=res)
return res

@ -12,19 +12,18 @@ def generate(jfile, outfile):
loader=FileSystemLoader("templates", encoding='utf-8', followlinks=False),
autoescape=select_autoescape(),
trim_blocks=True,
lstrip_blocks=True
# lstrip_blocks=True
)
template = env.get_template("attack_description.rst")
with open(jfile) as fh:
events = json.load(fh)
print(template.render(events=events))
# pprint(events)
# dest = os.path.join(self.get_plugin_path(), "filebeat.conf")
# with open(dest, "wt") as fh:
# res = template.render({"playground": self.get_playground()})
# fh.write(res)
rendered = template.render(events=events)
print(rendered)
with open(outfile, "wt") as fh:
fh.write(rendered)
if __name__ == "__main__":
@ -34,8 +33,13 @@ if __name__ == "__main__":
# generate("loot/2021_07_28___12_09_00/attack.json",
# "tools/human_readable_documentation/contents.rst") # FIN 7 The last minute locally generated thing
generate("loot/2021_08_30___14_40_23/attack.json",
"tools/human_readable_documentation/contents.rst") # FIN 7 With genereated files added
# generate("loot/2021_08_30___14_40_23/attack.json",
# "tools/human_readable_documentation/contents.rst") # FIN 7 With genereated files added
# generate("removeme/loot/2021_09_07___08_59_42/attack.json",
# "tools/human_readable_documentation/source/contents.rst") # FIN 7 first run on environment
generate("loot/2021_09_07___16_20_48/attack.json",
"tools/human_readable_documentation/source/contents.rst") # FIN 7 locally with extended data (older: loot/2021_09_07___14_38_14)
# generate("loot/2021_07_19___15_10_45/attack.json", "tools/human_readable_documentation/contents.rst")
# generate("removeme.json", "tools/human_readable_documentation/contents.rst")

@ -44,9 +44,7 @@ class FIN7Plugin(AttackPlugin):
def step1(self):
self.attack_logger.vprint(f"{CommandlineColors.OKBLUE}Step 1 (target hotelmanager): Initial Breach{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 1 (target hotelmanager): Initial Breach\n----------------------------")
self.attack_logger.start_attack_step("Step 1 (target hotelmanager): Initial Breach")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET
@ -73,8 +71,7 @@ This is the initial attack step that requires user interaction. Maybe it is bett
def step2(self):
self.attack_logger.vprint(f"{CommandlineColors.OKBLUE}Step 2 (target hotelmanager): Delayed Malware Execution{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 2 (target hotelmanager): Delayed Malware Execution\n----------------------------")
self.attack_logger.start_attack_step("Step 2 (target hotelmanager): Delayed Malware Execution")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET
@ -97,7 +94,7 @@ In this simulation sql-rat.js communication will be replaced by Caldera communic
def step3(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 3 (target hotelmanager): Target Assessment{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration("Step 3 (target hotelmanager): Target Assessment\n----------------------------")
self.attack_logger.start_attack_step("Step 3 (target hotelmanager): Target Assessment")
# TODO: Make sure logging is nice and complete
@ -254,8 +251,7 @@ In this simulation sql-rat.js communication will be replaced by Caldera communic
"""
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 4 (target hotelmanager): Staging Interactive Toolkit{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 4 (target hotelmanager): Staging Interactive Toolkit\n----------------------------")
self.attack_logger.start_attack_step("Step 4 (target hotelmanager): Staging Interactive Toolkit")
self.attack_logger.start_narration("""
In the original attack Babymetal payload is a dll. Currently we are using a simplification here (directly calling a exe). The original steps are:
* Target already runs adb156.exe. This one gets the shellcode over the network connection and decodes it.
@ -305,8 +301,7 @@ In the original attack Babymetal payload is a dll. Currently we are using a simp
def step5(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 5 (target hotelmanager): Escalate Privileges{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 5 (target hotelmanager): Escalate Privileges\n----------------------------")
self.attack_logger.start_attack_step("Step 5 (target hotelmanager): Escalate Privileges")
hotelmanager = self.get_target_by_name("hotelmanager")
@ -388,12 +383,14 @@ In the original attack Babymetal payload is a dll. Currently we are using a simp
situation_description="Executing Mimikatz through UAC bypassing powershell",
countermeasure="Behaviour detection"
)
print(metasploit.meterpreter_execute_on([execute_samcats], hotelmanager, delay=20))
result = metasploit.meterpreter_execute_on([execute_samcats], hotelmanager, delay=20)
print(result)
self.attack_logger.stop_metasploit_attack(source=self.attacker_machine_plugin.get_ip(),
target=hotelmanager.get_ip(),
metasploit_command=execute_samcats,
ttp="T1003",
logid=logid)
logid=logid,
result=result)
# samcat.exe: reads local credentials https://attack.mitre.org/techniques/T1003/001/
@ -481,8 +478,7 @@ In the original attack Babymetal payload is a dll. Currently we are using a simp
def step6(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 6 (target hotelmanager -> itadmin): Expand Access{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 6 (target hotelmanager and itadmin): Expand Access\n----------------------------")
self.attack_logger.start_attack_step("Step 6 (target hotelmanager and itadmin): Expand Access")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET. NEEDS A SECOND MACHINE FOR LATERAL MOVEMENT
* powershell download: paexec.exe and hollow.exe https://attack.mitre.org/techniques/T1105/
@ -543,8 +539,7 @@ NOT IMPLEMENTED YET. NEEDS A SECOND MACHINE FOR LATERAL MOVEMENT
def step7(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 7 on itadmin: Setup User Monitoring{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 7 (target itadmin): Setup User Monitoring\n----------------------------")
self.attack_logger.start_attack_step("Step 7 (target itadmin): Setup User Monitoring")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET. A REPLACEMENT FOR THE ALOHA COMMAND CENTER IS NEEDED
@ -579,8 +574,7 @@ NOT IMPLEMENTED YET. A REPLACEMENT FOR THE ALOHA COMMAND CENTER IS NEEDED
def step8(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 8 (target: itadmin as domain_admin): User Monitoring{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 8 (target itadmin): User Monitoring\n----------------------------")
self.attack_logger.start_attack_step("Step 8 (target itadmin): User Monitoring")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET. MAYBE DO THIS PARTIAL. KEYLOGGING NEEDS USER INTERACTION.
(Screen spying and keylogging are already implemented as standalone metasploit attacks. Use them)
@ -700,8 +694,7 @@ NOT IMPLEMENTED YET. MAYBE DO THIS PARTIAL. KEYLOGGING NEEDS USER INTERACTION.
def step9(self):
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 9 (target: accounting): Setup Shim Persistence{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 9 (target accounting): Setup Shim Persistence\n----------------------------")
self.attack_logger.start_attack_step("Step 9 (target accounting): Setup Shim Persistence")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET
@ -791,8 +784,7 @@ NOT IMPLEMENTED YET
self.attack_logger.vprint(
f"{CommandlineColors.OKBLUE}Step 10 (target: accounting): Steal Payment Data{CommandlineColors.ENDC}", 1)
self.attack_logger.start_narration(
"Step 10 (target accounting): Steal Payment Data\n----------------------------")
self.attack_logger.start_attack_step("Step 10 (target accounting): Steal Payment Data")
self.attack_logger.start_narration("""
NOT IMPLEMENTED YET. NEEDS TARGET REBOOTING: NO IDEA IF ATTACKX CAN SUPPORT THAT

@ -7,114 +7,161 @@ Target systems
Attack steps
------------
{% for e in events %}
{% if e.event is eq("start") %}
{% if e.type is eq("dropping_file") %}
Dropping file to target
~~~~~~~~~~~~~~~~~~~~~~~
At {{ e.timestamp }}
The file {{ e.file_name }} is dropped to the target {{ e.target }}.
{% endif %}
{% if e.type is eq("execute_payload") %}
Executing payload on target
~~~~~~~~~~~~~~~~~~~~~~~~~~~
At {{ e.timestamp }}
The command {{ e.command }} is used to start a file on the target {{ e.target }}.
{% endif %}
{% if e.type is eq("narration") %}
{{ e.text }}
{% endif %}
{% if e.sub_type is eq("metasploit") %}
Metasploit attack {{ e.name }}
~~~~~~~~~~~~~~~~~~~~~~~~~~
Tactics: {{ e.tactics }}
Tactics ID: {{ e.tactics_id }}
Hunting Tag: {{ e.hunting_tag}}
At {{ e.timestamp }} a Metasploit command {{ e.name }} was used to attack {{ e.target }} from {{ e.source }}.
{{ e.description }}
{% if e.metasploit_command is string() %}
Metasploit command: {{ e.metasploit_command }}
{% endif %}
{% if e.situation_description is string() %}
Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
Countermeasure: {{ e.countermeasure }}
{% endif %}
{% endif %}
{% if e.sub_type is eq("kali") %}
Kali attack {{ e.name }}
~~~~~~~~~~~~~~~~~~~~~~~~~~
Tactics: {{ e.tactics }}
Tactics ID: {{ e.tactics_id }}
Hunting Tag: {{ e.hunting_tag}}
At {{ e.timestamp }} a Kali command {{ e.kali_name }} was used to attack {{ e.target }} from {{ e.source }}.
{{ e.description }}
{% if e.kali_command is string() %}
Kali command: {{ e.kali_command }}
{% endif %}
{% if e.situation_description is string() %}
Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
Countermeasure: {{ e.countermeasure }}
{% endif %}
{% endif %}
{% if e.sub_type is eq("caldera") %}
Caldera attack {{ e.name }}
~~~~~~~~~~~~~~~~~~~~~~~~~~
Tactics: {{ e.tactics }}
Tactics ID: {{ e.tactics_id }}
Hunting Tag: {{ e.hunting_tag}}
At {{ e.timestamp }} a Caldera ability {{ e.ability_id }}/"{{ e.name }}" was used to attack the group {{ e.target_group }} from {{ e.source }}.
{{ e.description }}
{% if e.situation_description is string() %}
Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
Countermeasure: {{ e.countermeasure }}
{% endif %}
{% endif %}
{% endif %} {# event equal start #}
{% if e.event is eq("start") %}
{% if e.type is eq("attack_step") %}
{{ e.text }}
~~~~~~~~~~~~
{% endif %} {# end attack_step #}
{% if e.type is eq("dropping_file") %}
Dropping file to target
_______________________
At {{ e.timestamp }}
The file {{ e.file_name }} is dropped to the target {{ e.target }}.
{% endif %}
{% if e.type is eq("execute_payload") %}
Executing payload on target
___________________________
At {{ e.timestamp }}
The command {{ e.command }} is used to start a file on the target {{ e.target }}.
{% endif %}
{% if e.type is eq("narration") %}
{{ e.text }}
{% endif %}
{% if e.sub_type is eq("metasploit") %}
Metasploit attack {{ e.name }}
______________________________
+ Tactics: {{ e.tactics }}
+ Tactics ID: {{ e.tactics_id }}
+ Hunting Tag: {{ e.hunting_tag}}
+ At {{ e.timestamp }} a Metasploit command {{ e.name }} was used to attack {{ e.target }} from {{ e.source }}.
+ Description: {{ e.description }}
{% if e.metasploit_command is string() %}
+ Metasploit command: {{ e.metasploit_command }}
{% endif %}
{% if e.situation_description is string() %}
+ Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
+ Countermeasure: {{ e.countermeasure }}
{% endif %}
{% if e.result is string() %}
Attack result::
{{ e.result }}
{% endif %}
{% if e.result is iterable() %}
Attack result::
{% for item in e.result %}
{{ item|trim()|indent(4) }}
{% endfor %}
{% endif %}
{% endif %}
{% if e.sub_type is eq("kali") %}
Kali attack {{ e.name }}
________________________
+ Tactics: {{ e.tactics }}
+ Tactics ID: {{ e.tactics_id }}
+ Hunting Tag: {{ e.hunting_tag}}
+ At {{ e.timestamp }} a Kali command {{ e.kali_name }} was used to attack {{ e.target }} from {{ e.source }}.
+ Description: {{ e.description }}
{% if e.kali_command is string() %}
+ Kali command: {{ e.kali_command }}
{% endif %}
{% if e.situation_description is string() %}
+ Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
+ Countermeasure: {{ e.countermeasure }}
{% endif %}
{% if e.result is string() %}
Attack result::
{{ e.result }}
{% endif %}
{% if e.result is iterable() %}
Attack result::
{% for item in e.result %}
{{ item|trim()|indent(4) }}
{% endfor %}
{% endif %}
{% endif %}
{% if e.sub_type is eq("caldera") %}
Caldera attack {{ e.name }}
___________________________
+ Tactics: {{ e.tactics }}
+ Tactics ID: {{ e.tactics_id }}
+ Hunting Tag: {{ e.hunting_tag}}
+ At {{ e.timestamp }} a Caldera ability {{ e.ability_id }}/"{{ e.name }}" was used to attack the group {{ e.target_group }} from {{ e.source }}.
+ Description: {{ e.description }}
{% if e.situation_description is string() %}
+ Situation: {{ e.situation_description }}
{% endif %}
{% if e.countermeasure is string() %}
+ Countermeasure: {{ e.countermeasure }}
{% endif %}
{% if e.result is string() %}
Attack result::
{{ e.result }}
{% endif %}
{% if e.result is iterable() %}
Attack result::
{% for item in e.result %}
{{ item|trim()|indent(4) }}
{% endfor %}
{% endif %}
{% endif %}
{% endif %} {# event equal start #}
{% endfor %}
Tools
-----
{% for e in events %}
{% if e.event is eq("start") %}
{% if e.type is eq("build") %}
Building tool {{ e.filename }}
~~~~~~~~~~~~~~~~~~~~~~~
The file {{ e.filename }} is built
{% if e.for_step %}
It will be used in Step {{ e.for_step }}
{% endif %}
Build time is between {{ e.timestamp }} and {{ e.timestamp_end }}
{% if e.dl_uri is string() %}
Built from source downloaded from {{ e.dl_uri }}
{% endif %}
{% if e.dl_uris %}
Built from sources downloaded from
{% for i in e.dl_uris %}
* {{ i }}
{% endfor %}
{% endif %}
{% if e.payload is string() %}
The attack tool uses a Meterpreter payload. The payload is {{ e.payload }}. The payload is built for the {{ e.platform }} platform and the {{ e.architecture }} architecture.
The settings for lhost and lport are {{ e.lhost }}/{{ e.lport }}.
{% endif %}
{% if e.encoding is string() %}
The file was encoded using {{ e.encoding }} after compilation.
{% endif %}
{% if e.encoded_filename is string() %}
The encoded version is named {{ e.encoded_filename }}.
{% endif %}
{% if e.SRDI_conversion %}
The attack tool was converted to position independent shellcode. See: https://github.com/monoxgas/sRDI
{% endif %}
{{ e.comment }}
{% endif %}
{% endif %}
{% if e.event is eq("start") %}
{% if e.type is eq("build") %}
Building tool {{ e.filename }}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The file {{ e.filename }} is built
{% if e.for_step %}
It will be used in Step {{ e.for_step }}
{% endif %}
Build time is between {{ e.timestamp }} and {{ e.timestamp_end }}
{% if e.dl_uri is string() %}
Built from source downloaded from {{ e.dl_uri }}
{% endif %}
{% if e.dl_uris %}
Built from sources downloaded from
{% for i in e.dl_uris %}
* {{ i }}
{% endfor %}
{% endif %}
{% if e.payload is string() %}
The attack tool uses a Meterpreter payload. The payload is {{ e.payload }}. The payload is built for the {{ e.platform }} platform and the {{ e.architecture }} architecture.
The settings for lhost and lport are {{ e.lhost }}/{{ e.lport }}.
{% endif %}
{% if e.encoding is string() %}
The file was encoded using {{ e.encoding }} after compilation.
{% endif %}
{% if e.encoded_filename is string() %}
The encoded version is named {{ e.encoded_filename }}.
{% endif %}
{% if e.SRDI_conversion %}
The attack tool was converted to position independent shellcode. See: https://github.com/monoxgas/sRDI
{% endif %}
{{ e.comment }}
{% endif %}
{% endif %}
{% endfor %}

@ -0,0 +1,23 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= python3 -m sphinx
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile all
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
all: html epub latexpdf text man

@ -13,6 +13,7 @@
# import os
# import sys
master_doc = 'contents'
# -- Project information -----------------------------------------------------
Loading…
Cancel
Save