Exemple #1
0
def buffer(sendprintf: Callable[[bytes],bytes], maxlen=20) -> int:
    '''Bruteforcer to locate the offset of the input string itself.
    i.e. if buffer() returns 6,
        printf("%6$d") gives the value of p32("%6$p")

    Arguments:
        `sendprintf`: a function that simulates a single printf() call.
            This is much like the function passable to pwntools' FmtStr().
            e.g.
                def printf(l: bytes):
                    r = process('./mybinary')
                    r.send(l)
                    return r.recvline()
                buffer = fsb.find_offset.buffer(printf)
        `maxlen`: the maximum length of the input. If no value
            is given, the program assumes maxlen=20.

        Larger values of `maxlen` will allow for faster offset guessing.
    '''
    # Note: if config.PRINTF_MAX becomes really large, this might break
    guess_n = (maxlen-len("0x%10$x\n")) // context.bytes
    # So long as more than 1 guess can be done at a time:
    if guess_n > 1:
        '''Let's say guess_n=3 words worth of cyclic() can be inputted.
        If config.PRINTF_MIN=5, then the first payload ought to be
            cyclic(3*context.bytes) + "0x%{}$x\n".format(5+(3-1))
        because the first guess should be able to catch any offset in the range
            range(config.PRINTF_MIN, config.PRINTF_MIN+guess_n)
        '''
        for offset in range(config.PRINTF_MIN+guess_n-1, config.PRINTF_MAX+guess_n-1, guess_n):
            payload = cyclic(guess_n*context.bytes) + "0x%{}$x\n".format(offset).encode()
            extract = sendprintf(payload)
            if b"(nil)" in extract: extract = 0
            else: extract = unpack_hex(extract)    # Error will be -1
            if extract != -1 and 0 <= (found := cyclic_find(p32(extract))) < len(payload):
                assert found%context.bytes == 0 # if not, the offset is non-aligned
                log.info('%s for buffer: %d' % (__name__, offset-found//context.bytes))
                return offset-found//context.bytes
        raise RuntimeError  # Give up
Exemple #2
0
 def offset(self, **kwargs):
     try:
         length_ = kwargs['length']
         self.__offset = bytes(length_ * 'x', self.__encoding)
     except KeyError:
         try:
             target_ = kwargs['match']
             if type(target_) == 'int':
                 target_ = pack(target_)
             elif type(target_) == 'str':
                 target_ = bytes(target_, self.__encoding)
             length_ = cyclic_find(target_, n=len(target_)) - len(
                 self.__padding) - len(self.__eip)
             self.__offset = bytes(length_ * 'x', self.__encoding)
             print(f"[+] Offset => {self.__offset}\n")
         except KeyError:
             raise ValueError(
                 "[-] Only 'length' and 'match' are valid arguments\n")
Exemple #3
0
def main():
    args = parser.parse_args()
    alphabet = args.alphabet
    subsize = args.length

    if args.lookup:
        pat = args.lookup

        if pat.startswith('0x'):
            pat = packing.pack(int(pat[2:], 16), subsize * 8, 'little',
                               'unsigned')
        elif pat.isdigit():
            pat = packing.pack(int(pat, 10), subsize * 8, 'little', 'unsigned')

        if len(pat) != 4:
            log.critical('Subpattern must be 4 bytes')
            sys.exit(1)

        if not all(c in alphabet for c in pat):
            log.critical(
                'Pattern contains characters not present in the alphabet')
            sys.exit(1)

        offset = cyclic.cyclic_find(pat, alphabet, subsize)

        if offset == -1:
            log.critical('Given pattern does not exist in cyclic pattern')
            sys.exit(1)
        else:
            print offset
    else:
        want = args.count
        result = cyclic.cyclic(want, alphabet, subsize)
        got = len(result)
        if got < want:
            log.failure("Alphabet too small (max length = %i)" % got)

        sys.stdout.write(result)

        if sys.stdout.isatty():
            sys.stdout.write('\n')
Exemple #4
0
def main():
    args = parser.parse_args()
    alphabet = args.alphabet
    subsize  = args.length

    if args.lookup:
        pat = args.lookup

        if pat.startswith('0x'):
            pat = packing.pack(int(pat[2:], 16), subsize*8, 'little', False)
        elif pat.isdigit():
            pat = packing.pack(int(pat, 10), subsize*8, 'little', False)

        if len(pat) != subsize:
            log.critical('Subpattern must be %d bytes' % subsize)
            sys.exit(1)

        if not all(c in alphabet for c in pat):
            log.critical('Pattern contains characters not present in the alphabet')
            sys.exit(1)

        offset = cyclic.cyclic_find(pat, alphabet, subsize)

        if offset == -1:
            log.critical('Given pattern does not exist in cyclic pattern')
            sys.exit(1)
        else:
            print offset
    else:
        want   = args.count
        result = cyclic.cyclic(want, alphabet, subsize)
        got    = len(result)
        if got < want:
            log.failure("Alphabet too small (max length = %i)" % got)

        sys.stdout.write(result)

        if sys.stdout.isatty():
            sys.stdout.write('\n')
Exemple #5
0
def check_pattern(s):
    print("[+] Checking pattern")
    index = pattern.cyclic_find(s, alphabet=string.ascii_letters)
    print("[+] Pattern at {}".format(index))
    exit(0)