环境
Windows 7 32位(原始镜像安装完就行)
windbg
ida
漏洞分析
打开软件:在命令行输入fxscover
windbg附加,打开poc,点击确定
windbg断下
1 | 0:005> g |
堆栈调用显示如下:
1 | 0:000> kv |
其实上面可以看DeleteContents,Remove这个函数,应该是跟释放相关
触发异常的地址是已经free掉了的,那感觉是释放后重用,这个需要后面再确认
1 | 0:000> !heap -p -a 01de1ad8 |
我的gflags没有开
1 | 0:000> !gflag |
下面开启页堆,hpa(其实使用hfc【heap free check】更精准一点)
1 | 0:005> !gflag +hpa |
重新打开poc触发下面异常
1 | 0:005> g |
我们这时候再看下堆栈
1 | 0:000> kb |
开启页堆后,我们可以看得更多, FXSCOVER!CDrawDoc::Remove之后调用析构函数,再调用msvcrt!free,再之后通过ntdll的函数真正去free
那我们尝试在msvcrt!free+0x33下断点,并输出要free的地址看看是不是double free
1 | 0:009> u msvcrt!free+0x33 |
断点如下:
1 | bp msvcrt!free+0x33 "r esi;!heap -p -a esi;gc" |
跟着你就可以喝杯茶,回来看到最后一条记录
1 | esi=01e47a10 |
可以看到这时是去free一个已经free过了01e47a10,我们网上翻(其实是将记录复制下来ctrl+f),就可以看到下面这条记录
1 | esi=01e47a10 |
所以非常明显,这是一个double free
补丁对比
其实这个很难调试去发现为什么会双重释放,补丁对比会发现为什么
因为是doc那个函数出的错,我们去看这个函数
增加了IsObjectAlreadySerialized的检测,如果已经序列化过了,说明已经free过了,以为序列化的时候会free