From 3f3255141464111edc8afe974b336e633e5d5f8a Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Mon, 13 Sep 2021 10:38:13 +0200 Subject: [PATCH] Auto generate human readable Doc and put it into result zip --- app/doc_generator.py | 44 ++++++++++++++++++++++++++++++++++++++++ app/experimentcontrol.py | 9 +++++++- doc_generator.py | 44 +++++++++++++--------------------------- 3 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 app/doc_generator.py diff --git a/app/doc_generator.py b/app/doc_generator.py new file mode 100644 index 0000000..9abc4ff --- /dev/null +++ b/app/doc_generator.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +# A document generator module. + +import json +import os +from jinja2 import Environment, FileSystemLoader, select_autoescape + +class DocGenerator(): + """ Generates human readable docs from attack logs """ + + def __init__(self): + self.outfile = None + + def generate(self, jfile, outfile="tools/human_readable_documentation/source/contents.rst"): + + self.outfile = outfile + + env = Environment( + loader=FileSystemLoader("templates", encoding='utf-8', followlinks=False), + autoescape=select_autoescape(), + trim_blocks=True, + # lstrip_blocks=True + ) + template = env.get_template("attack_description.rst") + + with open(jfile) as fh: + events = json.load(fh) + + rendered = template.render(events=events) + print(rendered) + + with open(outfile, "wt") as fh: + fh.write(rendered) + + def compile_documentation(self): + """ Compiles the documentation using make """ + + os.system("cd tools/human_readable_documentation ; make html; make latexpdf ") + + def get_outfile_paths(self): + """ Returns the path of the output file written """ + + return ["tools/human_readable_documentation/build/latex/purpledomesimulation.pdf"] diff --git a/app/experimentcontrol.py b/app/experimentcontrol.py index 1b09b75..cbd6320 100644 --- a/app/experimentcontrol.py +++ b/app/experimentcontrol.py @@ -13,11 +13,13 @@ from app.config import ExperimentConfig from app.interface_sfx import CommandlineColors from app.exceptions import ServerError from app.pluginmanager import PluginManager +from app.doc_generator import DocGenerator from caldera_control import CalderaControl from machine_control import Machine from plugins.base.attack import AttackPlugin + # TODO: Multi threading at least when starting machines class Experiment(): @@ -185,7 +187,12 @@ class Experiment(): self.__stop_attacker() self.attack_logger.post_process() - self.attack_logger.write_json(os.path.join(self.lootdir, "attack.json")) + attack_log_file_path = os.path.join(self.lootdir, "attack.json") + self.attack_logger.write_json(attack_log_file_path) + dg = DocGenerator() + dg.generate(attack_log_file_path) + dg.compile_documentation() + zip_this += dg.get_outfile_paths() self.zip_loot(zip_this) def attack(self, target, attack): diff --git a/doc_generator.py b/doc_generator.py index 1709548..adae904 100755 --- a/doc_generator.py +++ b/doc_generator.py @@ -1,44 +1,28 @@ #!/usr/bin/env python3 -# A standalon document generator. Takes an attack log and generates a doc using templates. Functionality will later be merged into PurpleDome +# A standalone document generator. Takes an attack log and generates a doc using templates. Functionality will later be merged into PurpleDome import json from jinja2 import Environment, FileSystemLoader, select_autoescape # from pprint import pprint +import argparse +from app.doc_generator import DocGenerator +default_attack_log = "removeme/loot/2021_09_08___07_41_35/attack.json" # FIN 7 first run on environment -def generate(jfile, outfile): - env = Environment( - loader=FileSystemLoader("templates", encoding='utf-8', followlinks=False), - autoescape=select_autoescape(), - trim_blocks=True, - # lstrip_blocks=True - ) - template = env.get_template("attack_description.rst") - with open(jfile) as fh: - events = json.load(fh) +def create_parser(): + """ Creates the parser for the command line arguments""" + parser = argparse.ArgumentParser("Controls an experiment on the configured systems") - rendered = template.render(events=events) - print(rendered) + parser.add_argument("--attack_log", default=default_attack_log, help="The attack log the document is based on") + parser.add_argument("--outfile", default="tools/human_readable_documentation/source/contents.rst", help="The default output file") - with open(outfile, "wt") as fh: - fh.write(rendered) + return parser if __name__ == "__main__": - # generate("loot/2021_07_19___16_28_45/attack.json", "tools/human_readable_documentation/contents.rst") # Working example for a short run - # generate("loot/2021_07_20___08_26_33/attack.json", "tools/human_readable_documentation/contents.rst") # FIN 7 #1 - # generate("loot/2021_07_20___10_07_36/attack.json", "tools/human_readable_documentation/contents.rst") # FIN 7 #2 The one Fabrizio got - # 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("removeme/loot/2021_09_08___07_41_35/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") + arguments = create_parser().parse_args() + + dg = DocGenerator() + dg.generate(arguments.attack_log, arguments.outfile) \ No newline at end of file