|
|
|
@ -67,11 +67,14 @@ class Experiment():
|
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
|
# Maybe the machine just does not exist yet
|
|
|
|
|
pass
|
|
|
|
|
target_1.install_caldera_service()
|
|
|
|
|
if self.machine_needs_caldera(target_1, caldera_attacks):
|
|
|
|
|
target_1.install_caldera_service()
|
|
|
|
|
target_1.up()
|
|
|
|
|
needs_reboot = target_1.prime_vulnerabilities()
|
|
|
|
|
needs_reboot |= target_1.prime_sensors()
|
|
|
|
|
if needs_reboot:
|
|
|
|
|
self.attack_logger.vprint(
|
|
|
|
|
f"{CommandlineColors.OKBLUE}rebooting target {tname} ....{CommandlineColors.ENDC}", 1)
|
|
|
|
|
target_1.reboot()
|
|
|
|
|
self.attack_logger.vprint(f"{CommandlineColors.OKGREEN}Target is up: {tname} {CommandlineColors.ENDC}", 1)
|
|
|
|
|
self.targets.append(target_1)
|
|
|
|
@ -89,10 +92,15 @@ class Experiment():
|
|
|
|
|
a_target.start_sensors()
|
|
|
|
|
|
|
|
|
|
# First start of caldera implants
|
|
|
|
|
at_least_one_caldera_started = False
|
|
|
|
|
for target_1 in self.targets:
|
|
|
|
|
target_1.start_caldera_client()
|
|
|
|
|
self.attack_logger.vprint(f"{CommandlineColors.OKGREEN}Initial start of caldera client: {tname} {CommandlineColors.ENDC}", 1)
|
|
|
|
|
time.sleep(20) # Wait for all the clients to contact the caldera server
|
|
|
|
|
if self.machine_needs_caldera(target_1, caldera_attacks):
|
|
|
|
|
target_1.start_caldera_client()
|
|
|
|
|
self.attack_logger.vprint(f"{CommandlineColors.OKGREEN}Initial start of caldera client: {tname} {CommandlineColors.ENDC}", 1)
|
|
|
|
|
else:
|
|
|
|
|
at_least_one_caldera_started = True
|
|
|
|
|
if at_least_one_caldera_started:
|
|
|
|
|
time.sleep(20) # Wait for all the clients to contact the caldera server
|
|
|
|
|
# TODO: Smarter wait
|
|
|
|
|
|
|
|
|
|
self.attack_logger.vprint(f"{CommandlineColors.OKBLUE}Contacting caldera agents on all targets ....{CommandlineColors.ENDC}", 1)
|
|
|
|
@ -101,6 +109,9 @@ class Experiment():
|
|
|
|
|
running_agents = self.caldera_control.list_paws_of_running_agents()
|
|
|
|
|
self.attack_logger.vprint(f"Agents currently running: {running_agents}", 2)
|
|
|
|
|
while target_1.get_paw() not in running_agents:
|
|
|
|
|
if self.machine_needs_caldera(target_1, caldera_attacks) == 0:
|
|
|
|
|
self.attack_logger.vprint(f"No caldera agent needed for: {target_1.get_paw()} ", 3)
|
|
|
|
|
break
|
|
|
|
|
self.attack_logger.vprint(f"Connecting to caldera {caldera_url}, running agents are: {running_agents}", 3)
|
|
|
|
|
self.attack_logger.vprint(f"Missing agent: {target_1.get_paw()} ...", 3)
|
|
|
|
|
target_1.start_caldera_client()
|
|
|
|
@ -124,9 +135,11 @@ class Experiment():
|
|
|
|
|
for target_1 in self.targets:
|
|
|
|
|
if caldera_attacks is None:
|
|
|
|
|
# Run caldera attacks
|
|
|
|
|
caldera_attacks = self.experiment_config.get_caldera_attacks(target_1.get_os())
|
|
|
|
|
if caldera_attacks:
|
|
|
|
|
for attack in caldera_attacks:
|
|
|
|
|
new_caldera_attacks = self.experiment_config.get_caldera_attacks(target_1.get_os())
|
|
|
|
|
else:
|
|
|
|
|
new_caldera_attacks = caldera_attacks
|
|
|
|
|
if new_caldera_attacks:
|
|
|
|
|
for attack in new_caldera_attacks:
|
|
|
|
|
# TODO: Work with snapshots
|
|
|
|
|
# TODO: If we have several targets in the same group, it is nonsense to attack each one separately. Make this smarter
|
|
|
|
|
self.attack_logger.vprint(f"Attacking machine with PAW: {target_1.get_paw()} with {attack}", 2)
|
|
|
|
@ -150,6 +163,9 @@ class Experiment():
|
|
|
|
|
time.sleep(self.experiment_config.get_nap_time())
|
|
|
|
|
retries = 100
|
|
|
|
|
for target_system in self.targets:
|
|
|
|
|
if self.machine_needs_caldera(target_system, caldera_attacks) == 0:
|
|
|
|
|
self.attack_logger.vprint(f"No caldera agent needed for: {target_system.get_paw()} ", 3)
|
|
|
|
|
continue
|
|
|
|
|
running_agents = self.caldera_control.list_paws_of_running_agents()
|
|
|
|
|
self.attack_logger.vprint(f"Agents currently connected to the server: {running_agents}", 2)
|
|
|
|
|
while target_system.get_paw() not in running_agents:
|
|
|
|
@ -168,6 +184,8 @@ class Experiment():
|
|
|
|
|
self.attack_logger.vprint(f"{CommandlineColors.OKBLUE}Running attack plugins{CommandlineColors.ENDC}", 1)
|
|
|
|
|
for target_1 in self.targets:
|
|
|
|
|
plugin_based_attacks = self.experiment_config.get_plugin_based_attacks(target_1.get_os())
|
|
|
|
|
metasploit_plugins = self.plugin_manager.count_caldera_requirements(AttackPlugin, plugin_based_attacks)
|
|
|
|
|
print(f"Plugins needing metasploit for {target_1.get_paw()} : {metasploit_plugins}")
|
|
|
|
|
for attack in plugin_based_attacks:
|
|
|
|
|
# TODO: Work with snapshots
|
|
|
|
|
self.attack_logger.vprint(f"Attacking machine with PAW: {target_1.get_paw()} with attack: {attack}", 1)
|
|
|
|
@ -205,6 +223,21 @@ class Experiment():
|
|
|
|
|
zip_this += dg.get_outfile_paths()
|
|
|
|
|
self.zip_loot(zip_this)
|
|
|
|
|
|
|
|
|
|
def machine_needs_caldera(self, target, caldera_conf):
|
|
|
|
|
""" Counts the attacks and plugins needing caldera that are registered for this machine """
|
|
|
|
|
|
|
|
|
|
c_cmdline = 0
|
|
|
|
|
if caldera_conf is not None:
|
|
|
|
|
c_cmdline = len(caldera_conf)
|
|
|
|
|
c_conffile = len(self.experiment_config.get_caldera_attacks(target.get_os()))
|
|
|
|
|
plugin_based_attacks = self.experiment_config.get_plugin_based_attacks(target.get_os())
|
|
|
|
|
c_plugins = self.plugin_manager.count_caldera_requirements(AttackPlugin, plugin_based_attacks)
|
|
|
|
|
|
|
|
|
|
print(f"Caldera count: From cmdline: {c_cmdline}, From conf: {c_conffile} from plugins: {c_plugins}")
|
|
|
|
|
|
|
|
|
|
return c_cmdline + c_conffile + c_plugins
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def attack(self, target, attack):
|
|
|
|
|
""" Pick an attack and run it
|
|
|
|
|
|
|
|
|
@ -222,6 +255,7 @@ class Experiment():
|
|
|
|
|
plugin.set_sysconf({})
|
|
|
|
|
plugin.set_logger(self.attack_logger)
|
|
|
|
|
plugin.set_caldera(self.caldera_control)
|
|
|
|
|
plugin.connect_metasploit()
|
|
|
|
|
plugin.install()
|
|
|
|
|
|
|
|
|
|
# plugin.__set_logger__(self.attack_logger)
|
|
|
|
|