edit功能存在溢出,可以控制string对象,来实现任意地址读写
控制string对象,泄露出exe基址和dll的基址,然后就是泄露peb、teb地址,得到stack_base,为了能够准确得到栈rop的地址,我们在栈里布置一个字符串用来做TAG,然后利用任意地址读写从stack_base处开始搜索栈,直到找到我们布下的这个TAG。然后就是做ROP更改堆的执行权限后跳到堆里执行shellcode。
edit功能存在溢出,可以控制string对象,来实现任意地址读写
控制string对象,泄露出exe基址和dll的基址,然后就是泄露peb、teb地址,得到stack_base,为了能够准确得到栈rop的地址,我们在栈里布置一个字符串用来做TAG,然后利用任意地址读写从stack_base处开始搜索栈,直到找到我们布下的这个TAG。然后就是做ROP更改堆的执行权限后跳到堆里执行shellcode。
edit功能里的offset和size都为有符号数,因此,可以令offset为负数,size为整数,这样,可以对当前这个堆的上方任意地址进行写数据。
由于程序中全程使用的是write进行输出,加上程序没有show功能,因此,攻击IO_2_1_stdout的方法在这里就泄露不了数据。
栈溢出,可以利用3次
由于没有截断字符串,因此puts可以泄露出栈里的数据,在最后一次我们做rop重新回到main函数再一次进行利用,泄露出其他数据。由于windows上调用writefile的参数太多了,我们就直接使用kernel32.dll里的LoadLibraryA获得ucrtbase.dll加载地址,然后得到system地址,调用system(“cmd.exe”)来getshell。
根据这里的越界异或,将返回地址改为one_gadget。其中注意到能够异或的值是有限定的,可以异或(7 << (i - 1))的值,如下
1 | 00000011 |
用IDA分析一下,在edit功能里,没有检查length,可以直接溢出
由于是在windows server 2016上,所以堆header有加密,通过伪造header里的flag状态为0,然后设置好fd、bk,unlink即可。经过测试,在这个版本的windows上,可以直接unlink,只需要注意,在windows里fd和bk指向的是堆的content出,而不是header处。
首先,检查一下程序的保护机制
然后,我们用IDA分析一下,在Query的构造函数中,如果我们查询的name存在,则将对应的对象从容易里取出,获得其shared_ptr对象,关键在于调用了shared ptr的get函数,取得了对象的指针值,用这个指针值创建了一个新的shared_ptr对象。漏洞点在于,从一个shared_ptr对象里取得了被托管的对象的地址值创建了一个新的shared_ptr对象,因此,前面shard_ptr指针里的计数不会被传递给新创建的这个shared_ptr对象,因此这个局部的shared_ptr对象析构时,把受托管的对象也给free掉了。