def generateBaseDRQ(self, domain): """Generator for Basic DNS Range Queries (randomly generated query sets) Queries are unique inside their respective sets, but may appear more than once across different query blocks. @param domain: Domain for which a DNS Range Query should be generated @return: List of Sets, in order, each set representing a query block """ if not DB.isValidTarget(domain): Error.printErrorAndExit(domain + " is not a valid target") patlen = DB.getPatternLengthForHost(domain) block = [set()] pattern = DB.getPatternForHost(domain) # Get the actual pattern of the target randoms = DB.getRandomHosts((Config.RQSIZE-1)*len(pattern)) # Get random hosts (dummies) pattern.remove(domain) block[0].add(domain) i = 1 for subquery in pattern: # Create the blocks that will hold dummies and actual queries block.append(set()) block[i].add(subquery) # Add the actual query to its respective block i += 1 for query, index in zip(randoms, cycle(range(patlen))): # distribute the randomly chosen dummy queries as evenly as possible across the blocks block[index].add(query) return block
def generateBaseDRQ(self, domain): """Generator for Pattern-Based DNS Range Queries (trying to fill the query blocks with patterns) Queries are unique inside their respective sets, but may appear more than once across different query blocks. @param domain: Domain for which a DNS Range Query should be generated @return: List of Sets, in order, each set representing a query block """ if not DB.isValidTarget(domain): Error.printErrorAndExit(domain + " is not a valid target") pattern_length = len(DB.PATTERNS[domain]) block = [set()] num_of_available_patterns = DB.getNumberOfHostsWithPatternLength(pattern_length) - 1 if num_of_available_patterns >= Config.RQSIZE: hosts = set([domain]) hosts.update(set(DB.getRandomHostsByPatternLengthB(pattern_length, Config.RQSIZE-1, hosts))) pattern_copy = {} for host in hosts: pattern_copy[host] = DB.getPatternForHost(host) pattern_copy[host].remove(host) block[0].add(host) for i in range(1, pattern_length, 1): block.append(set()) for host in pattern_copy: block[i].add(pattern_copy[host].pop()) else: num_of_needed_patterns = Config.RQSIZE - (num_of_available_patterns+1) padding = [] for i in range(num_of_needed_patterns): # Find patterns whose lengths sum to pattern_length (if any exist that have not been chosen yet) pad1_len = pad2_len = -1 for pad1_len, pad2_len in zip(range(1, pattern_length/2+1, 1), range(pattern_length-1, pattern_length/2-1, -1)): # This is a construct that generates numbers that sum to pattern_length. It is used instead of truly random # numbers because it will not get stuck when no more patterns are available. if ((DB.getNumberOfHostsWithPatternLengthB(pad1_len, block[0]) > 0) and \ (DB.getNumberOfHostsWithPatternLength(pad2_len) > 0)): break elif pad1_len == pattern_length/2: # No patterns of the correct length have been found, abort pad1_len = -1 if (pad1_len == -1): # Break out of loop as no further patterns can be found. break # The following few lines get the dummy patterns from the database and saves them to the list of dummy-patterns pad1_host = DB.getRandomHostsByPatternLengthB(pad1_len, 1, block[0])[0] pad1_pattern = DB.getPatternForHost(pad1_host) pad1_pattern.remove(pad1_host) block[0].add(pad1_host) padding.append([pad1_host]) for host in pad1_pattern: padding[i].append(host) pad2_host = DB.getRandomHostsByPatternLength(pad2_len, 1)[0] pad2_pattern = DB.getPatternForHost(pad2_host) pad2_pattern.remove(pad2_host) padding[i].append(pad2_host) for host in pad2_pattern: padding[i].append(host) # We now have as many dummy patterns as we will get. Start distributing them. pattern_copy = {} block[0].add(domain) pattern_copy[domain] = DB.getPatternForHost(domain) pattern_copy[domain].remove(domain) for element in DB.getRandomHostsByPatternLengthB(pattern_length, num_of_available_patterns, block[0]): # Get all patterns with the correct length and add them to the range query pattern_copy[element] = DB.getPatternForHost(element) pattern_copy[element].remove(element) block[0].add(element) for i in range(1, pattern_length, 1): # Distribute the remaining patterns (those whose lengths sum to the correct length) block.append(set()) for host in pattern_copy: block[i].add(pattern_copy[host].pop()) for pattern in padding: block[i].add(pattern[i]) return block