def add_security_group_name_to_ec2_grants_callback(self, current_config, path, current_path, ec2_grant, callback_args): sg_id = ec2_grant['GroupId'] if sg_id in current_path: target = current_path[:(current_path.index(sg_id) + 1)] ec2_grant['GroupName'] = get_value_at(self.services['ec2'], target, 'name') elif 'UserId' in ec2_grant and ec2_grant['UserId'] == callback_args[ 'AWSAccountId']: if 'VpcId' in ec2_grant: target = current_path[:(current_path.index('vpcs') + 1)] target.append(ec2_grant['VpcId']) target.append('security_groups') target.append(sg_id) else: target = current_path[:(current_path.index('security_groups') + 1)] target.append(sg_id) ec2_grant['GroupName'] = get_value_at(self.services['ec2'], target, 'name') elif 'PeeringStatus' in ec2_grant: # Can't infer the name of the SG in the peered account pass else: print_exception('Failed to handle EC2 grant: %s' % ec2_grant)
def pass_conditions(all_info, current_path, conditions, unknown_as_pass_condition=False): """ Check that all conditions are passed for the current path. :param all_info: All of the services' data :param current_path: The value of the `path` variable defined in the finding file :param conditions: The conditions to check as defined in the finding file :param unknown_as_pass_condition: Consider an undetermined condition as passed :return: """ result = False if len(conditions) == 0: return True condition_operator = conditions.pop(0) for condition in conditions: if condition[0] in condition_operators: res = pass_conditions(all_info, current_path, condition, unknown_as_pass_condition) else: # Conditions are formed as "path to value", "type of test", "value(s) for test" path_to_value, test_name, test_values = condition path_to_value = fix_path_string(all_info, current_path, path_to_value) target_obj = get_value_at(all_info, current_path, path_to_value) if type(test_values) != list: dynamic_value = re_get_value_at.match(test_values) if dynamic_value: test_values = get_value_at(all_info, current_path, dynamic_value.groups()[0], True) try: res = pass_condition(target_obj, test_name, test_values) except Exception as e: res = True if unknown_as_pass_condition else False printError( 'Unable to process testcase \'%s\' on value \'%s\', interpreted as %s.' % (test_name, str(target_obj), res)) printException(e, True) # Quick exit and + false if condition_operator == 'and' and not res: return False # Quick exit or + true if condition_operator == 'or' and res: return True # Still here ? # or -> false # and -> true if condition_operator == 'or': return False else: return True
def pass_conditions(all_info, current_path, conditions, unknown_as_pass_condition=False): """ Check that all conditions are passed for the current path. :param all_info: All of the services' data :param current_path: The value of the `path` variable defined in the finding file :param conditions: The conditions to check as defined in the finding file :param unknown_as_pass_condition: Consider an undetermined condition as passed :return: """ # Fixes circular dependency from ScoutSuite.providers.base.configs.browser import get_value_at if len(conditions) == 0: return True condition_operator = conditions.pop(0) for condition in conditions: if condition[0] in ['and', 'or']: res = pass_conditions(all_info, current_path, condition, unknown_as_pass_condition) else: # Conditions are formed as "path to value", "type of test", "value(s) for test" path_to_value, test_name, test_values = condition path_to_value = fix_path_string(all_info, current_path, path_to_value) target_obj = get_value_at(all_info, current_path, path_to_value) if type(test_values) != list and type(test_values) != dict: dynamic_value = re_get_value_at.match(test_values) if dynamic_value: test_values = get_value_at(all_info, current_path, dynamic_value.groups()[0], True) try: res = pass_condition(target_obj, test_name, test_values) except Exception as e: res = True if unknown_as_pass_condition else False print_exception( 'Unable to process testcase \'%s\' on value \'%s\', interpreted as %s: %s' % (test_name, str(target_obj), res, e)) # Quick exit and + false if condition_operator == 'and' and not res: return False # Quick exit or + true if condition_operator == 'or' and res: return True return not condition_operator == 'or'
def add_security_group_name_to_ec2_grants_callback(self, current_config, path, current_path, ec2_grant, callback_args): sg_id = ec2_grant['GroupId'] if sg_id in current_path: target = current_path[:(current_path.index(sg_id) + 1)] ec2_grant['GroupName'] = get_value_at(self.services['ec2'], target, 'name') elif ec2_grant['UserId'] == callback_args['AWSAccountId']: if 'VpcId' in ec2_grant: target = current_path[:(current_path.index('vpcs') + 1)] target.append(ec2_grant['VpcId']) target.append('security_groups') target.append(sg_id) else: target = current_path[:(current_path.index('security_groups') + 1)] target.append(sg_id) ec2_grant['GroupName'] = get_value_at(self.services['ec2'], target, 'name')
def generate_listall_output(lines, resources, aws_config, template, arguments, nodup=False): """ Format and print the output of ListAll :param lines: :param resources: :param aws_config: :param template: :param arguments: :param nodup: :return: """ for line in lines: output = [] for resource in resources: current_path = resource.split('.') outline = line[1] for key in line[2]: outline = outline.replace( '_KEY_(' + key + ')', get_value_at(aws_config['services'], current_path, key, True)) output.append(outline) output = '\n'.join(line for line in sorted(set(output))) template = template.replace(line[0], output) for (i, argument) in enumerate(arguments): template = template.replace('_ARG_%d_' % i, argument) return template
def fix_path_string(all_info, current_path, path_to_value): # handle nested _GET_VALUE_AT_... while True: dynamic_path = re_get_value_at.findall(path_to_value) if len(dynamic_path) == 0: break for dp in dynamic_path: tmp = dp while True: nested = re_nested_get_value_at.findall(tmp) if len(nested) == 0: break tmp = nested[0].replace('_GET_VALUE_AT_(', '', 1) dv = get_value_at(all_info, current_path, tmp) path_to_value = path_to_value.replace('_GET_VALUE_AT_(%s)' % tmp, dv) return path_to_value
def fix_path_string(all_info, current_path, path_to_value): # Fixes circular dependency from ScoutSuite.providers.base.configs.browser import get_value_at # handle nested _GET_VALUE_AT_... while True: dynamic_path = re_get_value_at.findall(path_to_value) if len(dynamic_path) == 0: break for dp in dynamic_path: tmp = dp while True: nested = re_nested_get_value_at.findall(tmp) if len(nested) == 0: break tmp = nested[0].replace('_GET_VALUE_AT_(', '', 1) dv = get_value_at(all_info, current_path, tmp) path_to_value = path_to_value.replace('_GET_VALUE_AT_(%s)' % tmp, dv) return path_to_value
def propagate_vpc_names(aws_config, current_config, path, current_path, resource_id, callback_args): """ Propagate VPC names in VPC-related services (info only fetched during EC2 calls) :param aws_config: :param current_config: :param path: :param current_path: :param resource_id: :param callback_args: :return: """ if resource_id == ec2_classic: current_config['name'] = ec2_classic else: target_path = copy.deepcopy(current_path) target_path[1] = 'ec2' target_path.append(resource_id) target_path.append('Name') target_path = '.'.join(target_path) current_config['name'] = get_value_at(aws_config, target_path, target_path)