Firsts step in plugin streamlining

pull/3/head
Thorsten Sick 3 years ago
parent baf2515c60
commit b2a65566b9

@ -173,7 +173,7 @@ class Machine():
for plugin in self.plugin_manager.get_plugins(MachineryPlugin, [self.config.vmcontroller()]):
name = plugin.get_name()
print(f"{CommandlineColors.OKBLUE}Installing sensor: {name}{CommandlineColors.ENDC}")
print(f"{CommandlineColors.OKBLUE}Installing machinery: {name}{CommandlineColors.ENDC}")
syscon = {"abs_machinepath_internal": self.abs_machinepath_internal,
"abs_machinepath_external": self.abs_machinepath_external}
@ -197,10 +197,10 @@ class Machine():
print(f"{CommandlineColors.OKBLUE}Priming sensor: {name}{CommandlineColors.ENDC}")
syscon = {"abs_machinepath_internal": self.abs_machinepath_internal,
"abs_machinepath_external": self.abs_machinepath_external,
"sensor_specific": self.config.raw_config.get(name, {})
}
plugin.set_sysconf(syscon)
plugin.set_machine_plugin(self.vm_manager)
plugin.process_config(self.config.raw_config.get(name, {})) # plugin specific configuration
plugin.setup()
reboot |= plugin.prime()
self.sensors.append(plugin)
@ -220,9 +220,10 @@ class Machine():
print(f"{CommandlineColors.OKBLUE}Installing sensor: {name}{CommandlineColors.ENDC}")
syscon = {"abs_machinepath_internal": self.abs_machinepath_internal,
"abs_machinepath_external": self.abs_machinepath_external,
"sensor_specific": self.config.raw_config.get(name, {})}
}
plugin.set_sysconf(syscon)
plugin.set_machine_plugin(self.vm_manager)
plugin.process_config(self.config.raw_config.get(name, {})) # plugin specific configuration
plugin.setup()
plugin.install()
print(f"{CommandlineColors.OKGREEN}Installed sensor: {name}{CommandlineColors.ENDC}")
@ -289,12 +290,13 @@ class Machine():
syscon = {"abs_machinepath_internal": self.abs_machinepath_internal,
"abs_machinepath_external": self.abs_machinepath_external}
plugin.set_sysconf(syscon)
plugin.process_config({}) # process plugin specific config
plugin.set_machine_plugin(self.vm_manager)
plugin.setup()
plugin.install(self.vm_manager)
self.vulnerabilities.append(plugin)
def get_vulnerabilities(self) -> [SensorPlugin]:
def get_vulnerabilities(self) -> [VulnerabilityPlugin]:
""" Returns a list of installed vulnerabilities """
return self.vulnerabilities

@ -23,19 +23,6 @@ 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

@ -38,13 +38,6 @@ class MachineryPlugin(BasePlugin):
self.connection = None # Connection
self.config = None
def process_config(self, config: MachineConfig):
""" Machine specific processing of configuration
@param config: configuration to do additional processing on
"""
raise NotImplementedError
def create(self, reboot=True):
""" Create a machine
@ -132,7 +125,7 @@ class MachineryPlugin(BasePlugin):
# print("===========> Processing config")
self.config = config
self.process_config(config)
self.process_config(config.raw_config)
def __call_remote_run__(self, cmd, disown=False):
""" Simplifies connect and run

@ -7,6 +7,7 @@ import yaml
# TODO: Proper planning and re-building of plugin system. Especially the default config handling should be streamlined. All the plugin types should have a very similar programming interface.
class BasePlugin():
""" Base class for plugins """
@ -50,6 +51,19 @@ class BasePlugin():
self.sysconf["abs_machinepath_external"] = config["abs_machinepath_external"]
self.load_default_config()
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 BASE plugin")
print(self.conf)
def copy_to_machine(self, filename):
""" Copies a file shipped with the plugin to the machine share folder
@ -116,13 +130,19 @@ class BasePlugin():
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()
if os.path.isfile(self.get_default_config_filename()):
with open(self.get_default_config_filename(), "rt") as fh:
return fh.read()
else:
return f"# The plugin {self.get_name()} does not support configuration"
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:
if not os.path.isfile(self.get_default_config_filename()):
self.conf = {}
else:
with open(self.get_default_config_filename()) as fh:
self.conf = yaml.safe_load(fh)
if self.conf is None:
self.conf = {}

@ -28,7 +28,6 @@ class SensorPlugin(BasePlugin):
"""
super().set_sysconf(config)
self.sysconf["sensor_specific"] = config["sensor_specific"]
def prime(self):
""" prime sets hard core configs in the target. You can use it to call everything that permanently alters the OS by settings.

@ -36,6 +36,16 @@ from plugins.base.kali import KaliPlugin
# TODO -sT tcp connect scan - needs no special permissions
# TODO. -p- scan all ports
# TODO: -p <range> scan port rance
# TODO: -sS -A (aggressive scanning, will also connect to services, run script and detect vulnerabilities like anonymous FTP accounts)
# TODO: --reason: Additional info. I do not think the web traffic will change. So I do not think this is important
# TODO: -F fast scan (fewer ports than default scan)
# TODO: -oX -oG output as XML or grepable. If we want to process the results that could be handy
# TODO: -sN NULL scan, no bits are set
# TODO: -sF FIN scan: FIN bit is set
# TODO: -sX Xmas scan: FIN, PSH and URG flag set
# TODO firewall evasion : -sS and -f for fragmented. old tech. But good for basic NDS tests
# TODO decoy scan: -D RND:5 to generate 5 decoys
# TODO spoof mac: --spoof-mac with 0, Apple, Dell, Cisco or fake MAC the first parameters in this list will generate random mac
class NmapPlugin(KaliPlugin):

@ -2,10 +2,9 @@
# A plugin to control already running vms
import os
from plugins.base.machinery import MachineryPlugin, MachineStates
from fabric import Connection
from app.exceptions import ConfigurationError, NetworkError
from app.exceptions import NetworkError
from invoke.exceptions import UnexpectedExit
import paramiko
import time
@ -27,16 +26,6 @@ class RunningVMPlugin(MachineryPlugin):
self.vagrantfilepath = None
self.vagrantfile = None
def process_config(self, config):
""" 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):
raise ConfigurationError(f"Vagrantfile not existing: {self.vagrantfile}")
def create(self, reboot=True):
""" Create a machine

@ -33,6 +33,7 @@ class VagrantPlugin(MachineryPlugin):
def process_config(self, config):
""" Machine specific processing of configuration """
super().process_config(config)
self.vagrantfilepath = os.path.abspath(self.config.vagrantfilepath())
self.vagrantfile = os.path.join(self.vagrantfilepath, "Vagrantfile")

@ -26,33 +26,24 @@ class WeakPasswordVulnerabilityVulnerability(VulnerabilityPlugin):
# 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)
for user in self.conf["linux"]:
cmd = f"sudo useradd -m -p '{user['password']}' -s /bin/bash {user['name']}"
print(cmd)
self.run_cmd(cmd)
cmd = "net user password passw0rd /add"
print(cmd)
self.run_cmd(cmd)
elif self.machine_plugin.config.os() == "windows":
# 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)
for user in self.conf["windows"]:
# net user username password /add
cmd = f"net user {user['name']} {user['password']} /add"
print(cmd)
self.run_cmd(cmd)
cmd = """NET LOCALGROUP "Remote Desktop Users" test /ADD"""
print(cmd)
self.run_cmd(cmd)
for user in self.conf["windows"]:
# Adding the new users to RDP (just in case we want to test RDP)
cmd = f"""NET LOCALGROUP "Remote Desktop Users" {user['name']} /ADD"""
print(cmd)
self.run_cmd(cmd)
else:
raise NotImplementedError
@ -60,34 +51,25 @@ class WeakPasswordVulnerabilityVulnerability(VulnerabilityPlugin):
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
for user in self.conf["linux"]:
# Remove user
cmd = f"sudo userdel -r {user['name']}"
print(cmd)
self.run_cmd(cmd)
cmd = "net user test /delete"
print(cmd)
self.run_cmd(cmd)
cmd = "net user password /delete"
print(cmd)
self.run_cmd(cmd)
elif self.machine_plugin.config.os() == "windows":
for user in self.conf["windows"]:
# net user username /delete
cmd = f"net user {user['name']} /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)
for user in self.conf["windows"]:
# net user username /delete
cmd = f""""NET LOCALGROUP "Remote Desktop Users" {user['name']} /DELETE"""
print(cmd)
self.run_cmd(cmd)
else:
raise NotImplementedError

Loading…
Cancel
Save