通过堆进行信息泄漏¶
什么叫信息泄漏¶
在CTF中,Pwn题目一般都是运行在远端服务器上的。因此我们不能获知服务器上的libc.so地址、Heap基地址等地址信息,但是在进行利用的时候往往需要这些地址,此时就需要进行信息泄漏。
信息泄漏的目标¶
信息泄漏的目标有哪些?我们可以通过观察内存空间来获知这一点
Start End Offset Perm Path
0x0000000000400000 0x0000000000401000 0x0000000000000000 r-x /home/pwn
0x0000000000600000 0x0000000000601000 0x0000000000000000 r-- /home/pwn
0x0000000000601000 0x0000000000602000 0x0000000000001000 rw- /home/pwn
0x0000000000602000 0x0000000000623000 0x0000000000000000 rw- [heap]
0x00007ffff7a0d000 0x00007ffff7bcd000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7bcd000 0x00007ffff7dcd000 0x00000000001c0000 --- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dcd000 0x00007ffff7dd1000 0x00000000001c0000 r-- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dd1000 0x00007ffff7dd3000 0x00000000001c4000 rw- /lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dd3000 0x00007ffff7dd7000 0x0000000000000000 rw-
0x00007ffff7dd7000 0x00007ffff7dfd000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7fdb000 0x00007ffff7fde000 0x0000000000000000 rw-
0x00007ffff7ff6000 0x00007ffff7ff8000 0x0000000000000000 rw-
0x00007ffff7ff8000 0x00007ffff7ffa000 0x0000000000000000 r-- [vvar]
0x00007ffff7ffa000 0x00007ffff7ffc000 0x0000000000000000 r-x [vdso]
0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000025000 r-- /lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7ffd000 0x00007ffff7ffe000 0x0000000000026000 rw- /lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw-
0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack]
0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
通过什么进行泄漏¶
通过前面的知识我们知道heap分为unsorted bin、fastbin、smallbin、large bin等,我们逐个考察这些结构来查看如何进行泄漏。
unsorted bin¶
我们构造两个unsorted bin然后查看它的内存,现在在unsorted bin链表中存在两个块,第一个块的地址是0x602000、第二个块的地址是0x6020f0
0x602000: 0x0000000000000000 0x00000000000000d1
0x602010: 0x00007ffff7dd1b78 0x00000000006020f0 <=== 指向下一个块
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x6020f0: 0x0000000000000000 0x00000000000000d1
0x602100: 0x0000000000602000 0x00007ffff7dd1b78 <=== 指向main_arena
0x602110: 0x0000000000000000 0x0000000000000000
0x602120: 0x0000000000000000 0x0000000000000000
fastbin¶
我们构造了两个fastbin然后查看它们的内存,现在在fastbin链表中存在两个块,第一个块的地址是0x602040,第二个块的地址是0x602000
0x602000: 0x0000000000000000 0x0000000000000021
0x602010: 0x0000000000000000 0x0000000000000000
0x602040: 0x0000000000000000 0x0000000000000021
0x602050: 0x0000000000602000 0x0000000000000000 <=== 指向第一个块
smallbin¶
我们构造了两个fastbin然后查看它们的内存,现在在fastbin链表中存在两个块,第一个块的地址是0x602000,第二个块的地址是0x6020f0
0x602000: 0x0000000000000000 0x00000000000000d1
0x602010: 0x00007ffff7dd1c38 0x00000000006020f0 <=== 下一个块的地址
0x602020: 0x0000000000000000 0x0000000000000000
0x602030: 0x0000000000000000 0x0000000000000000
0x6020f0: 0x0000000000000000 0x00000000000000d1
0x602100: 0x0000000000602000 0x00007ffff7dd1c38 <=== main_arena的地址
0x602110: 0x0000000000000000 0x0000000000000000
0x602120: 0x0000000000000000 0x0000000000000000
哪些漏洞可以用于泄漏¶
通过前面的知识我们可以获知堆中存在哪些地址信息,但是想要获取到这些地址需要通过漏洞来实现 一般来说以下漏洞是可以进行信息漏洞的
- 堆内存未初始化
- 堆溢出
- Use-After-Free
- 越界读
- heap extend
0x01 read UAF¶
通过,UAF ,泄露 heapbase:
p0 = malloc(0x20);
p1 = malloc(0x20);
free(p0);
free(p1);
printf('heap base:%p',*p1);
由于 fastbin list 的特性,当我们构造一条fastbin list的时候
(0x30) fastbin[1]: 0x602030 --> 0x602000 --> 0x0
存在 chunk 1 -> chunk 0 的现象,如果此时 UAF漏洞存在,我们可以通过 show chunk 1,将chunk 0的地址打印出来
同理,泄露 libc base
p0 = malloc(0x100);
free(p0);
printf("libc: %p\n", *p0);