From 89b73a72622676535b86677078c293c6e51f65ac Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Tue, 4 May 2021 15:13:58 +0200 Subject: [PATCH] Added default config for plugins --- app/config.py | 2 ++ app/pluginmanager.py | 35 +++++++++++++------ plugin_manager.py | 18 ++++++++-- plugins/base/kali.py | 13 +++++++ plugins/base/plugin_base.py | 24 +++++++++++++ .../default/kali/hydra/default_config.yaml | 12 +++++++ plugins/default/kali/hydra/hydra_plugin.py | 10 ------ plugins/default/kali/nmap/default_config.yaml | 0 plugins/default/kali/nmap/nmap_plugin.py | 8 ----- .../running_vm/default_config.yaml | 0 .../running_vm/running_vm_plugin.py | 1 + .../vm_controller/vagrant/default_config.yaml | 0 .../linux_sshd_config/default_config.yaml | 0 .../weak_user_passwords/default_config.yaml | 0 .../windows_rdp_config/default_config.yaml | 0 15 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 plugins/default/kali/hydra/default_config.yaml create mode 100644 plugins/default/kali/nmap/default_config.yaml create mode 100644 plugins/default/vm_controller/running_vm/default_config.yaml create mode 100644 plugins/default/vm_controller/vagrant/default_config.yaml create mode 100644 plugins/default/vulnerabilities/linux_sshd_config/default_config.yaml create mode 100644 plugins/default/vulnerabilities/weak_user_passwords/default_config.yaml create mode 100644 plugins/default/vulnerabilities/windows_rdp_config/default_config.yaml diff --git a/app/config.py b/app/config.py index b9ec369..1399a70 100644 --- a/app/config.py +++ b/app/config.py @@ -206,6 +206,8 @@ class ExperimentConfig(): res = self.raw_config["kali_conf"][attack] except KeyError as exception: raise ConfigurationError from exception + if res is None: + res = {} return res diff --git a/app/pluginmanager.py b/app/pluginmanager.py index 7d769df..140c516 100644 --- a/app/pluginmanager.py +++ b/app/pluginmanager.py @@ -12,6 +12,16 @@ from plugins.base.sensor import SensorPlugin from plugins.base.vulnerability_plugin import VulnerabilityPlugin # from app.interface_sfx import CommandlineColors +sections = [{"name": "Vulnerabilities", + "subclass": VulnerabilityPlugin}, + {"name": "Machinery", + "subclass": MachineryPlugin}, + {"name": "Kali", + "subclass": KaliPlugin}, + {"name": "Sensors", + "subclass": SensorPlugin}, + ] + class PluginManager(): """ Manage plugins """ @@ -55,16 +65,6 @@ class PluginManager(): def print_list(self): """ Print a pretty list of all available plugins """ - sections = [{"name": "Vulnerabilities", - "subclass": VulnerabilityPlugin}, - {"name": "Machinery", - "subclass": MachineryPlugin}, - {"name": "Kali", - "subclass": KaliPlugin}, - {"name": "Sensors", - "subclass": SensorPlugin}, - ] - for section in sections: print(f'\t\t{section["name"]}') plugins = self.get_plugins(section["subclass"]) @@ -72,3 +72,18 @@ class PluginManager(): print(f"Name: {plugin.get_name()}") print(f"Description: {plugin.get_description()}") print("\t") + + def print_default_config(self, subclass_name, name): + + subclass = None + + for a in sections: + if a["name"] == subclass_name: + subclass = a["subclass"] + if subclass is None: + print("Use proper subclass. Available subclasses are: ") + "\n- ".join([a for a in sections["name"]]) + + plugins = self.get_plugins(subclass, [name]) + for plugin in plugins: + print(plugin.get_raw_default_config()) diff --git a/plugin_manager.py b/plugin_manager.py index d98adcc..43d8119 100644 --- a/plugin_manager.py +++ b/plugin_manager.py @@ -6,10 +6,17 @@ from app.pluginmanager import PluginManager def list_plugins(arguments): + """ List plugins """ p = PluginManager() p.print_list() +def get_default_config(arguments): + """ print default config of a specific plugin """ + p = PluginManager() + p.print_default_config(arguments.subclass_name, arguments.plugin_name) + + def create_parser(): """ Creates the parser for the command line arguments""" @@ -17,9 +24,14 @@ def create_parser(): subparsers = main_parser.add_subparsers(help="sub-commands") # Sub parser for machine creation - parser_create = subparsers.add_parser("list", help="list plugins") - parser_create.set_defaults(func=list_plugins) - # parser_create.add_argument("--configfile", default="experiment.yaml", help="Config file to create from") + parser_list = subparsers.add_parser("list", help="list plugins") + parser_list.set_defaults(func=list_plugins) + # parser_list.add_argument("--configfile", default="experiment.yaml", help="Config file to create from") + + parser_default_config = subparsers.add_parser("raw_config", help="print raw default config of the given plugin") + parser_default_config.set_defaults(func=get_default_config) + parser_default_config.add_argument("subclass_name", help="name of the subclass") + parser_default_config.add_argument("plugin_name", help="name of the plugin") # TODO: Get default config return main_parser diff --git a/plugins/base/kali.py b/plugins/base/kali.py index e23dc39..52a8d01 100644 --- a/plugins/base/kali.py +++ b/plugins/base/kali.py @@ -23,6 +23,19 @@ class KaliPlugin(BasePlugin): self.sysconf = {} # System configuration. common for all plugins self.attack_logger = None + def process_config(self, config): + """ process config and use defaults if stuff is missing + + @param config: The config dict + """ + + # TODO: Move to python 3.9 syntax z = x | y + + self.conf = {**self.conf, **config} + + print("\n\n\n\n\n") + print(self.conf) + def teardown(self): """ Cleanup afterwards """ pass # pylint: disable=unnecessary-pass diff --git a/plugins/base/plugin_base.py b/plugins/base/plugin_base.py index b6e27a4..3fcdb59 100644 --- a/plugins/base/plugin_base.py +++ b/plugins/base/plugin_base.py @@ -2,6 +2,7 @@ """ Base class for all plugin types """ import os +import yaml # from shutil import copy @@ -18,6 +19,9 @@ class BasePlugin(): self.plugin_path = None self.machine_plugin = None self.sysconf = {} + self.conf = {} + + self.default_config_name = "default_config.yaml" def setup(self): """ Prepare everything for the plugin """ @@ -43,6 +47,7 @@ class BasePlugin(): self.sysconf["abs_machinepath_internal"] = config["abs_machinepath_internal"] self.sysconf["abs_machinepath_external"] = config["abs_machinepath_external"] + self.load_default_config() def copy_to_machine(self, filename): """ Copies a file shipped with the plugin to the machine share folder @@ -101,3 +106,22 @@ class BasePlugin(): return self.description raise NotImplementedError + + def get_default_config_filename(self): + """ Generate the default filename of the default configuration file """ + + return os.path.join(os.path.dirname(self.plugin_path), self.default_config_name) + + def get_raw_default_config(self): + """ Returns the default config as string. Usable as an example and for documentation """ + + with open(self.get_default_config_filename(), "rt") as fh: + return fh.read() + + def load_default_config(self): + """ Reads and returns the default config as dict """ + + with open(self.get_default_config_filename()) as fh: + self.conf = yaml.safe_load(fh) + if self.conf is None: + self.conf = {} diff --git a/plugins/default/kali/hydra/default_config.yaml b/plugins/default/kali/hydra/default_config.yaml new file mode 100644 index 0000000..1f5ac13 --- /dev/null +++ b/plugins/default/kali/hydra/default_config.yaml @@ -0,0 +1,12 @@ +### +# A list of protocols to brute force against. Supported: "ssh" +protocols: + - ssh + - rdp + #- ftps +### +# A file containing potential user names +userfile: users.txt +### +# A file containing potential passwords +pwdfile: passwords.txt \ No newline at end of file diff --git a/plugins/default/kali/hydra/hydra_plugin.py b/plugins/default/kali/hydra/hydra_plugin.py index eff5e85..cb2dabe 100644 --- a/plugins/default/kali/hydra/hydra_plugin.py +++ b/plugins/default/kali/hydra/hydra_plugin.py @@ -21,16 +21,6 @@ class HydraPlugin(KaliPlugin): # print("Init hydra") - def process_config(self, config): - """ process config and use defaults if stuff is missing - - @param config: The config dict - """ - # TODO Create kali specific config class, send this to the plugins - self.conf["protocols"] = config.get("protocols", ["ssh"]) - self.conf["userfile"] = config.get("userfile", "users.txt") - self.conf["pwdfile"] = config.get("pwdfile", "passwords.txt") - def command(self, targets, config): """ Generate the command (having a separate step assists on debugging) diff --git a/plugins/default/kali/nmap/default_config.yaml b/plugins/default/kali/nmap/default_config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/plugins/default/kali/nmap/nmap_plugin.py b/plugins/default/kali/nmap/nmap_plugin.py index 1f2f625..a3f5c71 100644 --- a/plugins/default/kali/nmap/nmap_plugin.py +++ b/plugins/default/kali/nmap/nmap_plugin.py @@ -51,14 +51,6 @@ class NmapPlugin(KaliPlugin): super().__init__() self.plugin_path = __file__ - def process_config(self, config): - """ process config and use defaults if stuff is missing - - @param config: The config dict - """ - # TODO Create kali specific config class, send this to the plugins - # TODO: NMap specific config should be added. So far we only have the basic scan - def command(self, targets, config): """ Generate the command (having a separate step assists on debugging) diff --git a/plugins/default/vm_controller/running_vm/default_config.yaml b/plugins/default/vm_controller/running_vm/default_config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/plugins/default/vm_controller/running_vm/running_vm_plugin.py b/plugins/default/vm_controller/running_vm/running_vm_plugin.py index cd079d0..67653af 100644 --- a/plugins/default/vm_controller/running_vm/running_vm_plugin.py +++ b/plugins/default/vm_controller/running_vm/running_vm_plugin.py @@ -31,6 +31,7 @@ class RunningVMPlugin(MachineryPlugin): """ Machine specific processing of configuration """ # TODO: Rename vagrantfilepath in the whole project + # TODO: Is this a copy&paste artefact ? self.vagrantfilepath = os.path.abspath(self.config.vagrantfilepath()) self.vagrantfile = os.path.join(self.vagrantfilepath, "Vagrantfile") if not os.path.isfile(self.vagrantfile): diff --git a/plugins/default/vm_controller/vagrant/default_config.yaml b/plugins/default/vm_controller/vagrant/default_config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/plugins/default/vulnerabilities/linux_sshd_config/default_config.yaml b/plugins/default/vulnerabilities/linux_sshd_config/default_config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/plugins/default/vulnerabilities/weak_user_passwords/default_config.yaml b/plugins/default/vulnerabilities/weak_user_passwords/default_config.yaml new file mode 100644 index 0000000..e69de29 diff --git a/plugins/default/vulnerabilities/windows_rdp_config/default_config.yaml b/plugins/default/vulnerabilities/windows_rdp_config/default_config.yaml new file mode 100644 index 0000000..e69de29