Full unit test coverage for config.py

pull/3/head
Thorsten Sick 3 years ago
parent 3bac1d862d
commit 4f62301b6e

@ -151,6 +151,9 @@ class ExperimentConfig():
self._attackers = []
self.load(configfile)
# Test essential data that is a hard requirement. Should throw errors if anything is wrong
self.loot_dir()
def load(self, configfile):
""" Loads the configuration file
@ -194,7 +197,13 @@ class ExperimentConfig():
def loot_dir(self):
""" Returns the loot dir """
return self.raw_config["results"]["loot_dir"]
if "results" not in self.raw_config or self.raw_config["results"] is None:
raise ConfigurationError("results missing in configuration")
try:
res = self.raw_config["results"]["loot_dir"]
except KeyError:
raise ConfigurationError("results/loot_dir not properly set in configuration")
return res
def kali_conf(self, attack):
""" Get kali config for a specific kali attack
@ -274,5 +283,9 @@ class ExperimentConfig():
"""
if "sensors" not in self.raw_config:
return {}
if name not in self.raw_config["sensors"]:
if self.raw_config["sensors"] is None: # Better for unit tests that way.
return {}
if name in self.raw_config["sensors"]:
return self.raw_config["sensors"][name]
return {}

@ -78,8 +78,9 @@ class BasePlugin():
@param config: A dict with system configuration relevant for all plugins
"""
self.sysconf["abs_machinepath_internal"] = config["abs_machinepath_internal"]
self.sysconf["abs_machinepath_external"] = config["abs_machinepath_external"]
# TODO: Verify if it works properly. It should wotk thanks to the new design
# self.sysconf["abs_machinepath_internal"] = config["abs_machinepath_internal"]
# self.sysconf["abs_machinepath_external"] = config["abs_machinepath_external"]
self.load_default_config()
def process_config(self, config):

@ -16,8 +16,6 @@ class RunningVMPlugin(SSHFeatures, MachineryPlugin):
def __init__(self):
super().__init__()
# super(SSHFeatures).__init__()
# super(MachineryPlugin).__init__()
self.plugin_path = __file__
self.vagrantfilepath = None
self.vagrantfile = None

@ -91,21 +91,6 @@ class VagrantPlugin(SSHFeatures, MachineryPlugin):
else:
return super().connect()
# if self.config.os() == "linux":
# super
# if self.config.os() == "windows":
# args = {"key_filename": os.path.join(self.sysconf["abs_machinepath_external"], self.config.ssh_keyfile())}
# if self.config.ssh_password():
# args["password"] = self.config.ssh_password()
# uhp = self.get_ip()
# print(uhp)
# print(args)
# print(self.config.ssh_user())
# self.c = Connection(uhp, user=self.config.ssh_user(), connect_kwargs=args)
# print(self.c)
# return self.c
def get_state(self):
""" Get detailed state of a machine """
@ -127,20 +112,6 @@ class VagrantPlugin(SSHFeatures, MachineryPlugin):
def get_ip(self):
""" Return the machine ip """
# TODO: Create special code to extract windows IPs
# TODO: Find a smarter way to get the ip
# ips = []
# cmd = "ifconfig"
# res = self.vm_manager.__call_remote_run__(cmd)
# for line in res.split("\n"):
# m = re.match(r".*inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*", line)
# if m:
# print(m.group(1))
# ips.append(m.group(1))
filename = os.path.join(self.sysconf["abs_machinepath_external"], "ip4.txt")
filename = os.path.join(self.get_machine_path_external(), "ip4.txt")
with open(filename, "rt") as fh:
return fh.readline().strip()

@ -137,6 +137,8 @@ kali_conf:
###
# A file containing potential passwords
pwdfile: passwords.txt
missing:
# intentionally left blank
###
# Settings for the results being harvested
@ -144,3 +146,7 @@ results:
###
# The directory the loot will be in
loot_dir: loot
###
# General sensor config config
# sensors:

@ -146,4 +146,19 @@ kali_conf:
results:
###
# The directory the loot will be in
loot_dir: loot
loot_dir: loot
###
# General sensor config config
sensors:
###
# Windows sensor plugin configuration
windows_sensor:
###
# Name of the dll to use. Must match AV version
# dll_name: aswidptestdll.dll
dll_name: windows_sensor.dll
###
# Folder where the sensor tool is located
sensor_tool_folder: windows_sensor

@ -0,0 +1,155 @@
###
# Caldera configuration
caldera:
###
# API key for caldera. See caldera configuration. Default is ADMIN123
apikey: ADMIN123
###
# Attacks configuration
attackers:
###
# Configuration for the first attacker. One should normally be enough
attacker:
###
# Defining VM controller settings for this machine
vm_controller:
###
# Type of the VM controller, Options are "vagrant"
type: vagrant
###
# # path where the vagrantfile is in
vagrantfilepath: systems
###
# Name of machine in Vagrantfile
vm_name: attacker
###
# machinepath is a path where the machine specific files and logs are stored. Relative to the Vagrantfile path
# and will be mounted internally as /vagrant/<name>
# If machinepoath is not set AttackX will try "vm_name"
machinepath: attacker1
###
# OS of the VM guest. Options are so far "windows", "linux"
os: linux
###
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# List of targets
targets:
###
# Specific target
target1:
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target1
os: linux
###
# Targets need a unique PAW name for caldera
paw: target1
###
# Targets need to be in a group for caldera
group: red
machinepath: target1
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
target2:
#root: systems/target1
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target2
os: windows
paw: target2w
group: red
machinepath: target2w
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# Optional setting to activate force when halting the machine. Windows guests sometime get stuck
halt_needs_force: yes
###
# If SSH without vagrant support is used (Windows !) we need a user name (uppercase)
ssh_user: ATTACKX
###
# For non-vagrant ssh connections a ssh keyfile stored in the machinepath is required.
ssh_keyfile: id_rsa.3
###
# General attack config
attacks:
###
# configure the seconds the system idles between the attacks. Makes it slower. But attack and defense logs will be simpler to match
nap_time: 5
###
# A list of caldera attacks to run against the targets.
caldera_attacks:
###
# Linux specific attacks. A list of caldera ability IDs
linux:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Windows specific attacks. A list of caldera ability IDs
windows:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Kali tool based attacks. Will result in kali commandline tools to be called. Currently supported are: "hydra"
kali_attacks:
###
# Linux specific attacks, a list
linux:
- hydra
###
# Windows specific attacks, a list
windows:
- hydra
###
# Configuration for the kali attack tools
kali_conf:
###
# Hydra configuration
hydra:
###
# A list of protocols to brute force against. Supported: "ssh"
protocols:
- ssh
#- ftp
#- ftps
###
# A file containing potential user names
userfile: users.txt
###
# A file containing potential passwords
pwdfile: passwords.txt
###
# Settings for the results being harvested
results:
###
# The directory the loot will be in
loot_dir: loot
###
# General sensor config config
sensors:
foo:

@ -0,0 +1,149 @@
###
# Caldera configuration
caldera:
###
# API key for caldera. See caldera configuration. Default is ADMIN123
apikey: ADMIN123
###
# Attacks configuration
attackers:
###
# Configuration for the first attacker. One should normally be enough
attacker:
###
# Defining VM controller settings for this machine
vm_controller:
###
# Type of the VM controller, Options are "vagrant"
type: vagrant
###
# # path where the vagrantfile is in
vagrantfilepath: systems
###
# Name of machine in Vagrantfile
vm_name: attacker
###
# machinepath is a path where the machine specific files and logs are stored. Relative to the Vagrantfile path
# and will be mounted internally as /vagrant/<name>
# If machinepoath is not set AttackX will try "vm_name"
machinepath: attacker1
###
# OS of the VM guest. Options are so far "windows", "linux"
os: linux
###
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# List of targets
targets:
###
# Specific target
target1:
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target1
os: linux
###
# Targets need a unique PAW name for caldera
paw: target1
###
# Targets need to be in a group for caldera
group: red
machinepath: target1
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
target2:
#root: systems/target1
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target2
os: windows
paw: target2w
group: red
machinepath: target2w
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# Optional setting to activate force when halting the machine. Windows guests sometime get stuck
halt_needs_force: yes
###
# If SSH without vagrant support is used (Windows !) we need a user name (uppercase)
ssh_user: ATTACKX
###
# For non-vagrant ssh connections a ssh keyfile stored in the machinepath is required.
ssh_keyfile: id_rsa.3
###
# General attack config
attacks:
###
# configure the seconds the system idles between the attacks. Makes it slower. But attack and defense logs will be simpler to match
nap_time: 5
###
# A list of caldera attacks to run against the targets.
caldera_attacks:
###
# Linux specific attacks. A list of caldera ability IDs
linux:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Windows specific attacks. A list of caldera ability IDs
windows:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Kali tool based attacks. Will result in kali commandline tools to be called. Currently supported are: "hydra"
kali_attacks:
###
# Linux specific attacks, a list
linux:
- hydra
###
# Windows specific attacks, a list
windows:
- hydra
###
# Configuration for the kali attack tools
kali_conf:
###
# Hydra configuration
hydra:
###
# A list of protocols to brute force against. Supported: "ssh"
protocols:
- ssh
#- ftp
#- ftps
###
# A file containing potential user names
userfile: users.txt
###
# A file containing potential passwords
pwdfile: passwords.txt
###
# Settings for the results being harvested
results:
###
# The directory the loot will be in
fake_loot_dir: loot

@ -0,0 +1,149 @@
###
# Caldera configuration
caldera:
###
# API key for caldera. See caldera configuration. Default is ADMIN123
apikey: ADMIN123
###
# Attacks configuration
attackers:
###
# Configuration for the first attacker. One should normally be enough
attacker:
###
# Defining VM controller settings for this machine
vm_controller:
###
# Type of the VM controller, Options are "vagrant"
type: vagrant
###
# # path where the vagrantfile is in
vagrantfilepath: systems
###
# Name of machine in Vagrantfile
vm_name: attacker
###
# machinepath is a path where the machine specific files and logs are stored. Relative to the Vagrantfile path
# and will be mounted internally as /vagrant/<name>
# If machinepoath is not set AttackX will try "vm_name"
machinepath: attacker1
###
# OS of the VM guest. Options are so far "windows", "linux"
os: linux
###
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# List of targets
targets:
###
# Specific target
target1:
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target1
os: linux
###
# Targets need a unique PAW name for caldera
paw: target1
###
# Targets need to be in a group for caldera
group: red
machinepath: target1
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
target2:
#root: systems/target1
vm_controller:
type: vagrant
vagrantfilepath: systems
vm_name: target2
os: windows
paw: target2w
group: red
machinepath: target2w
# Do not destroy/create the machine: Set this to "yes".
use_existing_machine: yes
###
# Optional setting to activate force when halting the machine. Windows guests sometime get stuck
halt_needs_force: yes
###
# If SSH without vagrant support is used (Windows !) we need a user name (uppercase)
ssh_user: ATTACKX
###
# For non-vagrant ssh connections a ssh keyfile stored in the machinepath is required.
ssh_keyfile: id_rsa.3
###
# General attack config
attacks:
###
# configure the seconds the system idles between the attacks. Makes it slower. But attack and defense logs will be simpler to match
nap_time: 5
###
# A list of caldera attacks to run against the targets.
caldera_attacks:
###
# Linux specific attacks. A list of caldera ability IDs
linux:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Windows specific attacks. A list of caldera ability IDs
windows:
- "bd527b63-9f9e-46e0-9816-b8434d2b8989"
###
# Kali tool based attacks. Will result in kali commandline tools to be called. Currently supported are: "hydra"
kali_attacks:
###
# Linux specific attacks, a list
linux:
- hydra
###
# Windows specific attacks, a list
windows:
- hydra
###
# Configuration for the kali attack tools
kali_conf:
###
# Hydra configuration
hydra:
###
# A list of protocols to brute force against. Supported: "ssh"
protocols:
- ssh
#- ftp
#- ftps
###
# A file containing potential user names
userfile: users.txt
###
# A file containing potential passwords
pwdfile: passwords.txt
###
# Settings for the results being harvested
#results:
###
# The directory the loot will be in
# loot_dir: loot

@ -511,6 +511,24 @@ class TestExperimentConfig(unittest.TestCase):
self.assertEqual(ex.raw_config["caldera"]["apikey"], "ADMIN123")
self.assertEqual(ex.caldera_apikey(), "ADMIN123")
def test_loot_dir(self):
""" Test with existing loot dir """
ex = ExperimentConfig("tests/data/basic.yaml")
self.assertEqual(ex.loot_dir(), "loot")
def test_missing_loot_dir(self):
""" Test with missing loot dir """
with self.assertRaises(ConfigurationError):
ExperimentConfig("tests/data/basic_loot_missing.yaml")
def test_missing_results(self):
""" Test with missing results """
with self.assertRaises(ConfigurationError):
ExperimentConfig("tests/data/basic_results_missing.yaml")
def test_basic_loading_targets_read(self):
""" Targets in config: can be found """
ex = ExperimentConfig("tests/data/basic.yaml")
@ -542,6 +560,14 @@ class TestExperimentConfig(unittest.TestCase):
data = ex.kali_conf("hydra")
self.assertEqual(data["userfile"], "users.txt")
def test_kali_config_missing_attack_data(self):
""" Getting kali config for a specific attack: Missing """
ex = ExperimentConfig("tests/data/attacks_missing.yaml")
data = ex.kali_conf("missing")
self.assertEqual(data, {})
def test_missing_caldera_config_obfuscator(self):
""" A config file with no caldera config at all """
@ -664,6 +690,34 @@ class TestExperimentConfig(unittest.TestCase):
self.assertEqual(ex.get_caldera_attacks("windows"), ["bd527b63-9f9e-46e0-9816-b8434d2b8989", "foo", "bar"])
def test_basic_sensor_config(self):
""" Test global configuration for a specific sensor """
ex = ExperimentConfig("tests/data/basic.yaml")
self.assertEqual(ex.get_sensor_config("windows_sensor"), {"dll_name": "windows_sensor.dll", "sensor_tool_folder": "windows_sensor"})
def test_basic_sensor_config_missing(self):
""" Test global configuration for a specific and missing sensor """
ex = ExperimentConfig("tests/data/basic.yaml")
self.assertEqual(ex.get_sensor_config("missing_windows_sensor"), {})
def test_basic_sensor_entry_missing(self):
""" Test global configuration for a specific and missing sensor entry"""
ex = ExperimentConfig("tests/data/attacks_missing.yaml")
self.assertEqual(ex.get_sensor_config("windows_sensor"), {})
def test_basic_sensor_entry_empty(self):
""" Test global configuration for a specific and empty sensor entry"""
ex = ExperimentConfig("tests/data/basic_empty_sensor.yaml")
self.assertEqual(ex.get_sensor_config("windows_sensor"), {})
if __name__ == '__main__':
unittest.main()

Loading…
Cancel
Save