Pwnable.tw secretgarden



Use after free vulnerability
在做出本题目之后,在Pwnable.tw上看其他师傅的wp,简直把heap玩出了花,原本一个不算复杂的Fastbin attack,竟然能够写到main_arena,IO_stdout,stack,realloc_hook中,各种姿势,让我受益匪浅,真是人外有人,天外有天。于是,特意总结了一下所有wp的基本姿势,总结在Blog中。

Reverse

程序是典型的选单程序,其中分为以下5个操作:

  1. Raise a flower
  2. Visit the garden
  3. Remove a flower from the garden
  4. Clean the garden
  5. Leave the garden"

其中raise a flower中为每一个flower建立了如下的数据结构:

其中name通过malloc(size)分配,size大小由用户自己制定。

remove flower与clean graden都是移除flower的操作,但是也有不同

remove flower的目的是去除flag位,free掉name,在free前它仅仅检查了index的合法性和存在性,并且没有在free后对指针进行置空,所以存在use after free,可以double free。

clean graden是在remove flower基础上操作:

free掉所有flag=0的flower的结构,并且将指针置空,不存在明显漏洞
Visit garden是打印所有flower信息,leave garden是结束进程。

Exploit

首先利用Unsotred bin 泄露出Unsorted(av)即libc的地址,这点不再赘述
因为PIE开启,而在heap中没有明显的泄露进程段的位置,泄露proc基地址不现实,那么double free可用的方式最好是Fastbin attack。

__malloc_hook

通过hook函数劫持程序控制流,利用uaf-double free 能够进行fastbin attack
虽然我们一般使用的__free_hook附近没有合适的size,但是在__malloc_hook附近情况如下:

fastbin在分配时并不检查对齐情况,利用偏移,将fastbin的header地址设置为__malloc_hook-0x23,从而利用size=0x7f触发fastbin attack,将__malloc_hook修改为one_gadgets。

一般malloc触发的方式,one_gadgets由于限制条件不满足,执行都不会成功,可以考虑malloc_printerr触发,恰好[esp+0x50]=0

该one_gadgets可以执行成功

Scipt:

__free_hook

刚刚提到通过__free_hook攻击比较困难,就被打脸了。

思路简要概括如下:

1.使用UnsortedBins泄露出libc地址,使用Fastbins泄露出heap地址。
2.使用fastbin attack 攻击main_arena。
在攻击main_arnea时,攻击的地址在FastbinY数组中,可能需要特意构造一个合适大小的Fastbin,并且fastbin的地址开头(即伪造fake fastbin的size)的大小不能是0x55,否则程序会在_libc_malloc.c中crash。

具体原因不得而知…
如下是FastbinAttack写入main_arena中的情况

3.劫持*topchunk,改写成__free_hook-0xb58。因为topchunk必须有一个比较大的size,在_free_hook向上找到__free_hook-0xb58合适。
4.不断分配chunk,使得最终malloc的地址到达_free_hook。在分配时也有一定的讲究,不能够分配过大的chunk,会造成malloc使用sysmalloc分配,同时也注意scanf内部也是会调用malloc的….
这个坑,我也是很久没有跳出来,按照作者的分配方式就不会出现问题….而过大过小都会出现topchunksize=0的问题,不明觉厉,还请看过的师傅们指教。
5.最后修改__free_hooksystem,free一个"/bin/sh"的chunk,触发system(“/bin/sh”) Getshell。

佩服师傅对heap的深入理解,自己在操作时都跳了好几次坑….
而且从wp中看出师傅的思路异常清晰….

_IO_2_1_stdout_

File stcuct exploit 在最近一年的ctf流行了起来,在本题中攻击stdout的file结构的方式我认为是最简单的。

利用fastbin attack 攻击Stdout的file 结构_IO_2_1_stdout,更改stdout 的vtable指向one_gadgets,如下所示:

当然也可以直接构造一个填充着one_gadgets的heap chunk,将_IO_jump_t的地址更改为该chunk地址即可,过程不再赘述。

__realloc_hook

在地址上__malloc_hook__realloc_hook是相邻的,在攻击malloc_hook我们没有能够成功执行one_gadgets,但是我们可以通过将__malloc_hook更改为_libc_realloc+0x20,将__realloc_hook更该为one_gadgets。

这样的好处在于,我们能够控制__malloc_hook指向的代码的内容,规避掉_libc_realloc中部分指令,从而更改在执行one_gadgets时的占空间,创建能够成功执行one_gadgets的栈空间。这是一个很巧妙的点…MAGIC!

Rop

利用Fastbin attack攻击栈

  1. information leak.
    题目中存在double free,我们能够得到environ的地址,通过Use after free,构造flower a的manger chunk与flower b的name chunk指向同一个地址空间,即我们可以通过编辑b name中的内容,打印flower a,泄露地址,即可顺利泄露得到stack 地址。
  2. Fastbin Dup in stack.
    在stack中,注意观察找到合适size=0x7f的位置,然后将malloc引入栈。
  3. Rop chain execve atfer read.
    构造好Rop chain,在read()执行结束后,Payload 写入栈中,由于题目中存在Canary,不能贸然写到fuction的返回地址,但敲好能够覆盖read返回地址,计算offset,写入payload即可。

发表评论