Ejemplo n.º 1
0
    def destroy_all_scenarios(self, profile):
        # Information gathering.
        extant_scenario_instance_names_and_paths = list()
        for scenario_name in self.scenario_names:
            scenario_instance_dir_path = find_scenario_instance_dir(
                self.base_dir, scenario_name)

            if scenario_instance_dir_path is None:
                continue
            else:
                extant_scenario_instance_names_and_paths.append(
                    (scenario_name, scenario_instance_dir_path))
                print(f"Scenario instance for {scenario_name} found.")

        if not extant_scenario_instance_names_and_paths:
            print(f"\n  No scenario instance directories exist.\n")
            return
        else:
            print(
                f"\n  {len(extant_scenario_instance_names_and_paths)} scenario"
                f" instance directories found.")

        # Iteration.
        success_count, failure_count, skipped_count = 0, 0, 0

        for scenario_name, instance_path in extant_scenario_instance_names_and_paths:
            print(f"\n--------------------------------\n")

            # Confirmation.
            delete_permission = input(f'Destroy "{scenario_name}"? [y/n]: ')

            if not delete_permission.strip()[0].lower() == "y":
                skipped_count += 1
                print(f"\nSkipped destruction of {scenario_name}.\n")
                continue

            # Terraform execution.
            terraform_directory = os.path.join(instance_path, "terraform")

            if os.path.exists(
                    os.path.join(terraform_directory, "terraform.tfstate")):
                terraform = Terraform(working_dir=terraform_directory)

                cgid = extract_cgid_from_dir_name(
                    os.path.basename(instance_path))

                destroy_retcode, destroy_stdout, destroy_stderr = terraform.destroy(
                    capture_output=False,
                    var={
                        "cgid": cgid,
                        "cg_whitelist": list(),
                        "profile": profile,
                        "region": self.aws_region,
                    },
                    no_color=IsNotFlagged,
                )
                if destroy_retcode != 0:
                    display_terraform_step_error(
                        "terraform destroy",
                        destroy_retcode,
                        destroy_stdout,
                        destroy_stderr,
                    )
                    failure_count += 1
                    # Subsequent destroys should not be skipped when one fails.
                    continue
                else:
                    print(
                        f"\n[cloudgoat] terraform destroy completed with no error code."
                    )
            else:
                print(
                    f"\nNo terraform.tfstate file was found in the scenario instance's"
                    f' terraform directory, so "terraform destroy" will not be run.'
                )

            # Scenario instance directory trashing.
            trash_dir = create_dir_if_nonexistent(self.base_dir, "trash")

            trashed_instance_path = os.path.join(
                trash_dir, os.path.basename(instance_path))

            shutil.move(instance_path, trashed_instance_path)

            success_count += 1

            print(
                f"\nSuccessfully destroyed {scenario_name}."
                f"\nScenario instance files have been moved to {trashed_instance_path}"
            )

        # Iteration summary.
        print(f"\nDestruction complete."
              f"\n    {success_count} scenarios successfully destroyed"
              f"\n    {failure_count} destroys failed"
              f"\n    {skipped_count} skipped\n")

        return
Ejemplo n.º 2
0
    def destroy_scenario(self,
                         scenario_name_or_path,
                         profile,
                         confirmed=False):
        # Information gathering.
        scenario_name = normalize_scenario_name(scenario_name_or_path)
        scenario_instance_dir_path = find_scenario_instance_dir(
            self.base_dir, scenario_name)

        if scenario_instance_dir_path is None:
            print(
                f'[cloudgoat] Error: No scenario instance for "{scenario_name}" found.'
                f" Try: cloudgoat.py list deployed")
            return

        instance_name = os.path.basename(scenario_instance_dir_path)

        # Confirmation.
        if not confirmed:
            delete_permission = input(
                f'Destroy "{instance_name}"? [y/n]: ').strip()
            if not delete_permission or not delete_permission[0].lower(
            ) == "y":
                print(f"\nCancelled destruction of {instance_name}.\n")
                return

        # Terraform execution.
        terraform_directory = os.path.join(scenario_instance_dir_path,
                                           "terraform")

        if os.path.exists(
                os.path.join(terraform_directory, "terraform.tfstate")):
            terraform = Terraform(working_dir=terraform_directory)

            cgid = extract_cgid_from_dir_name(
                os.path.basename(scenario_instance_dir_path))

            destroy_retcode, destroy_stdout, destroy_stderr = terraform.destroy(
                capture_output=False,
                var={
                    "cgid": cgid,
                    "cg_whitelist": list(),
                    "profile": profile,
                    "region": self.aws_region,
                },
                no_color=IsNotFlagged,
            )
            if destroy_retcode != 0:
                display_terraform_step_error("terraform destroy",
                                             destroy_retcode, destroy_stdout,
                                             destroy_stderr)
                return
            else:
                print(
                    "\n[cloudgoat] terraform destroy completed with no error code."
                )
        else:
            print(
                f"\nNo terraform.tfstate file was found in the scenario instance's"
                f' terraform directory, so "terraform destroy" will not be run.'
            )

        # Scenario instance directory trashing.
        trash_dir = create_dir_if_nonexistent(self.base_dir, "trash")

        trashed_instance_path = os.path.join(
            trash_dir, os.path.basename(scenario_instance_dir_path))

        shutil.move(scenario_instance_dir_path, trashed_instance_path)

        print(
            f"\nSuccessfully destroyed {instance_name}."
            f"\nScenario instance files have been moved to {trashed_instance_path}"
        )

        return
Ejemplo n.º 3
0
    def test_extract_cgid_from_dir_name(self):
        self.assertEqual(extract_cgid_from_dir_name("codebuild_secrets"), None)
        self.assertEqual(extract_cgid_from_dir_name("/codebuild_secrets"),
                         None)
        self.assertEqual(extract_cgid_from_dir_name("scenarios/ec2_ssrf"),
                         None)
        self.assertEqual(extract_cgid_from_dir_name("/scenarios/ec2_ssrf"),
                         None)
        self.assertEqual(
            extract_cgid_from_dir_name("long/path/iam_privesc_by_attachment"),
            None)
        self.assertEqual(
            extract_cgid_from_dir_name("/long/path/iam_privesc_by_attachment"),
            None)
        self.assertEqual(
            extract_cgid_from_dir_name(
                "long/path/rce_web_app/even/longer/path"), None)
        self.assertEqual(
            extract_cgid_from_dir_name(
                "/long/path/rce_web_app/even/longer/path"), None)

        self.assertEqual(
            extract_cgid_from_dir_name("codebuild_secrets_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name("/codebuild_secrets_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name("scenarios/ec2_ssrf_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name("/scenarios/ec2_ssrf_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name(
                "long/path/iam_privesc_by_attachment_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name(
                "/long/path/iam_privesc_by_attachment_cgid0123456789"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name(
                "long/path/rce_web_app_cgid0123456789/even/longer/path"),
            "cgid0123456789",
        )
        self.assertEqual(
            extract_cgid_from_dir_name(
                "/long/path/rce_web_app_cgid0123456789/even/longer/path"),
            "cgid0123456789",
        )