【CISCN2021Final】Binary_Cheater
来复现下肥猫出的题目
至于漏洞点我就不贴了,就是个2.32下的uaf,然后开了沙盒,然后限制在了largebin,这里我就直接调它的exp了。
因为开了混淆,所以我没怎么看反汇编,这里知道的是使用calloc函数。
首先申请了四个堆块
add(0x410,'c7')#0 |
然后释放两个堆块
free(0) |
这里就是很传统的放两个chunk进unsortedbin中,然后申请一个大的chunk之后就能把这两个chunk放到largebin中
add(0x450,'ca')#4 |
可以看到上面的图,申请了大的chunk之后确实把两个chunk放入到了largebin中
show(0) |
然后因为存在uaf,就可以理所当然的把libc基址和heap基址都泄露出来。这里有个值得注意的点,就是高版本,我也不知道到底是从哪个版本开始的,就是放入到unsorted bin中的地址,也就是main_arena+96的地方,低位变成了00,所以会存在截断的问题,这里放入到了largebin后,泄露的就不是main_arena+96了,所以就不用担心截断的问题。
然后再把这两个chunk申请回来,然后释放
add(0x410,'ca')#5 |
那么此时的一个状态就是如下
在unsortedbin中存在一个chunk,然后我们申请一个比他大的chunk,把他放到largebin中,然后呢,我们继续释放一个chunk进入到unsortedbin中
add(0x450,'ca')#7 |
那么此时就是一个标准的largebin attack的一个状态,在largebin中存在一个chunk,然后呢unsorted bin中也存在一个chunk,还要注意下他的大小关系,就是unsorted bin中的chunk比largebin中的小,别问为什么,忘记了。此时我们只需要修改largebin中的那个chunk的bk_nextsize域后申请chunk就能够达成攻击。
stderr = libc_base + libc.sym['stderr'] |
这里我们将largebin中的chunk,也就是0x55555555db30的chunk的bk_nextsize域改写成了stderr-0x20的地方,这样就可以在stderr的地方写上一个堆地址,这个地址是什么呢,就是放入到largebin中的chunk的地址,即0x55555555d2b0。
add(0x450,'c7')#8 |
可以看到攻击达成后,我们的stderr被修改成了堆地址。
可以看下我们原来的stderr
然后是我们伪造的
然后就是重复刚才的操作,刚刚从unsortedbin放入到largebin的chunk,申请回来后又释放,这次攻击tcache指针,怎么找这个指针呢,直接search heapbase+0x10的地方就行了
add(0x410,'ca')#9 |
add(0x450,'cb')#10 |
可以看到tcache指针的内容也被我们修改成了我们可控的堆块地址。
继续重复操作,这次我们攻击top chunk
add(0x410,'cc')#11 |
我们知道我们在main_arena+96存放着top_chunk的指针
add(0x450,'ca')#12 |
攻击成功后,可以看到top chunk的指针被我们修改成了可控的堆块地址。
到这里,我们的stderr、tcache指针、top chunk指针都被修改成了同一个可控的chunk。
攻击完成后,我们看下结构
接下来就是修改我们可控的那个chunk的内容。
调用链:
calloc -> _int_malloc -> sysmalloc -> _malloc_assert -> __fxprintf -> locked_vfxprintf -> _vfprintf_internal -> _IO_str_overflow