From 1c03ac4dcf646ae356734be8200a63f577e0b3d4 Mon Sep 17 00:00:00 2001 From: Thorsten Sick Date: Mon, 19 Apr 2021 10:28:49 +0200 Subject: [PATCH] Added plugins --- plugins/README.md | 39 ++++++++ plugins/default/kali/hydra/README.md | 1 + plugins/default/kali/hydra/hydra_plugin.py | 68 ++++++++++++++ plugins/default/kali/hydra/passwords.txt | 8 ++ plugins/default/kali/hydra/users.txt | 5 + plugins/default/kali/nmap/nmap_plugin.py | 79 ++++++++++++++++ .../linux_sshd_config_issues.py | 44 +++++++++ .../weak_user_passwords.py | 93 +++++++++++++++++++ .../windows_rdp_config/windows_rdp_config.py | 45 +++++++++ 9 files changed, 382 insertions(+) create mode 100644 plugins/README.md create mode 100644 plugins/default/kali/hydra/README.md create mode 100644 plugins/default/kali/hydra/hydra_plugin.py create mode 100644 plugins/default/kali/hydra/passwords.txt create mode 100644 plugins/default/kali/hydra/users.txt create mode 100644 plugins/default/kali/nmap/nmap_plugin.py create mode 100644 plugins/default/vulnerabilities/linux_sshd_config/linux_sshd_config_issues.py create mode 100644 plugins/default/vulnerabilities/weak_user_passwords/weak_user_passwords.py create mode 100644 plugins/default/vulnerabilities/windows_rdp_config/windows_rdp_config.py diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 0000000..6cea12b --- /dev/null +++ b/plugins/README.md @@ -0,0 +1,39 @@ +Plugin reasoning and planning. To be deleted later. + +Which parts to make into plugins +================================ + +* Everything that could be contributed by external people +* Very specialized features + +At the moment those are: + +* kali attacks +* sensors +* vm_controllers +* post_processors + + +Parts of a plugin +================= + +* Plugin specific configuration +* The plugin python code +* Additional files and tools to be used by the plugin + +Therefore: We need a specific folder for every plugin + +We want out own plugins plus external plugins to throw in. So we will have a default folder for plugins (ours) and additional folders with names chosen by external people. Plugins must be searched in those folders. + +Picking and loading plugins +=========================== + +* the experiment.yaml config specifies the plugins to use + +Found plugin interfaces +======================= + +https://github.com/ironfroggy/straight.plugin +https://github.com/tibonihoo/yapsy ( -: not maintained anymore, sourceforge) +https://github.com/pytest-dev/pluggy/ ( -: not maintained anymore; +: used by tox and similar) + diff --git a/plugins/default/kali/hydra/README.md b/plugins/default/kali/hydra/README.md new file mode 100644 index 0000000..9d655cd --- /dev/null +++ b/plugins/default/kali/hydra/README.md @@ -0,0 +1 @@ +The hydra plugin remote controls the hydra tool. Hydra is able to brute force a number of protocols. Where especially ssh is relevant. \ No newline at end of file diff --git a/plugins/default/kali/hydra/hydra_plugin.py b/plugins/default/kali/hydra/hydra_plugin.py new file mode 100644 index 0000000..eff5e85 --- /dev/null +++ b/plugins/default/kali/hydra/hydra_plugin.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +# A plugin for hydra bruteforce attacks + +from plugins.base.kali import KaliPlugin + + +class HydraPlugin(KaliPlugin): + + # Boilerplate + name = "hydra" + description = "A plugin controlling the hydra brute forcing tool" + ttp = "T1110" + references = ["https://attack.mitre.org/techniques/T1110/"] + + required_files = ["passwords.txt", "users.txt"] # Files shipped with the plugin which are needed by the kali tool. Will be copied to the kali share + + def __init__(self): + super().__init__() + self.plugin_path = __file__ + + # 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) + + @param targets: A list of targets, ip addresses will do + @param config: dict with command specific configuration + """ + + # Set defaults if not present in config + self.process_config(config) + playground = self.machine_plugin.get_playground() + + # Generate command + cmd = f"cd {playground};" + cmd += "sudo apt -y install hydra;" + for t in targets: + for p in self.conf['protocols']: + cmd += f"hydra -L {self.conf['userfile']} -P {self.conf['pwdfile']} {p}://{t};" + + return cmd + + def run(self, targets, config): + """ Run the command + + @param targets: A list of targets, ip addresses will do + @param config: dict with command specific configuration + """ + + # print("running hydra as plugin") + cmd = self.command(targets, config) + # res += str(self.run_cmd(cmd).stdout.strip()) + res = self.run_cmd(cmd) or "" + + # print("hydra done") + + return res diff --git a/plugins/default/kali/hydra/passwords.txt b/plugins/default/kali/hydra/passwords.txt new file mode 100644 index 0000000..2af5eee --- /dev/null +++ b/plugins/default/kali/hydra/passwords.txt @@ -0,0 +1,8 @@ +12345 +qwert +qwertz +qwerty +password +passw0rd +swordfish +test diff --git a/plugins/default/kali/hydra/users.txt b/plugins/default/kali/hydra/users.txt new file mode 100644 index 0000000..986ff7b --- /dev/null +++ b/plugins/default/kali/hydra/users.txt @@ -0,0 +1,5 @@ +test +root +password +nonexistend_user_1 +nonexistend_user_2 \ No newline at end of file diff --git a/plugins/default/kali/nmap/nmap_plugin.py b/plugins/default/kali/nmap/nmap_plugin.py new file mode 100644 index 0000000..45b464f --- /dev/null +++ b/plugins/default/kali/nmap/nmap_plugin.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +# A plugin to nmap targets + +from plugins.base.kali import KaliPlugin + + +# TODO All scan patterns need explicit logging into the attack log ! +# TODO: Add config for subnet range for ping sweeps +# TODO: Add IP exclusion --exclude ip,ip,ip to not accidentially scan non-targets +# TODO: host discovery Ping scan: -sn +# TODO: host discovery PE/PP/PM +# TODO: host discovery PS/PA/PU/PY +# TODO: host discovery reverse DNS resolution +# TODO OS identification +# TODO service discovery +# TODO stealth scans +# TODO firewall evasion +# TODO service fingerprinting +# TODO udp scans -sU +# TODO TCP SYN scan: -sS +# TODO TCP connect scan: -sT +# TODO port scan without prior ping (this is to avoid triggering firewall logic): -Pn + +class NmapPlugin(KaliPlugin): + + # Boilerplate + name = "nmap" + description = "NMap scan the target" + ttp = "T1595" + references = ["https://attack.mitre.org/techniques/T1595/"] + + required_files = [] # Files shipped with the plugin which are needed by the kali tool. Will be copied to the kali share + + def __init__(self): + 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) + + @param targets: A list of targets, ip addresses will do + @param config: dict with command specific configuration + """ + + # Set defaults if not present in config + self.process_config(config) + playground = self.machine_plugin.get_playground() + + # Generate command + cmd = f"cd {playground};" + # cmd += "sudo apt -y install nmap;" + for t in targets: + cmd += f"nmap {t};" + + return cmd + + def run(self, targets, config): + """ Run the command + + @param targets: A list of targets, ip addresses will do + @param config: dict with command specific configuration + """ + + res = "" + + cmd = self.command(targets, config) + + res += self.run_cmd(cmd) or "" + + return res diff --git a/plugins/default/vulnerabilities/linux_sshd_config/linux_sshd_config_issues.py b/plugins/default/vulnerabilities/linux_sshd_config/linux_sshd_config_issues.py new file mode 100644 index 0000000..c814ceb --- /dev/null +++ b/plugins/default/vulnerabilities/linux_sshd_config/linux_sshd_config_issues.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +# Some users are created (with weak passwords) and sshd is set to allow password-based access + +from plugins.base.vulnerability_plugin import VulnerabilityPlugin + + +class SshdVulnerability(VulnerabilityPlugin): + + # Boilerplate + name = "sshd_config_vul" + description = "Allowing passwords based sshd access" + ttp = "T1110" + references = ["https://attack.mitre.org/techniques/T1110/"] + + required_files = [] # Files shipped with the plugin which are needed by the machine. Will be copied to the share + + def __init__(self): + super().__init__() + self.plugin_path = __file__ + + def start(self): + + # allow password access via ssh + cmd = "sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config" + print(cmd) + self.run_cmd(cmd) + + # Restart ssh + cmd = "sudo service ssh restart" + print(cmd) + self.run_cmd(cmd) + + def stop(self): + + # Re-configure sshd to stable state + cmd = "sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config" + print(cmd) + self.run_cmd(cmd) + + # Restart ssh + cmd = "sudo service ssh restart" + print(cmd) + self.run_cmd(cmd) diff --git a/plugins/default/vulnerabilities/weak_user_passwords/weak_user_passwords.py b/plugins/default/vulnerabilities/weak_user_passwords/weak_user_passwords.py new file mode 100644 index 0000000..c238408 --- /dev/null +++ b/plugins/default/vulnerabilities/weak_user_passwords/weak_user_passwords.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 + +# Some users are created (with weak passwords) and sshd is set to allow password-based access + +from plugins.base.vulnerability_plugin import VulnerabilityPlugin + + +class WeakPasswordVulnerabilityVulnerability(VulnerabilityPlugin): + + # Boilerplate + name = "weak_user_passwords" + description = "Adding users with weak passwords" + ttp = "T1110" + references = ["https://attack.mitre.org/techniques/T1110/"] + + required_files = [] # Files shipped with the plugin which are needed by the machine. Will be copied to the share + + def __init__(self): + super().__init__() + self.plugin_path = __file__ + + def start(self): + + if self.machine_plugin.config.os() == "linux": + # Add vulnerable user + # mkpasswd -m sha-512 # To calc the passwd + # This is in the debian package "whois" + + # user with password "test" + cmd = "useradd -m -p '$6$bc4k4Tq2.1GW$0ysyuxyfyds2JkfVEf9xHy39MhpS.hhnAo4sBLprNfIHqcpaa9GJseRJJsrq0cSOWwYlOPrdHQNHp10E1ekO81' -s /bin/bash test" + print(cmd) + self.run_cmd(cmd) + + # user with password "passw0rd" + cmd = "useradd -m -p '$6$q5PAnDI5K0uv$hMGMJQleeS9F2yLOiHXs2PxZHEmV.ook8jyWILzDGDxSTJmTTZSe.QgLVrnuwiyAl5PFJVARkMsSnPICSndJR1' -s /bin/bash password" + print(cmd) + self.run_cmd(cmd) + elif self.machine_plugin.config.os() == "windows": + # net user username password /add + cmd = "net user test test /add" + print(cmd) + self.run_cmd(cmd) + + cmd = "net user password passw0rd /add" + print(cmd) + self.run_cmd(cmd) + + # Adding the new users to RDP (just in case we want to test RDP) + cmd = """NET LOCALGROUP "Remote Desktop Users" password /ADD""" + print(cmd) + self.run_cmd(cmd) + + cmd = """NET LOCALGROUP "Remote Desktop Users" test /ADD""" + print(cmd) + self.run_cmd(cmd) + + else: + raise NotImplementedError + + def stop(self): + + if self.machine_plugin.config.os() == "linux": + # Remove user + cmd = "sudo userdel -r test" + print(cmd) + self.run_cmd(cmd) + + # Remove user + cmd = "sudo userdel -r password" + print(cmd) + self.run_cmd(cmd) + elif self.machine_plugin.config.os() == "windows": + # net user username /delete + + cmd = "net user test /delete" + print(cmd) + self.run_cmd(cmd) + + cmd = "net user password /delete" + print(cmd) + self.run_cmd(cmd) + + # Remove the new users to RDP (just in case we want to test RDP) + cmd = """NET LOCALGROUP "Remote Desktop Users" password /DELETE""" + print(cmd) + self.run_cmd(cmd) + + cmd = """NET LOCALGROUP "Remote Desktop Users" test /DELETE""" + print(cmd) + self.run_cmd(cmd) + + else: + raise NotImplementedError diff --git a/plugins/default/vulnerabilities/windows_rdp_config/windows_rdp_config.py b/plugins/default/vulnerabilities/windows_rdp_config/windows_rdp_config.py new file mode 100644 index 0000000..ecf7e4f --- /dev/null +++ b/plugins/default/vulnerabilities/windows_rdp_config/windows_rdp_config.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Enable RDP for users +# https://pureinfotech.com/enable-remote-desktop-command-prompt-windows-10/ + +from plugins.base.vulnerability_plugin import VulnerabilityPlugin + + +class RDPVulnerability(VulnerabilityPlugin): + + # Boilerplate + name = "rdp_config_vul" + description = "Allowing rdp access" + ttp = "T1110" + references = ["https://attack.mitre.org/techniques/T1110/"] + + required_files = [] # Files shipped with the plugin which are needed by the machine. Will be copied to the share + + def __init__(self): + super().__init__() + self.plugin_path = __file__ + + def start(self): + + # allow password access via rdp + cmd = r"""reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f""" + print(cmd) + self.run_cmd(cmd) + + # Open Firewall + cmd = """netsh advfirewall firewall set rule group="remote desktop" new enable=Yes""" + print(cmd) + self.run_cmd(cmd) + + def stop(self): + + # Re-configure sshd to stable state + cmd = r"""reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 1 /f""" + print(cmd) + self.run_cmd(cmd) + + # Reset firewall + cmd = """netsh advfirewall firewall set rule group="remote desktop" new enable=No""" + print(cmd) + self.run_cmd(cmd)