Exemple #1
0
def filter_valid_attacks(attacks):
    valid_attacks = [
        attack_name for attack_name in attacks
        if CFState.get_instance().active_target.model_data_type in
        CFState.get_instance().loaded_attacks[attack_name].tags
    ]
    return valid_attacks
Exemple #2
0
def show_info(self, args):
    if args.target:
        target = CFState.get_instance().loaded_targets.get(args.target, None)
        if not target:
            self.pwarning(f"\n [!] Invalid target '{args.target}'.\n")
            return
        else:
            self.poutput(show_target_info(target))

    if not args.target and not args.attack:
        target = CFState.get_instance().active_target
        if not target:
            self.pwarning("\n [!] No active target.\n")
            return
        else:
            self.poutput(show_target_info(target))
            return

    if args.attack:
        attack = CFState.get_instance().loaded_attacks.get(args.attack, None)
        if not attack:
            self.pwarning(f"\n [!] Invalid attack '{args.attack}'.\n")
            return
        else:
            self.poutput(show_attack_info(attack))
            return
Exemple #3
0
def do_reload(self, args):
    """Reload the active target. Helpful when making changes to a target class."""
    if not CFState.get_instance().active_target:
        self.poutput("\n[!] Not interacting with a target. \n")
        return
    else:
        CFState.get_instance().reload_target()
Exemple #4
0
    def _set_prompt(self):
        if not CFState.get_instance().active_target:
            self.prompt = "counterfit> "

        else:
            if not CFState.get_instance().active_target.active_attack:
                self.prompt = f"{CFState.get_instance().active_target.model_name}> "
            else:
                self.prompt = f"{CFState.get_instance().active_target.model_name}>{CFState.get_instance().active_target.active_attack.attack_name}> "
Exemple #5
0
def do_use(self, args):
    """Select an attack to use on the active target.
    Use 'interact' to select a target first.
    """

    if not CFState.get_instance().active_target:
        self.pwarning("\n [!] Not interacting with any targets. Try interacting with a target.\n")
        return

    CFState.get_instance().add_attack_to_active_target(args.attack, args.parameters)
Exemple #6
0
def get_attacks(input_attack):
    # Takes input attack name and returns respective attack class object
    if not input_attack:
        attacks = list(CFState.get_instance().loaded_attacks.keys())
    else:
        try:
            attack_cls = CFState.get_instance().loaded_attacks[input_attack]
        except KeyError:
            raise ValueError(f"Attack Not Found: {input_attack}")
        if CFState.get_instance().active_target.model_data_type not in attack_cls.tags:
            raise ValueError(f"Inappropriate attack for target: {input_attack}")
        attacks = [input_attack]
    return attacks
Exemple #7
0
def do_back(self, args):
    """
    Exits the active attack or target.
    """

    if not CFState.get_instance().active_target.active_attack:
        self.poutput(
            f"\n[+] Exiting {CFState.get_instance().active_target.model_name}\n"
        )
        CFState.get_instance().active_target = None
    else:
        self.poutput(
            f"\n[+] Exiting {CFState.get_instance().active_target.active_attack.attack_id}\n"
        )
        CFState.get_instance().active_target.active_attack = None
Exemple #8
0
def scan_attacks_on_active_target(self, args):
    if CFState.get_instance().active_target is None:
        self.pwarning(
            "\n [!] Not interacting with a target. Set the active target with `interact`.\n"
        )
        return

    # read arguments
    input_attacks = args.attack
    num_iters = args.iterations
    has_logging_enabled = args.log
    has_verbose_enabled = args.verbose
    set_params = args.set
    class_summary = args.class_summary

    # get attacks
    try:
        attacks = get_attacks(input_attacks)
    except ValueError as e:
        self.pwarning(f'\n [!] {e}\n')
        return

    # prefilter for valid attacks
    attacks = filter_valid_attacks(attacks)
    if len(attacks) == 0:
        self.pwarning(
            "\n [!] No matching attacks found for target.  Did you load a framework?\n"
        )
        return

    self.poutput(
        f'\n[+] Running these attacks {num_iters}x each:\n\t{", ".join(attacks)}\n'
    )
    perform_attacks_on_target(self, attacks, num_iters, has_logging_enabled,
                              has_verbose_enabled, set_params, class_summary)
Exemple #9
0
def do_save(self, args):
    """save parameters and results (if available) of current target
    Requires
    *  "interact <target>"
    """
    if not CFState.get_instance().active_target:
        self.pwarning("\n [!] Not interacting with a target. Set the active target with `interact`.\n")
        return
    module_path = "/".join(CFState.get_instance().active_target.__module__.split(".")[:-1])
    if "results" not in os.listdir(module_path):
        os.mkdir(f"{module_path}/results")

    filename = f"{module_path}/results/{CFState.get_instance().active_target.model_name}_{CFState.get_instance().active_target.target_id}.json"
    with open(filename, "w") as outfile:
        json.dump(CFState.get_instance().active_target.dump(), outfile, indent=1)

    self.poutput(f"\n[+] Successfully wrote {filename}\n")
Exemple #10
0
def show_results(self, args):
    try:
        summary = get_run_summary(CFState.get_instance().active_target)
    except (KeyError, AttributeError, TypeError):
        self.pwarning("\n [!] No results found. First 'run' an attack.\n")
        return

    self.poutput(get_printable_run_summary(summary))
Exemple #11
0
def list_frameworks():
    columns: List[Column] = list()
    data_list: List[List[Any]] = list()
    columns.append(Column("Framework", width=20))
    columns.append(Column("# of Attacks", width=30))
    for framework, list_of_attacks in CFState.get_instance(
    ).loaded_frameworks.items():
        data_list.append([framework, len(list_of_attacks)])
    st = SimpleTable(columns)
    print()
    print(st.generate_table(data_list, row_spacing=0))
    print()
Exemple #12
0
def show_options(self, args):
    if args.attack:
        try:
            attack = CFState.get_instance().loaded_attacks.get(
                args.attack, None)
        except AttributeError:
            self.pwarning("\n [!] Attack not found.\n")
    else:
        # default to the active attack
        try:
            attack = CFState.get_instance().active_target.active_attack
        except AttributeError:
            self.pwarning(
                "\n [!] Interact with a target and set an active target first.\n"
            )
            return

    if attack is None:
        self.pwarning("\n [!] No active attack. Try 'use'.\n")
        return

    self.poutput("\n" + show_attack_options(attack))
Exemple #13
0
def list_attacks():
    columns: List[Column] = list()
    data_list: List[List[Any]] = list()
    columns.append(Column("Name", width=25))
    columns.append(Column("Type", width=15))
    columns.append(Column("Category", width=15))
    columns.append(Column("Tags", width=15))
    columns.append(Column("Framework", width=10))
    for _, attack_obj in CFState.get_instance().loaded_attacks.items():
        tags = ", ".join(attack_obj.tags)
        data_list.append([
            attack_obj.attack_name, attack_obj.attack_type,
            attack_obj.category, tags, attack_obj.framework
        ])
    st = SimpleTable(columns)
    print()
    print(st.generate_table(data_list, row_spacing=0))
    print()
Exemple #14
0
def show_sample(self, args):
    try:
        target = CFState.get_instance().active_target
        attack = target.active_attack
    except AttributeError:
        self.pwarning(
            "\n [!] Interact with a target and set an active target first.\n")
        return

    if attack is None:
        self.pwarning("\n [!] No active attack. Try 'use'.\n")
        return

    if args.index is not None and args.result:
        self.pwarning("\n [!] Cannot specify both an index and a result.\n")
        return

    if args.result:
        try:
            samples = target.active_attack.results["final"]["input"]
            sample_index = [target.active_attack.attack_id] * len(samples)
            heading1 = "attack id"
        except (KeyError, AttributeError):
            self.p("\n [!] No results found. First 'run' an attack.\n")
            return
    elif args.index is None:
        restore_index = attack.sample_index
        target.set_attack_samples(attack.sample_index)
        samples = attack.samples
        target.set_attack_samples(restore_index)
        sample_index = attack.sample_index
        heading1 = None
    else:
        restore_index = attack.sample_index
        target.set_attack_samples(args.index)
        samples = attack.samples
        target.set_attack_samples(restore_index)
        sample_index = args.index
        heading1 = None

    self.poutput(
        show_current_sample(target, get_printable_batch(target, samples),
                            heading1, sample_index))
Exemple #15
0
def list_targets():
    columns: List[Column] = list()
    data_list: List[List[Any]] = list()
    columns.append(Column("Name", width=15))
    columns.append(Column("Type", width=15))
    columns.append(Column("Input Shape", width=15))
    columns.append(Column("Location", width=85))
    for _, target_obj in CFState.get_instance().loaded_targets.items():
        shp = str(target_obj.model_input_shape)
        data_list.append([
            target_obj.model_name, target_obj.model_data_type, shp,
            target_obj.model_endpoint
        ])
    st = SimpleTable(columns)
    print()
    print(st.generate_table(
        data_list,
        row_spacing=0,
    ))
    print()
Exemple #16
0
def do_list(self, args):
    """List the available targets, frameworks, or attacks."""

    if args.type.lower() == "targets":
        list_targets()

    elif args.type.lower() == "attacks":
        if not CFState.get_instance().loaded_attacks:
            self.pwarning(
                "\n [!] No frameworks have been loaded. Try 'load <framework>'.\n"
            )
        else:
            list_attacks()

    elif args.type.lower() == "frameworks":
        list_frameworks()

    else:
        self.pwarning(
            "\n [!] Argument not recognized: expecting 'targets', 'attacks', or 'frameworks'.\n"
        )
Exemple #17
0
def do_interact(self, args):
    """Sets the active target."""

    CFState.get_instance().set_active_target(args.target)
Exemple #18
0
def show_sample(self, args):

    target = CFState.get_instance().active_target
    if not target:
        self.pwarning(
            "\n [!] Not interacting with a target. Set the active target with `interact`.\n"
        )
        return

    if sum([args.surprise, args.index is not None, args.result]) > 1:
        self.pwarning(
            "\n [!] must specify only one of {surprise, index, result}.\n")
        return

    elif sum([args.surprise, args.index is not None, args.result]) == 0:
        # "show sample" with an active target uses the current sample_index as input
        try:
            args.index = target.active_attack.sample_index
        except (ValueError, AttributeError):
            self.pwarning(
                "\n [!] No active attack. Please provide valid arguments. Try 'show sample -i 2' or 'show sample -s'.\n"
            )
            return

    if isinstance(args.index, int):
        sample_index = args.index
        target_x_len = len(target.X) - 1
        if sample_index > target_x_len:
            self.pwarning(
                "\n [!] Entered index is out of bounds. Please provide index in the range {0} and {1} including.\n"
                .format(0, target_x_len))
            return
        samples = get_samples(target, sample_index)
        heading1 = None

    elif args.surprise:
        sample_index = random.randint(0, len(target.X) - 1)
        samples = get_samples(target, index=sample_index)
        heading1 = None

    elif args.result:
        attack = target.active_attack
        if not attack:
            self.pwarning(
                "\n [!] No active attack. load respective framework and try 'use'.\n"
            )
            return
        if args.index is not None and args.result:
            self.pwarning(
                "\n [!] Cannot specify both an index and a result.\n")
            return
        try:
            samples = attack.results["final"]["input"]
            sample_index = [attack.attack_id] * len(samples)
            heading1 = "attack id"
        except (KeyError, AttributeError, TypeError):
            self.pwarning("\n [!] No results found. First 'run' an attack.\n")
            return
    else:
        self.pwarning(
            "\n [!] Please provide valid arguments. Try 'show sample -i 2' or 'show sample -s'.\n"
        )
        return

    self.poutput(
        show_current_sample(target, get_printable_batch(target, samples),
                            heading1, sample_index))
Exemple #19
0
def do_scan(self, args):
    """scan over all attacks against an active target, using random parameters
    Requires
    *  "interact <target>"
    """

    def perform_attacks_on_target(attacks, num_iters, has_logging_enabled, has_verbose_enabled):
        # loop over loaded attacks
        scans_by_attack = defaultdict(list)
        scans_by_label = defaultdict(list)
        for attack_name in attacks:
            for n in range(num_iters):
                if has_verbose_enabled:
                    self.poutput(f"\n[+] Running {attack_name} iteration {n+1} of {num_iters}")
                # set random attack algorithm parameters
                CFState.get_instance().add_attack_to_active_target(attack_name, "random")

                parameters = CFState.get_instance().active_target.active_attack.parameters
                if has_verbose_enabled:
                    self.poutput(
                        f"Parameters: {json.dumps(parameters)}"
                    )

                # set random attack sample
                CFState.get_instance().active_target.set_attack_samples(
                    random.randint(0, len(CFState.get_instance().active_target.X) - 1)
                )
                
                # Initialize the attack to obtain initail labels
                CFState.get_instance().active_target.init_run_attack()
                
                # set random target class depends on targeted or untargeted attack
                is_targeted = CFState.get_instance().active_target.active_attack.parameters.get("targeted", False)
                if is_targeted:
                    initial_labels = CFState.get_instance().active_target.active_attack.results['initial']['label']
                    target_class = random.choice(list(set(CFState.get_instance().active_target.model_output_classes).difference(set(initial_labels))))
                    target_class_idx = CFState.get_instance().active_target.model_output_classes.index(target_class)
                else:
                    target_class_idx = random.randint(
                    0, len(CFState.get_instance().active_target.model_output_classes) - 1
                )
                CFState.get_instance().active_target.active_attack.target_class = target_class_idx 

                # run the attack
                CFState.get_instance().active_target.run_attack(logging=has_logging_enabled)

                # update the status and show success
                summary = get_run_summary(CFState.get_instance().active_target)
                scans_by_attack[attack_name].append(summary)
                for lab in summary['initial_label']:
                    scans_by_label[lab].append(summary)

                if has_verbose_enabled:
                    self.poutput(get_printable_run_summary(summary))    

        # print scan summary
        summary_by_attack = {k : get_scan_summary(v) for k, v in scans_by_attack.items()}
        summary_by_label = {k : get_scan_summary(v) for k, v in scans_by_label.items()}
        printable = get_printable_scan_summary(summary_by_attack, summary_by_label if args.class_summary else None)
        self.poutput(printable)

    if CFState.get_instance().active_target is None:
        self.pwarning("\n [!] Not interacting with a target. Set the active target with `interact`.\n")
        return

    input_attack = args.attack
    num_iters = args.iterations
    has_logging_enabled = args.log
    has_verbose_enabled = args.verbose

    try:
        attacks = [get_attacks(a)[0] for a in input_attack]
    except ValueError as e:
        self.pwarning(f'\n [!] {e}\n')
        return

    # prefilter for valid attacks
    attacks = filter_valid_attacks(attacks)
    if len(attacks) == 0:
        self.pwarning("\n [!] No matching attacks found for target.  Did you load a framework?\n")
        return
    self.poutput(f'\n[+] Running these attacks {num_iters}x each:\n\t{", ".join(attacks)}\n')
    perform_attacks_on_target(attacks, num_iters, has_logging_enabled, has_verbose_enabled)
Exemple #20
0
from counterfit.core.state import CFState
from counterfit.core.run_scan_utils import get_printable_batch, get_run_summary, get_printable_run_summary
from cmd2.table_creator import Column, SimpleTable, HorizontalAlignment
from typing import Any, List

# show
base_parser = argparse.ArgumentParser()
base_subparsers = base_parser.add_subparsers(
    title="subcommands", help="show information about models and targets")

# show info
parser_info = base_subparsers.add_parser(
    "info", help="show information about the model and active attack")
parser_info.add_argument(
    "--attack",
    choices=CFState.get_instance().loaded_attacks.keys(),
    default=None,
    help="attack to show info (defaults to active attack)",
)
parser_info.add_argument(
    "--target",
    choices=CFState.get_instance().loaded_targets.keys(),
    default=None,
    help="target to show info (defaults to active target)",
)

# show options
parser_options = base_subparsers.add_parser(
    "options", help="show configuration options for the active attack")
parser_options.add_argument(
    "--attack",
Exemple #21
0
def perform_attacks_on_target(self, attacks, num_iters, has_logging_enabled,
                              has_verbose_enabled, set_params, class_summary):
    set_params_tuples = re.findall(r"(\w+)\s?=\s?([\w\.]+)",
                                   " ".join(set_params))
    # parse set parameters and put into default dict
    set_params_dict = dict(set_params_tuples)

    # loop over loaded attacks
    scans_by_attack = defaultdict(list)
    scans_by_label = defaultdict(list)
    for attack_name in attacks:
        for n in range(num_iters):
            if has_verbose_enabled:
                self.poutput(
                    f"\n[+] Running {attack_name} iteration {n+1} of {num_iters}"
                )

            # set random attack algorithm parameters
            CFState.get_instance().add_attack_to_active_target(
                attack_name, "random")

            parameters = CFState.get_instance(
            ).active_target.active_attack.parameters
            if has_verbose_enabled:
                self.poutput(f"Parameters: {json.dumps(parameters)}")

            # set random attack sample only if user hasn't set in the parameters
            sample_index = set_params_dict.get('sample_index', None)
            if sample_index:
                sample_index = int(set_params_dict['sample_index'])
            else:
                sample_index = random.randint(
                    0,
                    len(CFState.get_instance().active_target.X) - 1)
            CFState.get_instance().active_target.set_attack_samples(
                sample_index)

            # Initialize the attack to obtain initail labels
            CFState.get_instance().active_target.init_run_attack()

            # set random target class depends on targeted or untargeted attack
            is_targeted = CFState.get_instance(
            ).active_target.active_attack.parameters.get("targeted", False)
            if is_targeted:
                initial_labels = CFState.get_instance(
                ).active_target.active_attack.results['initial']['label']
                target_class = random.choice(
                    list(
                        set(CFState.get_instance().active_target.
                            model_output_classes).difference(
                                set(initial_labels))))
                target_class_idx = CFState.get_instance(
                ).active_target.model_output_classes.index(target_class)
            else:
                target_class_idx = random.randint(
                    0,
                    len(CFState.get_instance().active_target.
                        model_output_classes) - 1)
            CFState.get_instance(
            ).active_target.active_attack.target_class = target_class_idx

            # run the attack
            CFState.get_instance().active_target.run_attack(
                logging=has_logging_enabled)

            # update the status and show success
            summary = get_run_summary(CFState.get_instance().active_target)
            scans_by_attack[attack_name].append(summary)
            for lab in summary['initial_label']:
                scans_by_label[lab].append(summary)

            if has_verbose_enabled:
                self.poutput(get_printable_run_summary(summary))

    # print scan summary
    summary_by_attack = {
        k: get_scan_summary(v)
        for k, v in scans_by_attack.items()
    }
    summary_by_label = {
        k: get_scan_summary(v)
        for k, v in scans_by_label.items()
    }
    printable = get_printable_scan_summary(
        summary_by_attack, summary_by_label if class_summary else None)
    self.poutput(printable)
Exemple #22
0
def do_set(self, args):
    """Set parameters of the active attack on the active target using param1=val1 param2=val2 notation.
    This command replaces built-in "set" command, which is renamed to "setg".
    """

    if not CFState.get_instance().active_target:
        self.pwarning(
            '\n [!] No active target. Try "setg" for setting global arguments.\n'
        )
        return

    if not CFState.get_instance().active_target.active_attack:
        self.pwarning('\n [!] No active attack. Try "use <attack>".\n')
        return

    # 'set' with no options shows current variables, similar to "show options"
    if not args.what:
        self.pwarning(
            '\n [!] No arguments specified.  Try "set <param>=<value>".\n')

    # create structure to ensure all params are present and ordered properly. Defaults to current params to prevent over writing with default values
    params_struct = namedtuple(
        "params",
        [
            i for i in CFState.get_instance().active_target.active_attack.
            parameters.keys()
        ] + ["sample_index", "target_class"],
        defaults=list(CFState.get_instance(
        ).active_target.active_attack.parameters.values()) + [
            CFState.get_instance().active_target.active_attack.sample_index,
            CFState.get_instance().active_target.active_attack.target_class,
        ],
    )

    # parse parameters and new values from the args
    try:
        params_to_update = re.findall(r"(\w+)\s?=\s?([\w\.]+)",
                                      " ".join(args.what))
    except:
        self.pwarning("\n [!] Failed to parse arguments.\n")
        return

    # create default params struct
    default_params = {
        k: v
        for k, v in
        CFState.get_instance().active_target.active_attack.default.items()
    }
    default_params["sample_index"] = CFState.get_instance(
    ).active_target.active_attack.sample_index
    default_params["target_class"] = CFState.get_instance(
    ).active_target.active_attack.target_class

    # ensure all current params exist and are ordered correctly
    default_params = params_struct(**default_params)._asdict()

    # convert string "True"/"true" and "False"/"false" to boolean
    for i, v in enumerate(params_to_update):
        if type(default_params.get(v[0], None)) is bool:
            if v[1].lower() == "true" or int(v[1]) == 1:
                params_to_update[i] = (v[0], True)
            elif v[1].lower() == "false" or int(v[1]) == 0:
                params_to_update[i] = (v[0], False)

    # create new params struct using default values where no new values are spec'd
    new_params = params_struct(**{
        i[0]: type(default_params.get(i[0], ""))(i[1])
        for i in params_to_update
    })

    # create current params struct
    current_params = {
        k: v
        for k, v in
        CFState.get_instance().active_target.active_attack.parameters.items()
    }
    current_params["sample_index"] = CFState.get_instance(
    ).active_target.active_attack.sample_index
    current_params["target_class"] = CFState.get_instance(
    ).active_target.active_attack.target_class

    # ensure all current params exist and are ordered correctly
    current_params = params_struct(**current_params)._asdict()

    # separate target_class and sample_index from struct and update the relevant values
    CFState.get_instance().active_target.active_attack.parameters = {
        k: v
        for k, v in zip(new_params._fields[:-2], new_params[:-2])
    }
    CFState.get_instance(
    ).active_target.active_attack.sample_index = new_params.sample_index
    CFState.get_instance(
    ).active_target.active_attack.target_class = new_params.target_class

    # print info
    print_new_params = new_params._asdict()

    columns: List[Column] = list()
    data_list: List[List[Any]] = list()
    columns.append(
        Column("Attack Parameter (type)",
               width=25,
               header_horiz_align=HorizontalAlignment.LEFT,
               data_horiz_align=HorizontalAlignment.RIGHT))
    columns.append(
        Column("Default",
               width=12,
               header_horiz_align=HorizontalAlignment.CENTER,
               data_horiz_align=HorizontalAlignment.LEFT))
    columns.append(
        Column("Previous",
               width=12,
               header_horiz_align=HorizontalAlignment.CENTER,
               data_horiz_align=HorizontalAlignment.LEFT))
    columns.append(
        Column("New",
               width=12,
               header_horiz_align=HorizontalAlignment.CENTER,
               data_horiz_align=HorizontalAlignment.LEFT))

    for k, default_value in default_params.items():
        param = f"{k} ({str(type(default_value).__name__)})"
        previous_value = current_params.get(k, "")
        new_value = print_new_params.get(k, "")
        if new_value != previous_value:
            data_list.append([
                param,
                str(default_value),
                str(previous_value),
                str(new_value)
            ])

        else:
            data_list.append(
                [param,
                 str(default_value)[:11],
                 str(previous_value)[:11], ""])

    st = SimpleTable(columns)
    print()
    print(st.generate_table(data_list, row_spacing=0))
    print()
Exemple #23
0
def do_run(self, args):
    """run an active attack against an active target, using parameters set by "set".
    Requires
    *  "interact <target>"
    *  "use <attack>"
    Default parameters may be override via "set param1=val1 param2=val2"
    """
    if CFState.get_instance().active_target is None:
        self.pwarning("\n [!] Not interacting with a target. Set the active target with `interact`.\n")
        return

    if CFState.get_instance().active_target.active_attack is None:
        self.pwarning("\n [!] No attack specified. Set the active attack with 'use'.\n")
        return

    if (
        CFState.get_instance().active_target.model_data_type
        not in CFState.get_instance().active_target.active_attack.tags
    ):
        self.pwarning(
            f"Error: innappropriate attack for target {CFState.get_instance().active_target.model_name}"
        )
        print()
        self.pwarning(
            f"{CFState.get_instance().active_target.model_name} is of data type {CFState.get_instance().active_target.model_data_type}"
        )
        self.pwarning(
            f"but, {CFState.get_instance().active_target.active_attack.attack_name} is for models with:"
        )
        for tag in CFState.get_instance().active_target.active_attack.tags:
            self.pwarning(f"\t{tag}")

        return

    self.poutput(
        f"\n[+] Running {CFState.get_instance().active_target.active_attack.attack_name} on {CFState.get_instance().active_target.model_name}\n"
    )

    CFState.get_instance().active_target.set_attack_samples(
        CFState.get_instance().active_target.active_attack.sample_index
    )
    # Run init_attack followed by run_attack
    CFState.get_instance().active_target.init_run_attack()
    CFState.get_instance().active_target.run_attack(logging=args.log)

    summary = get_run_summary(CFState.get_instance().active_target)
    self.poutput(get_printable_run_summary(summary))    
Exemple #24
0
import sys
import os
import warnings
from counterfit.core import config
from counterfit.core.state import CFState
from counterfit.core.terminal import Terminal

if sys.version_info < (3, 7):
    print("[!] Python 3.7+ is required")
    sys.exit(1)

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"  # make tensorflow quiet
warnings.filterwarnings("ignore", category=FutureWarning)

if __name__ == "__main__":
    terminal = Terminal()
    num_attacks = CFState.get_instance().import_frameworks()
    num_targets = CFState.get_instance().import_targets()
    terminal.load_commands(
    )  # load commands last. Choices depend on targets and attacks.

    print(config.start_banner)
    print(f"""
        [+] {num_attacks} attacks
        [+] {num_targets} targets
    """)

    sys.exit(terminal.cmdloop())
Exemple #25
0
import cmd2
import argparse

from counterfit.core.state import CFState


parser = argparse.ArgumentParser()
parser.add_argument("attack", choices=CFState.get_instance().loaded_attacks.keys())
parser.add_argument("-p", "--parameters", choices=["default", "random"], default="default")


@cmd2.with_argparser(parser)
@cmd2.with_category("Counterfit Commands")
def do_use(self, args):
    """Select an attack to use on the active target.
    Use 'interact' to select a target first.
    """

    if not CFState.get_instance().active_target:
        self.pwarning("\n [!] Not interacting with any targets. Try interacting with a target.\n")
        return

    CFState.get_instance().add_attack_to_active_target(args.attack, args.parameters)
Exemple #26
0
import argparse
import cmd2

from counterfit.core.state import CFState

parser = argparse.ArgumentParser()
parser.add_argument("framework",
                    choices=CFState.get_instance().loaded_frameworks,
                    default="art")


@cmd2.with_argparser(parser)
@cmd2.with_category("Counterfit Commands")
def do_load(self, args):
    """Loads a framework.

    :param framework name: the framework to load.
    """
    CFState.get_instance().load_framework(args.framework)
Exemple #27
0
def do_predict(self, args):
    """Predict a single sample for the active target"""
    if CFState.get_instance().active_target is None:
        self.pwarning("\n [!] must first `interact` with a target.\n")
        return
    else:
        target = CFState.get_instance().active_target

    if sum([args.random, args.sample_index is not None, args.result]) > 1:
        self.pwarning("\n [!] must specify only one of {random, sample_index, result}.\n")
        return

    heading1 = "Sample Index"
    if args.random:
        sample_index = random.randint(0, len(target.X) - 1)
        samples = set_attack_samples(target, sample_index)

    elif args.sample_index:  # default behavior
        sample_index = args.sample_index
        samples = set_attack_samples(target, sample_index)

    elif args.result:
        try:
            samples = target.active_attack.results['final']['input']
            sample_index = [target.active_attack.attack_id] * len(samples)            
            heading1 = "Attack ID"
        except (KeyError, AttributeError):
            self.pwarning("\n [!] No results found. First 'run' an attack.\n")
            return

    elif target.active_attack is not None and target.active_attack.sample_index is not None:
        sample_index = target.active_attack.sample_index
        samples = set_attack_samples(target, sample_index)        

    else:
        self.pwarning("\n [!] No index sample, setting random index.\n")
        sample_index = random.randint(0, len(target.X) - 1)
        samples = set_attack_samples(target, sample_index)        

    result = target._submit(samples)

    columns: List[Column] = list()
    columns.append(
        Column(
            heading1,
            width=8,
            header_horiz_align=HorizontalAlignment.LEFT,
            data_horiz_align=HorizontalAlignment.RIGHT,
        )
    )
    columns.append(
        Column(
            "Sample",
            width=60,
            header_horiz_align=HorizontalAlignment.CENTER,
            data_horiz_align=HorizontalAlignment.RIGHT,
        )
    )
    columns.append(
        Column(
            "Output Scores\n" + str(target.model_output_classes).replace(',', ''),
            width=30,
            header_horiz_align=HorizontalAlignment.CENTER,
            data_horiz_align=HorizontalAlignment.RIGHT,
        )
    )

    if not hasattr(sample_index, "__iter__"):
        sample_index = [sample_index]

    samples_str = get_printable_batch(target, samples)
    results_str = printable_numpy(result)

    data_list: List[List[Any]] = list()
    for idx, samp, res in zip(sample_index, samples_str, results_str):
        data_list.append([idx, samp, res])

    st = SimpleTable(columns)
    self.poutput("\n" + st.generate_table(data_list, row_spacing=0) + "\n")
Exemple #28
0
def do_load(self, args):
    """Loads a framework.

    :param framework name: the framework to load.
    """
    CFState.get_instance().load_framework(args.framework)
Exemple #29
0
def do_new(self, args):
    """Optional wizard to aid in creating a new attack target."""
    model_name = questionary.text("Target name:").ask()
    model_name = model_name.replace(" ", "")

    available_frameworks = list(
        CFState.get_instance().loaded_frameworks.keys())
    framework_choice = questionary.select("Which framework?",
                                          choices=available_frameworks).ask()

    if "textattack" in framework_choice:
        framework = "TextTarget"
    elif "art" in framework_choice:
        framework = "ArtTarget"
    else:
        raise ValueError("invalid framework")

    if framework == "TextTarget":
        model_data_type = "text"
    elif framework == "ArtTarget":
        model_data_type = questionary.select("What data type?",
                                             choices=["numpy", "image"]).ask()
    else:
        raise ValueError("invalid framework")

    if model_name not in os.listdir(config.targets_path):
        try:
            os.mkdir(f"{config.targets_path}/{model_name}")
            open(f"{config.targets_path}/{model_name}/__init__.py",
                 "w").close()
            with open(f"{config.targets_path}/{model_name}/{model_name}.py",
                      "w") as f:
                f.write(f"""

# Generated by counterfit #

from counterfit.core.targets import {framework}

class {model_name.capitalize()}({framework}):
    model_name = "{model_name.lower()}"
    model_data_type = "{model_data_type}"
    model_endpoint = ""
    model_input_shape = ()
    model_output_classes = []
    X = []

    def __init__(self):
        self.X = []

    def __call__(self, x):
        return x
""")

            CFState.get_instance().import_targets()
        except Exception as e:

            self.pwarning(f"\n [!] Failed to write target file: {e}.\n")

    else:
        self.pwarning(
            f"\n [!] {model_name} already exists. Choose a new name.\n")
Exemple #30
0
 def target_singleton_handler(self):
     target_singleton_obj = CFState.get_instance()
     return target_singleton_obj