DWORD Shoot利用Crt库free函数
来源:互联网 发布:淘宝客代运营 编辑:程序博客网 时间:2024/05/29 08:20
之前写过Win32运行库的DWORD Shoot,随着windows安全性检查的升级,简单的DWORD shoot并不能达到利用程序的目的。但是这种技术就被淘汰了吗?我个人觉得并不是这样,因为DWORD shoot技术本质上是钻了链表出链时不检查内存地址合法性的漏洞,因此只要在代码中找到有链表存在的影子就有利用的可能。
C Programmer一般用Crt运行库提供的库函数malloc/free管理程序的内存,而malloc最终调用HeapAlloc分配内存。我们知道HeapAlloc分配的内存块是_HEAP_ENTRY+用户可见区+尾块的形式,malloc调用HeapAlloc,因此它获得的内存块也遵循这样的形式。无非Crt管理器将用户可见区一部分内存挪为己用。这部分内存用_CrtMemBlockHeader结构进行管理,在VS2010中的定义为:
typedef struct _CrtMemBlockHeader{ struct _CrtMemBlockHeader * pBlockHeaderNext; struct _CrtMemBlockHeader * pBlockHeaderPrev; char * szFileName; int nLine;#ifdef _WIN64 /* These items are reversed on Win64 to eliminate gaps in the struct * and ensure that sizeof(struct)%16 == 0, so 16-byte alignment is * maintained in the debug heap. */ int nBlockUse; size_t nDataSize;#else /* _WIN64 */ size_t nDataSize; int nBlockUse;#endif /* _WIN64 */ long lRequest; unsigned char gap[nNoMansLandSize]; /* followed by: * unsigned char data[nDataSize]; * unsigned char anotherGap[nNoMansLandSize]; */} _CrtMemBlockHeader;
从pBlockHeaderNext和pBlockHeaderPrev域,可以看出crt库以双向链表的方式用来管理所有调用malloc分配出去内存块。如果调用free时,crt库并没有检查pBlockHeaderNext和pBlockHeaderPrev变量的合法性,就在无意中为我们提供了利用的机会。分别查看vs2010下Debug版本和Release版本对free的调用堆栈,可以看到如下输出:
;release版本0:000> bp ntdll!RtlFreeHeap0:000> gBreakpoint 1 hit0:000> kbChildEBP RetAddr Args to Child 0012ff5c 00401049 00390000 00000000 003928e8 ntdll!RtlFreeHeap0012ff70 00401b6f 003928e8 7ffda000 00f0f6ee malloc!free+0x1c [f:\dd\vctools\crt_bld\self_x86\crt\src\free.c @ 51] //_free_base (void * pBlock)0012ff84 004011f4 3aeb8a72 00f0f6ee 00f0f7aa malloc!_wsetenvp+0x9d [f:\dd\vctools\crt_bld\self_x86\crt\src\stdenvp.c @ 139]0012ffc0 7c817067 00f0f6ee 00f0f7aa 7ffda000 malloc!__tmainCRTStartup+0xd0 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 259];debug版本0:000> bp ntdll!RtlFreeHeap0:000> gBreakpoint 1 hit0:000> kbChildEBP RetAddr Args to Child 0012fef4 00431839 00390000 00000000 00392930 ntdll!RtlFreeHeap0012ff10 00428f6e 00392930 00392930 0012ff58 malloc!_free_base+0x29 [f:\dd\vctools\crt_bld\self_x86\crt\src\free.c @ 50]0012ff20 00428a70 00392950 00000002 7ce76772 malloc!_free_dbg_nolock+0x4ae [f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c @ 1431]0012ff58 0042d57b 00392950 00000002 00000012 malloc!_free_dbg+0x50 [f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c @ 1265]0012ff78 00427557 7ce76792 00f6f6ee 00f6f7a6 malloc!_wsetenvp+0x16b [f:\dd\vctools\crt_bld\self_x86\crt\src\stdenvp.c @ 138]0012ffb8 0042746f 0012fff0 7c817067 00f6f6ee malloc!__tmainCRTStartup+0xd7 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 259]借助调用堆栈在结合crt源码,可知Release版本的程序并没有使用_CrtMemBlockHeader结构管理堆内存;而Debug版本的程序使用_CrtMemBlockHeader用于管理调用malloc分配的堆内存,更重要的一点,vs2010调用free从链表中移除已分配的堆内存时并没有做安全检查,于是,我们有了DWORD Shoot的机会。很幸运的是,crt管理的双向链表和Windows堆管理器管理的空闲链表数组FreeList[128]不同:在win xp sp1以上的系统上,堆管理器对堆分配释放进行严格的安全检查(严格检查_HEAP_ENTRY,_Free_HEAP_ENTRY等结构的正确性),因此出现了文章开头提到的DWORD shoot失效的情况;但是crt提供的堆管理并不在进程堆管理器的管理范围之内(毕竟,对于OS来说_CrtMemBlockHeader结构是在用户可见内存范围内),换句话说,DWORD shoot crt库的free函数是一个很好的选择。
附注,本文分析利用crt库的可行性,具体的事实过程和前面几篇blog大同小异,因此就不细写了。
参考资料:张银奎 <软件调试> 23章 Crt运行库
0 0
- DWORD Shoot利用Crt库free函数
- DWORD SHOOT
- xp sp3不让dword shoot
- xp下堆溢出DWORD SHOOT---狙击空闲表
- 堆溢出(二)空表DWORD SHOOT
- 堆溢出(三)快表DWORD SHOOT
- shoot
- 函数GetTickcount和DWORD关键字
- DWORD
- DWORD
- DWORD
- dword
- CRT 入口函数 CRTStartup
- 废弃的CRT函数
- CRT函数解读
- free ()函数
- free()函数
- free()函数
- 遗传算法初步理解
- Struts2.0学习笔记---关于重定向与携带信息
- 详解Configuration对象
- 前端编码规范之CSS
- javascript 异步编程
- DWORD Shoot利用Crt库free函数
- 10min了解ContentProvider
- C语言入门与进阶书籍汇总
- 遗传算法改进
- Java 线程池 四种创建方式
- oracle 12C数据库PSU补丁安装方式的变化---新增datapatch
- DOJ Round #1 解题报告
- 学习安装单机版Hadoop记录
- centos停止运行中的wget操作