예제 #1
0
def test_random_array():
    obj = ba_random()
    l = [1, 2, 3, 4, 5]
    for i in range(400):
        val = obj.array_random(l)
        assert val in l
        assert val == 1 or val == 2 or val == 3 or val == 4 or val == 5
예제 #2
0
def test_will_do():
    obj = ba_random()
    truecount = 0
    falsecount = 0
    for i in range(400):
        val = obj.will_do()
        assert val == True or val == False

        if val == True:
            truecount += 1
        elif val == False:
            falsecount += 1

    assert truecount > 0
    assert falsecount > 0
예제 #3
0
    def __load_provides(self, provides_string, restriction_list):

        choose_list = []

        for module in module_util.get_module_list():

            current_module = module_util.import_module(module)

            if current_module.has_provides(
                    provides_string) and current_module.get_class_name(
                    ) not in restriction_list:

                # If the module we selected is already loaded (but not processed), use it
                if current_module.get_class_name(
                ) in self.__name_map and self.__name_map[
                        current_module.get_class_name()] != None:
                    self.__provides_map[
                        provides_string] = current_module.get_class_name()
                    return self.__name_map[current_module.get_class_name()]
                else:
                    choose_list.append(module)

        if choose_list == 0:
            return None

        selected_module_name = ba_random().array_random(choose_list)

        selected_module = module_util.import_module(selected_module_name)

        if selected_module == None:
            return None

        # Set the provides mapping
        self.__provides_map[provides_string] = selected_module.get_class_name()

        self.__insert_module(selected_module.get_class_name(), selected_module)

        return self.__name_map[selected_module.get_class_name()]
예제 #4
0
	def __load_provides(self, provides_string, restriction_list):

		choose_list = []
		
		for module in module_util.get_module_list():
			
			current_module = module_util.import_module(module)

			if current_module.has_provides(provides_string) and current_module.get_class_name() not in restriction_list:
				
				# If the module we selected is already loaded (but not processed), use it
				if current_module.get_class_name() in self.__name_map and self.__name_map[current_module.get_class_name()] != None:
					self.__provides_map[provides_string] = current_module.get_class_name()
					return self.__name_map[current_module.get_class_name()]
				else:
					choose_list.append(module)

			
		if choose_list == 0:
			return None
		
		selected_module_name = ba_random().array_random(choose_list)
		
		selected_module = module_util.import_module(selected_module_name)
		
		if selected_module == None:
			return None
		
		
		
		# Set the provides mapping
		self.__provides_map[provides_string] = selected_module.get_class_name()
		
		self.__insert_module(selected_module.get_class_name(), selected_module)
		

		return self.__name_map[selected_module.get_class_name()]
예제 #5
0
def test_random_string():
    obj = ba_random()
    for i in range(400):
        val = obj.random_string(2, 10)
        assert len(val) >= 2 and len(val) <= 10
예제 #6
0
def test_random_number():
    obj = ba_random()
    for i in range(400):
        num = obj.random_number(0, 10)
        assert num >= 0 and num <= 10
예제 #7
0
    def __resolve_vuln(self,
                       module_obj,
                       depth,
                       vuln_object,
                       ver_restrictions=[],
                       dep_restrictions=[]):

        front = "\t   " * depth

        if self.__debug:
            print(front + "V: Processing " + module_obj.get_class_name() +
                  "." + vuln_object.name())
            print(front + "------------------------------------------\n")

        dep_list = vuln_object.get_dependencies()

        if len(dep_list) > 0:

            for dep in dep_list:

                if self.__debug:
                    print(front + "V: Dependency: ")
                    for item in dep.get_links():
                        print(front + "   " + str(item))

                dep_done = False
                # List for ORed vulnerabilities of provides strings that have failed
                failed_ps_list = []

                # Loop until a valid module for the dependency is loaded
                while dep_done == False:

                    selected_dep_ps = None
                    selected_dep_range = None

                    # Check if the dependency has mutiple matchable values (is OR)
                    if dep.is_or():

                        dep_choice_list = dep.get_links()

                        dep_valid_list = []

                        # Remove from the running any provides strings that have failed
                        for dep_choice in dep_choice_list:
                            if not dep_choice[0] in failed_ps_list:
                                dep_valid_list.append(dep_choice)

                        # Check if the OR has failed on all counts, if so fail the vuln
                        if len(dep_valid_list) == 0:
                            return False

                        # If so, check to see if any of the provides strings are already loaded, and use them if so
                        for dep_choice in dep_valid_list:
                            if dep_choice[0] in self.__provides_map:
                                selected_dep_ps = dep_choice.provides_string
                                selected_dep_range = dep_choice.version_range

                        # If no existing values were found, then select a random one
                        if selected_dep_ps == None:
                            choice_sel = ba_random().array_random(
                                dep_valid_list)
                            selected_dep_ps = choice_sel.provides_string
                            selected_dep_range = choice_sel.version_range
                    # If not OR, just get the strings
                    else:
                        link = dep.get_links()[0]
                        selected_dep_ps = link.provides_string
                        selected_dep_range = link.version_range

                    if self.__debug:
                        print(
                            front +
                            "V: Looking for a dependency that can provide: " +
                            selected_dep_ps + " - " + str(selected_dep_range))

                    # If no other module that provides the string, load a module that does
                    if selected_dep_ps not in self.__provides_map:

                        provides_done = False

                        # Modules that were tried to provide the necessary provides_string, but failed to resolve
                        failed_modules = []

                        # Loop until we load a resolvable module that provides the given provides string
                        while provides_done == False:

                            # Get a module to attempt to use
                            dep_module = self.__load_provides(
                                selected_dep_ps, failed_modules)

                            # Could not get a module that provides the dependency that works
                            if dep_module == None:
                                if dep.is_or():
                                    failed_ps_list.append(selected_dep_ps)
                                    provides_done = True
                                else:
                                    self.__add_faulting_module(
                                        "PS:" + selected_dep_ps,
                                        "Could not load module for " +
                                        selected_dep_ps)
                                    return False
                            else:

                                if self.__debug:
                                    print(front + "V: Loaded module " +
                                          dep_module.get_class_name() +
                                          " to provide " + selected_dep_ps)

                                self.__add_parent(module_obj.get_class_name(),
                                                  dep_module.get_class_name())

                                # Add the restriction given by the dependency definition
                                dep_module.add_version_restriction(
                                    selected_dep_ps, selected_dep_range)

                                result = self.__resolve_module(
                                    dep_module, depth + 1, ver_restrictions +
                                    module_obj.get_dependency_restrictions())

                                if result == True:
                                    dep_done = True
                                    provides_done = True
                                else:
                                    if self.__debug:
                                        print(front +
                                              "V: Module failed to resolve")
                                    if not dep_module in failed_modules:
                                        failed_modules.append(
                                            dep_module.get_class_name())
                                    self.__remove_child_tree(
                                        dep_module.get_class_name())
                                    dep_module._clear_restrictions()

                    else:

                        dep_done = True

                        # A module with that provides string has been loaded and presumably processed. Use it
                        provides_module = self.__name_map[
                            self.__provides_map[selected_dep_ps]]

                        # Check if dependency is parent to the dependency's parent (circular dependence)
                        if self.__in_parent_path(
                                module_obj.get_class_name(),
                                provides_module.get_class_name()):
                            self.__add_faulting_module(
                                module_obj.get_class_name(),
                                "Circular dependency detected")
                            return False

                        # Check if the dependency module has already been processed
                        if provides_module.get_class_name(
                        ) in self.__processed:
                            # If so, we need to check if we need to reprocess the tree

                            # First create list of dependency restrictions that are for this dependency
                            for dep_restriction in vuln.get_dependency_restrictions(
                            ):
                                if dep_restriction.provides_string(
                                ) == self.__provides_map[selected_dep_ps]:
                                    provides_module._add_temp_dependency_restriction(
                                        dep_restriction)

                            # Check if with the new restrictions the module doesn't need to be changed
                            if provides_module.still_valid():
                                # If so, convert the temp restictions into permanent ones
                                provides_module.commit_temp_dependency_restrictions(
                                )
                                # Clear the temp restrictions
                                provides_module.clear_temp_dependency_restrictions(
                                )
                            # If the vulnerabilities in the dependency are no longer possible, here's where things get interesting
                            else:

                                # First check if the module has any child modules (already processed dependencies)

                                if self.__has_children(
                                        provides_module.get_class_name()):
                                    # If so, remove them
                                    self.__remove_child_tree(
                                        provides_module.get_class_name())

                                # Check if the module is a dependency for anything else, because the vulnerabilities that it provided are now invalid
                                if not self.__has_parents(
                                        provides_module.get_class_name()):
                                    # If not, things are a lot simpler

                                    # Add the current restrictions to the child module
                                    provides_module.commit_temp_dependency_restrictions(
                                    )
                                    # Clear the temp restrictions
                                    provides_module.clear_temp_dependency_restrictions(
                                    )
                                    # Reprocess the child module
                                    result = self.__resolve_module(
                                        provides_module, depth + 1)
                                    if result == False:
                                        return False

                                else:
                                    # If not, we must figure out how to get both parent modules to give valid restrictions if possible
                                    # TODO: Change his algorithm to something better
                                    pass
                                    # Current Algorithm: Randomly select one of modules to set its current vulnerabilities and restrict them
                                    # This still has possibility of leaving out valid combinations, and also not working at all

                                    select_list = self.__parent_map[
                                        provides_module.get_class_name()] + [
                                            module_obj.get_class_name()
                                        ]

                                    selection = ba_random().array_random(
                                        select_list)
                                    self.__name_map[
                                        selection].negate_selections()
                                    self.__restarting = True
                        else:
                            error_message = "Invalid state, '" + selected_dep_ps + "' is set, but the module has not been resolved"
                            self.__add_faulting_module(
                                provides_module.get_class_name(),
                                error_message)
                            if self.__debug:
                                print(error_message)
                            return False

            return True

        else:
            return True
예제 #8
0
	def __resolve_vuln(self, module_obj, depth, vuln_object, ver_restrictions=[], dep_restrictions=[]):			
		
		front = "\t   " * depth
		
		if self.__debug:
			print(front + "V: Processing " + module_obj.get_class_name() + "." + vuln_object.name())
			print(front + "------------------------------------------\n")
		
		dep_list = vuln_object.get_dependencies()
		
		if len(dep_list) > 0:

			for dep in dep_list:
				
				if self.__debug:
					print(front + "V: Dependency: ")
					for item in dep.get_links():
						print(front + "   " + str(item))

				dep_done = False
				# List for ORed vulnerabilities of provides strings that have failed
				failed_ps_list = [] 
				 
				
				# Loop until a valid module for the dependency is loaded
				while dep_done == False:

					
					selected_dep_ps = None
					selected_dep_range = None
					
					# Check if the dependency has mutiple matchable values (is OR)
					if dep.is_or():

						
						dep_choice_list = dep.get_links()
						
						dep_valid_list = []
						
						# Remove from the running any provides strings that have failed
						for dep_choice in dep_choice_list:
							if not dep_choice[0] in failed_ps_list:
								dep_valid_list.append(dep_choice)	
						
						# Check if the OR has failed on all counts, if so fail the vuln
						if len(dep_valid_list) == 0:
							return False
						
						# If so, check to see if any of the provides strings are already loaded, and use them if so
						for dep_choice in dep_valid_list:
							if dep_choice[0] in self.__provides_map:
								selected_dep_ps = dep_choice.provides_string
								selected_dep_range = dep_choice.version_range
								
						# If no existing values were found, then select a random one		
						if selected_dep_ps == None:
							choice_sel = ba_random().array_random(dep_valid_list)
							selected_dep_ps = choice_sel.provides_string
							selected_dep_range = choice_sel.version_range
					# If not OR, just get the strings
					else:
						link = dep.get_links()[0]
						selected_dep_ps = link.provides_string
						selected_dep_range = link.version_range
					
					if self.__debug:
						print(front + "V: Looking for a dependency that can provide: " + selected_dep_ps + " - " + str(selected_dep_range))
					
					# If no other module that provides the string, load a module that does
					if selected_dep_ps not in self.__provides_map:
						
						provides_done = False
						
						# Modules that were tried to provide the necessary provides_string, but failed to resolve
						failed_modules = []
						
						# Loop until we load a resolvable module that provides the given provides string
						while provides_done == False:
							
							# Get a module to attempt to use
							dep_module = self.__load_provides(selected_dep_ps, failed_modules)
							
							# Could not get a module that provides the dependency that works
							if dep_module == None:
								if dep.is_or():
									failed_ps_list.append(selected_dep_ps)
									provides_done = True
								else:
									self.__add_faulting_module("PS:" +  selected_dep_ps, "Could not load module for " + selected_dep_ps)
									return False
							else:
								
								if self.__debug:
									print(front + "V: Loaded module " + dep_module.get_class_name() + " to provide " + selected_dep_ps)
								
								self.__add_parent(module_obj.get_class_name(), dep_module.get_class_name())
							
								# Add the restriction given by the dependency definition
								dep_module.add_version_restriction(selected_dep_ps, selected_dep_range)
								
								result = self.__resolve_module(dep_module, depth + 1, ver_restrictions + module_obj.get_dependency_restrictions())
								
								if result == True:
									dep_done = True	
									provides_done = True							
								else:
									if self.__debug:
										print(front + "V: Module failed to resolve")
									if not dep_module in failed_modules:
										failed_modules.append(dep_module.get_class_name())
									self.__remove_child_tree(dep_module.get_class_name())
									dep_module._clear_restrictions()
									
					
					else:

						
						dep_done = True
						
						# A module with that provides string has been loaded and presumably processed. Use it
						provides_module = self.__name_map[self.__provides_map[selected_dep_ps]]
						
						# Check if dependency is parent to the dependency's parent (circular dependence)
						if self.__in_parent_path(module_obj.get_class_name() ,provides_module.get_class_name()):
							self.__add_faulting_module(module_obj.get_class_name(), "Circular dependency detected")
							return False
						
						# Check if the dependency module has already been processed
						if provides_module.get_class_name() in self.__processed:
							# If so, we need to check if we need to reprocess the tree
							
							# First create list of dependency restrictions that are for this dependency
							for dep_restriction in vuln.get_dependency_restrictions():
								if dep_restriction.provides_string() == self.__provides_map[selected_dep_ps]:
									provides_module._add_temp_dependency_restriction(dep_restriction)
							
							# Check if with the new restrictions the module doesn't need to be changed
							if provides_module.still_valid():
								# If so, convert the temp restictions into permanent ones
								provides_module.commit_temp_dependency_restrictions()
								# Clear the temp restrictions
								provides_module.clear_temp_dependency_restrictions()
							# If the vulnerabilities in the dependency are no longer possible, here's where things get interesting
							else:
								
								# First check if the module has any child modules (already processed dependencies)
								
								if self.__has_children(provides_module.get_class_name()):
									# If so, remove them
									self.__remove_child_tree(provides_module.get_class_name())
								
								# Check if the module is a dependency for anything else, because the vulnerabilities that it provided are now invalid
								if not self.__has_parents(provides_module.get_class_name()):
									# If not, things are a lot simpler
									
			
									# Add the current restrictions to the child module
									provides_module.commit_temp_dependency_restrictions()
									# Clear the temp restrictions
									provides_module.clear_temp_dependency_restrictions()
									# Reprocess the child module
									result = self.__resolve_module(provides_module, depth + 1)
									if result == False:
										return False

									
								else:
									# If not, we must figure out how to get both parent modules to give valid restrictions if possible
									# TODO: Change his algorithm to something better
									pass
									# Current Algorithm: Randomly select one of modules to set its current vulnerabilities and restrict them
									# This still has possibility of leaving out valid combinations, and also not working at all
									
									select_list = self.__parent_map[provides_module.get_class_name()] + [module_obj.get_class_name()]
									
									selection = ba_random().array_random(select_list)
									self.__name_map[selection].negate_selections()
									self.__restarting = True			
						else:
							error_message = "Invalid state, '" + selected_dep_ps +"' is set, but the module has not been resolved"
							self.__add_faulting_module(provides_module.get_class_name(), error_message)
							if self.__debug:
								print(error_message)
							return False
			
			
			return True
			
		else:
			return True	
예제 #9
0
    def __module(self, options):

        if len(options) == 0:
            print("Incomplete command")
            print(
                "Valid sub-commands: add, remove, info, list, random, force, test"
            )
        else:
            subcommand = options[0]
            del options[0]

            if subcommand == "add":

                if not len(options) == 1:
                    print("module add: No module name")
                else:
                    module_name = options[0]

                    if module_util.module_exists(module_name):
                        if not module_name in self.__vars['to_run']['value']:
                            self.__vars['to_run']['value'].append(module_name)
                            print("Module added")
                        else:
                            print("Module is already set to be run")
                    else:
                        print("Module '" + module_name + "' does not exist")
            elif subcommand == "random":
                rand_list = []
                self.__vars['to_run']['value'] = []

                while len(rand_list) == 0:

                    mod_list = module_util.get_module_list()

                    set_level = self.__vars['level']['value']

                    for module in mod_list:
                        # Skip the test module
                        if module == "test_module":
                            continue

                        mod_obj = module_util.import_module(module)

                        if mod_obj:
                            if set_level == "any":
                                if ba_random().will_do():
                                    rand_list.append(module)
                            else:
                                if mod_obj.has_difficulty(
                                        set_level) and ba_random().will_do():
                                    rand_list.append(module)
                        else:
                            print("Could not import module " + module)

                for module_name in rand_list:
                    self.__vars['to_run']['value'].append(module_name)

            elif subcommand == "remove":
                if not len(options) == 1:
                    print("module add: No module set")
                else:
                    module_name = options[0]

                    if module_util.module_exists(module_name):
                        if module_name in self.__vars['to_run']['value']:
                            self.__vars['to_run']['value'].remove(module_name)
                            print("Module removed")
                        else:
                            print("Module is not set to run")
                    else:
                        print("Module '" + module_name + "' does not exist")
            elif subcommand == "info":

                if not len(options) == 1:
                    print("module info: No module name")
                else:
                    module_name = options[0]

                    if module_util.module_exists(module_name):
                        tmp_module = module_util.import_module(module_name)
                        print(tmp_module.info())

                        print("Vulnerabilities:")
                        for vuln in tmp_module.full_vulnerability_list():
                            print("    " + vuln)

                    else:
                        print("Module '" + module_name + "' does not exist")
            elif subcommand == "list":
                module_list = module_util.get_module_list()

                if len(module_list) > 0:
                    for item in module_list:
                        if item == "test_module":
                            continue
                        if item in self.__vars['to_run']['value']:
                            print("\t+ " + item)
                        else:
                            print("\t- " + item)
                else:
                    print("\nNo modules are set to run!")
            elif subcommand == "force":
                if not len(options) == 2:
                    print("Enter a module and vulnerability to force")
                else:
                    module = options[0]
                    vuln = options[1]

                    if module_util.module_exists(module):
                        if vuln in module_util.import_module(
                                module).full_vulnerability_list():
                            if not module in self.__vars['force']['value']:
                                self.__vars['force']['value'][module] = []

                            if not vuln in self.__vars['force']['value'][
                                    module]:
                                self.__vars['force']['value'][module].append(
                                    vuln)
                            else:
                                print(
                                    "That vulnerability is already being forced"
                                )
                        else:
                            print("Module '" + module +
                                  "' does not have the vulnerability '" +
                                  vuln + "'")
                    else:
                        print("Module '" + module + "' does not exist")
            elif subcommand == "test":
                if self.__debug_mode == False:
                    print("'module test' can only be used in debug mode")
                elif not len(options) == 2:
                    print("Enter a module and vulnerability to test")
                else:
                    module = options[0]
                    vuln = options[1]

                    if module_util.module_exists(module):
                        module_obj = module_util.import_module(module)

                        if vuln in module_obj.full_vulnerability_list():
                            result = module_obj.test(vuln)
                            if result == False:
                                print("Test failed")
                            else:
                                print("Test succeeded")
                        else:
                            print("Module '" + module +
                                  "' does not have the vulnerability '" +
                                  vuln + "'")
                    else:
                        print("Module '" + module + "' does not exist")
            else:
                print("module: invalid subcommand '" + subcommand + "'")
예제 #10
0
	def __module(self, options):
		
		if len(options) == 0:
			print("Incomplete command")
			print("Valid sub-commands: add, remove, info, list, random, force, test")
		else:
			subcommand = options[0]
			del options[0]
			
			if subcommand == "add":
				
				if not len(options) == 1:
					print("module add: No module name")
				else:
					module_name = options[0]
					
					if module_util.module_exists(module_name):
						if not module_name in self.__vars['to_run']['value']:
							self.__vars['to_run']['value'].append(module_name)
							print("Module added")
						else:
							print("Module is already set to be run")
					else:
						print("Module '" + module_name + "' does not exist")
			elif subcommand == "random":	
				rand_list = []
				self.__vars['to_run']['value'] = []
				
				while len(rand_list) == 0:
				
					mod_list = module_util.get_module_list()
					
					set_level = self.__vars['level']['value']
					
					for module in mod_list:
						# Skip the test module
						if module == "test_module":
							continue
						
						mod_obj = module_util.import_module(module)
						
						if mod_obj:
							if set_level == "any":
								if ba_random().will_do():
									rand_list.append(module)
							else: 
								if mod_obj.has_difficulty(set_level) and ba_random().will_do():
									rand_list.append(module)
						else:
							print("Could not import module "+ module)
						
					
				for module_name in rand_list:
					self.__vars['to_run']['value'].append(module_name)		
						
			elif subcommand == "remove":
				if not len(options) == 1:
					print("module add: No module set")
				else:
					module_name = options[0]
					
					if module_util.module_exists(module_name):
						if module_name in self.__vars['to_run']['value']:
							self.__vars['to_run']['value'].remove(module_name)
							print("Module removed")
						else:
							print("Module is not set to run")
					else:
						print("Module '" + module_name + "' does not exist")			
			elif subcommand == "info":
				
				if not len(options) == 1:
					print("module info: No module name")
				else:
					module_name = options[0]
					
					if module_util.module_exists(module_name):
						tmp_module = module_util.import_module(module_name)
						print(tmp_module.info())
						
						print("Vulnerabilities:")
						for vuln in tmp_module.full_vulnerability_list():
							print("    " + vuln)
							
					else:
						print("Module '" + module_name + "' does not exist")	
			elif subcommand == "list":
				module_list = module_util.get_module_list()
				
				if len(module_list) > 0:
					for item in module_list:
						if item == "test_module":
							continue
						if item in self.__vars['to_run']['value']:
							print("\t+ " + item)
						else:
							print("\t- " + item)
				else:
					print("\nNo modules are set to run!")
			elif subcommand == "force":
				if not len(options) == 2:
					print("Enter a module and vulnerability to force")
				else:
					module = options[0]
					vuln = options[1]
					
					if module_util.module_exists(module):
						if vuln in module_util.import_module(module).full_vulnerability_list():
							if not module in self.__vars['force']['value']:
								self.__vars['force']['value'][module] = []
							
							if not vuln in self.__vars['force']['value'][module]:
								self.__vars['force']['value'][module].append(vuln)
							else:
								print("That vulnerability is already being forced")
						else:
							print("Module '" + module + "' does not have the vulnerability '" + vuln + "'")
					else:
						print("Module '" + module + "' does not exist")
			elif subcommand == "test":
				if self.__debug_mode == False:
					print("'module test' can only be used in debug mode")
				elif not len(options) == 2:
					print("Enter a module and vulnerability to test")
				else:
					module = options[0]
					vuln = options[1]
					
					if module_util.module_exists(module):
						module_obj = module_util.import_module(module)
						
						if vuln in module_obj.full_vulnerability_list():
							result = module_obj.test(vuln)
							if result == False:
								print("Test failed")
							else:
								print("Test succeeded")
						else:
							print("Module '" + module + "' does not have the vulnerability '" + vuln + "'")
					else:
						print("Module '" + module + "' does not exist")
			else:
				print("module: invalid subcommand '" + subcommand + "'")