0x0 程序保护和流程
保护:
流程:
main()
real_main()
add()
依次输入aaaa,100,0x50,aaaa后的会分配两个堆块。
heap_pointer的情况。
del()根据输入的名字free掉相应的堆块,list()输出所有的信息,change_price()可以修改价格。
change_descrip()
在这个函数中,如果输入的size和原来的不一样的话就会调用realloc函数重新分配堆块。如果size比原来大则会free掉原来的堆块,并且重新分配一个堆块,但是程序并没有对指针信息进行修改,形成了一个UAF。
0x1 利用过程
1.由于题目给出了libc,首先需要确定libc的版本。
确定libc版本后选择ubuntu16.04作为复现的系统。
2.要想泄露函数的真实地址必须使用输出函数进行输出,而程序给出的输出函数是根据&heap_pointer)[index] + 6中的地址输出字符串。
3.通过以上的分析可以的得出,如果可以控制&heap_pointer)[index] + 6中的数据再配合change_descrip()函数就可以实现任意地址读写了。
4.UAF(use after free),顾名思义就是在释放完堆块之后还可以对其进行操作,如果对Linux的堆管理器有一定认识的话可以知道,在堆块释放完之后,如果重新申请的堆块大小合适,会将之前已经释放的堆块重新分配。也就是说当程序在realloc函数的时候size比原来大,free掉之前的chunk,再重新调用add()生成两个堆块,第一个堆块的位置会落在之前被realloc函数free掉的函数中,并且第一个堆块中存放的数据的地址信息可以被之前的指针进行修改,这样的话就可以实现任意地址读写。
首次add。
再次add,防止realloc直接向topchunk申请内存。
修改首次add的堆块大小。
这时首次add的堆块的指向description仍然指向原来的位置,而原来的位置已经被free了(配合上图食用)。
这时再add一个。