示例#1
0
def unbits(s, endian='big'):
    """unbits(s, endian = 'big') -> str

    Converts an iterable of bits into a string.

    Arguments:
       s: Iterable of bits
       endian (str):  The string "little" or "big", which specifies the bits endianness.

    Returns:
       A string of the decoded bits.

    Example:
       >>> unbits([1])
       b'\\x80'
       >>> unbits([1], endian = 'little')
       b'\\x01'
       >>> unbits(bits(b'hello'), endian = 'little')
       b'\\x16\\xa666\\xf6'
    """
    if endian == 'little':
        u = lambda s: packing._p8lu(int(s[::-1], 2))
    elif endian == 'big':
        u = lambda s: packing._p8lu(int(s, 2))
    else:
        raise ValueError("unbits(): 'endian' must be either 'little' or 'big'")

    out = b''
    cur = b''

    for c in s:
        if c in ['1', 1, True]:
            cur += b'1'
        elif c in ['0', 0, False]:
            cur += b'0'
        else:
            raise ValueError(
                "unbits(): cannot decode the value %r into a bit" % c)

        if len(cur) == 8:
            out += u(cur)
            cur = b''
    if cur:
        out += u(cur.ljust(8, b'0'))

    return out
示例#2
0
def xor_pair(data, avoid=b'\x00\n'):
    """xor_pair(data, avoid = '\\x00\\n') -> None or (str, str)

    Finds two strings that will xor into a given string, while only
    using a given alphabet.

    Arguments:
        data (str): The desired string.
        avoid: The list of disallowed characters. Defaults to nulls and newlines.

    Returns:
        Two strings which will xor to the given string. If no such two strings exist, then None is returned.

    Example:

        >>> xor_pair(b"test")
        (b'\\x01\\x01\\x01\\x01', b'udru')
    """

    if isinstance(data, six.integer_types):
        data = packing.pack(data)

    if not isinstance(avoid, (bytes, bytearray)):
        avoid = avoid.encode('utf-8')

    avoid = bytearray(avoid)
    alphabet = list(packing._p8lu(n) for n in range(256) if n not in avoid)

    res1 = b''
    res2 = b''

    for c1 in bytearray(data):
        if context.randomize:
            random.shuffle(alphabet)
        for c2 in alphabet:
            c3 = packing._p8lu(c1 ^ packing.u8(c2))
            if c3 in alphabet:
                res1 += c2
                res2 += c3
                break
        else:
            return None

    return res1, res2
示例#3
0
 def style_byte(by):
     hbyte = '%02x' % by
     b = packing._p8lu(by)
     abyte = chr(by) if isprint(b) else '·'
     if hbyte in style:
         st = style[hbyte]
     elif isprint(b):
         st = style.get('printable')
     else:
         st = style.get('nonprintable')
     if st:
         hbyte = st(hbyte)
         abyte = st(abyte)
     return hbyte, abyte
示例#4
0
def xor_key(data, avoid=b'\x00\n', size=None):
    r"""xor_key(data, size=None, avoid='\x00\n') -> None or (int, str)

    Finds a ``size``-width value that can be XORed with a string
    to produce ``data``, while neither the XOR value or XOR string
    contain any bytes in ``avoid``.

    Arguments:
        data (str): The desired string.
        avoid: The list of disallowed characters. Defaults to nulls and newlines.
        size (int): Size of the desired output value, default is word size.

    Returns:
        A tuple containing two strings; the XOR key and the XOR string.
        If no such pair exists, None is returned.

    Example:

        >>> xor_key(b"Hello, world")
        (b'\x01\x01\x01\x01', b'Idmmn-!vnsme')
    """
    size = size or context.bytes

    if len(data) % size:
        log.error("Data must be padded to size for xor_key")

    words = lists.group(size, data)
    columns = [b''] * size
    for word in words:
        for i, byte in enumerate(bytearray(word)):
            columns[i] += bytearray((byte, ))

    avoid = bytearray(avoid)
    alphabet = bytearray(n for n in range(256) if n not in avoid)

    result = b''

    for column in columns:
        if context.randomize:
            random.shuffle(alphabet)
        for c2 in alphabet:
            if all(c ^ c2 in alphabet for c in column):
                result += packing._p8lu(c2)
                break
        else:
            return None

    return result, xor(data, result)
示例#5
0
    def _leak(self, addr, n, recurse=True):
        """_leak(addr, n) => str

        Leak ``n`` consecutive bytes starting at ``addr``.

        Returns:
            A string of length ``n``, or :const:`None`.
        """
        if not self.relative and addr < 0:
            return None

        addresses = [addr+i for i in range(n)]

        for address in addresses:
            # Cache hit
            if address in self.cache:
                continue

            # Cache miss, get the data from the leaker
            data = None
            try:
                data = self.leak(address)
            except Exception as e:
                if self.reraise:
                    raise

            if data:
                for i,byte in enumerate(bytearray(data)):
                    self.cache[address+i] = _p8lu(byte)

            # We could not leak this particular byte, search backwards
            # to see if another request will satisfy it
            elif recurse:
                for i in range(1, self.search_range):
                    data = self._leak(address-i, i+1, False)
                    if address in self.cache:
                        break
                else:
                    return None

        # Ensure everything is in the cache
        if not all(a in self.cache for a in addresses):
            return None

        # Cache is filled, satisfy the request
        return b''.join(self.cache[addr+i] for i in range(n))
示例#6
0
    def sets(self, addr, val, null_terminate = True):
        r"""Set known string at `addr`, which will be optionally be null-terminated

        Note that this method is a bit dumb about how it handles the data.
        It will null-terminate the data, but it will not stop at the first null.

        Examples:

            >>> l = MemLeak(lambda x: b'')
            >>> l.cache == {}
            True
            >>> l.sets(0, b'H\x00ello')
            >>> l.cache == {0: b'H', 1: b'\x00', 2: b'e', 3: b'l', 4: b'l', 5: b'o', 6: b'\x00'}
            True
        """
        if null_terminate:
            val += b'\x00'

        for i,b in enumerate(bytearray(val)):
            self.cache[addr+i] = _p8lu(b)
示例#7
0
def update_cyclic_pregenerated(size):
    global cyclic_pregen
    while size > len(cyclic_pregen):
        cyclic_pregen += packing._p8lu(next(de_bruijn_gen))
示例#8
0
 def get(n):
     rv = 0
     for s in strs:
         rv ^= s[n % len(s)]
     return packing._p8lu(rv)
示例#9
0
 def compare(self, address, bts):
     for i, byte in enumerate(bytearray(bts)):
         if self.n(address + i, 1) != _p8lu(byte):
             return False
     return True
示例#10
0
 def _set(self, addr, val, ndx, size):
     addr += ndx * size
     for i,b in enumerate(bytearray(pack(val, size*8))):
         self.cache[addr+i] = _p8lu(b)