Пример #1
0
    def attack(self, block):
        """Attack a given Range Query with a distinguishable first block

        This function can only be used under specific circumstances, which is why it is not the default function.
        To use it, change the Dictionary of the getAttackerFor-function in DRQPatternAttack.py to point to
        DFBPatternBRQ instead of DFBPatternPRQ, but be aware that it will not always work on small data sets.

        @param fb: The first block, as set
        @param rq: The remaining range query, as set
        @return: List of possible results
        """
        fb, rq = block
        res = []
        suspected_n = float(len(fb))
        rq.update(fb)
        rqlen = len(rq)
        pattern_length_max = math.ceil(rqlen / suspected_n)
        pattern_length_max += 2 * math.ceil(pattern_length_max / suspected_n)
        # Increase maximum pattern length, because duplicates could lead to a miscalculation of up to floor(real_pattern_length/real_N).
        # We are using ceil() to avoid border cases where the real M would lead to x in that calculation, while our detected M
        # only leads to x-1. Those cases would be few and far between, considering the chances of actually getting so many duplicates,
        # but nevertheless, they should be dealt with.
        pattern_length_min = math.floor(rqlen / (suspected_n+1))
        for key in fb: # Iterate through all elements of the first block
            if DB.isValidTarget(key) and (pattern_length_min <= DB.getPatternLengthForHost(key) <= pattern_length_max):
                # if the current element is a beginning of a pattern with the correct length...
                if DB.getPatternForHost(key) <= rq: # Check if the pattern is a subset of the remaining range query.
                    res.append(key)
        return res
Пример #2
0
    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
Пример #3
0
    def attack(self, rq):
        """Attack a given Range Query using the assumption from the class description.

        @param rq: A Range Query, as returned by generate.DRQ
        @return: list of possible results
        """
        res = []
        for element in rq: # Iterate through all elements (queries) of the given range query
            if DB.isValidTarget(element): # If the current element is the beginning of a pattern...
                # This checks if the pattern of the current element is a subset of the range query
                inter = rq & DB.getPatternForHost(element) 
                if len(inter) == DB.getPatternLengthForHost(element):
                    res.append(element)
        return res
Пример #4
0
    def attack(self, blocklist):
        """Attack a given range query with fully distinguishable blocks

        @param blocklist: A list of sets, each set representing a block, the main target in the first block.
        @return: List of possible results
        """
        res = []
        length = len(blocklist)
        for key in blocklist[0]: # Iterate through all candidates for the main target (as it must be in the first block)
            if DB.isValidTarget(key) and DB.getPatternLengthForHost(key) == length: # If it is the beginning of a pattern of the correct length...
                # The following is a method of determining if every block contains exactly one element of the pattern of the current candidate.
                tmp = blocklist[1:]
                cnt = {}
                for i in range(length-1):
                    cnt[i] = 0
                for query in DB.getPatternForHost(key):
                    if query != key:
                        for i in range(len(tmp)):
                            if query in tmp[i]:
                                cnt[i] += 1
                if not 0 in cnt.values():
                    res.append(key)
        return res