Example #1
0
    def __init__(
            self,
            victim: ChainImage,
            normal: ChainImage,
            exploit: ChainImage,
            wait_times,
            warmup_time=60,
            recording_time=300,
            exploit_start_time=0,
            storage_services: List[CollectorStorageService] = None
    ):
        """
        initialize all time sequences needed for the recording process
        as well es for statistically relevant execution
        """
        self.general_meta = ScenarioMeta(exploit_start_time, warmup_time, recording_time)
        self.logger = log.get_logger("control_script", ScenarioEnvironment().logging_queue)
        self.logging_thread = Thread(target=log.print_logs)
        self.logging_thread.start()

        self.storage_services = storage_services if storage_services else []

        self.victim = ScenarioVictim(victim)
        self.normal = ScenarioNormal(normal, wait_times)
        self.exploit = ScenarioAttacker(exploit)

        Collector().set_meta(
            name=self.general_meta.name,
            image=victim.name, recording_time=self.general_meta.recording_time,
            is_exploit=self.general_meta.is_exploit)
Example #2
0
def optimize_attack_time(image: ChainImage):
    env = ScenarioEnvironment()
    logger = log.get_logger("postprocessing", env.logging_queue)

    scap = os.path.join(env.out_dir, f'{env.recording_name}.scap')
    pcap = os.path.join(env.out_dir, f'{env.recording_name}.pcap')
    ip = Collector().attacker_ip
    logger.info(f"Starting postprocessing for attacker {ip}")

    matcher = PostprocessingMatcher(pcap, scap, ip)

    for command in image.commands:
        optimized_time, source = matcher.get_exact_attack_time(
            command.after_packet)
        Collector().set_exploit_time(command.name, optimized_time, source)

    logger.info(f"Finished postprocessing")
Example #3
0
 def start_container(self, check_if_available, init=None):
     self.container = run_image(self.image.name, self.env.network, self.env.victim_hostname, self.port_mapping)
     self.logger.debug("Waiting for container to be available")
     self.container.reload()
     Collector().add_container(self.env.victim_hostname, "victim", get_ip_address(self.container))
     wait_until(check_if_available, 60, 1, container=self.container)
     self.logger.info("Container available on port(s) %s" % self.container.ports)
     if init is not None:
         init(self.container, self.logger)
     yield self.container
     self.container.stop()
Example #4
0
    def __call__(self, with_exploit=False):
        self.logger.info('Simulating Scenario: {}'.format(self))
        with self.victim.start_container(self.wait_for_availability,
                                         self.init_victim) as container:
            Collector().set_container_ready()
            self._warmup()
            self._recording()
        self._teardown()
        self._postprocessing()

        log.stop()
        self.logging_thread.join()
Example #5
0
    def _warmup(self):
        self.logger.info('Warming up Scenario: {}'.format(self.general_meta.name))
        sleep(self.general_meta.warmup_time)
        Collector().set_warmup_end()

        if self.is_exploit:
            exploit_time = time() + self.general_meta.exploit_time
            self.exploit_thread = Thread(
                target=self.exploit.execute_exploit_at_time, args=(exploit_time,))
            self.exploit_thread.start()

        self.logger.info('Start Normal Behaviours for Scenario: {}'.format(self.general_meta.name))
        wts = self.normal.start_simulation()
        self.logger.debug("Simulating with %s" % wts)
Example #6
0
    def execute_exploit_at_time(self, execution_time):
        while time.time() < execution_time:
            time.sleep(0.5)

        for command in self.image.commands:
            self.logger.info('Executing the exploit step %s now at %s' %
                             (command.name, time.time()))
            Collector().set_exploit_time(command.name)
            cmd = format_command(command.command)
            if self.to_stdin:
                socket = self.container.attach_socket(params={
                    'stdin': 1,
                    'stream': 1
                })
                socket._writing = True
                try:
                    socket.write(cmd.encode() + b"\n")
                except:
                    pass
            else:
                _, out = self.container.exec_run(cmd)
                for line in out.decode("utf-8").split("\n")[:-1]:
                    self.logger.info(line)
Example #7
0
 def start_container(self):
     self.container = run_image(self.image.name, self.network,
                                self.container_name)
     Collector().add_container(self.container_name, "attacker",
                               get_ip_address(self.container))
Example #8
0
        Collector().set_exploit_time(command.name, optimized_time, source)

    logger.info(f"Finished postprocessing")


if __name__ == '__main__':
    portscan = ExecCommand("sh /app/nmap.sh ${victim}", name="port-scan")
    bruteforce = ExecCommand("sh /app/hydra.sh ${victim}",
                             name="brute-force",
                             after_packet=TCPPacketPartsMatcher(
                                 ["GET /", "User-Agent: curl"],
                                 forbidden_parts=["Authorization"]))
    privilege_escalation = ExecCommand(
        "python3 /app/attacker.py ${victim}:5984",
        name="privilege-escalation",
        after_packet=TCPPacketPartsMatcher(
            ["GET /_all_dbs", "User-Agent: curl", "Authorization"]))
    remote_code = ExecCommand("python3 /app/reverse-shell.py ${victim}:5984",
                              name="remote-code",
                              after_packet=TCPPacketPartsMatcher(
                                  ["GET /_users/_all_docs", "Authorization"]))

    exploit_full = ChainImage(
        "exploit_couchdb",
        commands=[portscan, bruteforce, privilege_escalation, remote_code])

    ScenarioEnvironment().out_dir = "../../couchdb_example/runs"
    ScenarioEnvironment().recording_name = "young_franklin_9218"
    Collector().add_container("x", "attacker", "192.168.224.3")
    optimize_attack_time(exploit_full)
Example #9
0
 def _postprocessing(self):
     if self.is_exploit:
         postprocessing.optimize_attack_time(self.exploit.image)
     Collector().write(self.storage_services)
Example #10
0
 def start_containers(self):
     for k in self.containers.keys():
         args = format_command(self.image.init_args)
         self.containers[k] = run_image(self.image.name, network=self.network, name=k, command=args)
         self.logger[k] = log.get_logger(f"[NORMAL] {k}", self.queue)
         Collector().add_container(k, "normal", get_ip_address(self.containers[k]))