最近两年来windows的堆栈溢出问题变得愈来愈流行了。本文向读者介绍了常用的堆栈漏洞发现方法为啥对新平台(xp sp2与win 2003)不适用了,因为微软修改了winxp,winxp sp1,与win2000的堆栈保护机制。文章告诉读者如何绕过第一层保护,来触发内存中的数据覆写。
堆栈是一块块连续的内存结合,当一个程序要动态分配内存时,分配的动作将发生在堆栈中,象malloc(),globalalloc(),localalloc()与heapalloc()等功能函数只是核心函数rtlallocateheap()的外衣,由ntdll.dll文件提供的api负责在堆栈中分配内存。还有其他的rtl*heap()函数,负责生成与撤销堆栈,以及处理堆栈中的内存块。每个内存块都含有一个头,这个头详细描述了本块与前一块的大小,块是否正在忙的状态,以及该块位于内存的哪个段位中,块头一般是8位长,接着是块在实际存储区域。如果块空闲,则有两个针指向该标准头,这些针叫flink与blink,就是前连与后连的意思。参考图 【相关文章:如何选择您的网络的最佳路由器交换路径】
windows的堆栈溢出的概览 【扩展阅读:对传统路由协议的扩展可以最大限度地减少网】
当溢出发生时,当前临近块的指示头的结构就被覆写了,通过伪造‘恶意’值,将引起后续的堆栈操作,就可能触发一个任意的4字节内存覆写。其实这只是发现堆栈机制的一个简单方法-叫做切断连接。假设我们来溢出一个自由块中的内容,以下2条汇编指令可以完成切断连接的过程: 【扩展信息:Cisco路由器的口令恢复技巧】
560)this.style.width=560; onmousewheel = javascript:return big(this) height=137 alt="" src="/files/uploadimg/20051009/1015570.jpg" width=337 border=0>
mov [reg1], reg2 ; reg1=flink
mov [reg2+4], reg1 ;reg2=blink 这样伪造了flink与blink并导致4字节内存覆写后,下一步就可以获得控制权了。windows堆栈保护简介
常见的堆栈保护技术在windows xp,windows xp sp1与win2000等操作系统中使用得很好。但是随着windows 2003的出现,微软为了在分配与解除内存块之前验证块的有效性,对堆栈的管理例程与结构进行了修改,主要有: 在块头部分引入了‘安全标记项’(security cookie),块一旦被分配,该项就被检查以确保没有溢出发生; 执行切断连接动作时,flink与blink指针也要作同样的检验,如果想发现堆栈溢出,黑客就必须克服这个标记验证项。同时微软还引入了其他一些保护措施,主要是进程环境块随机化、特殊指针重新编码等,目的都是要减少那些‘固定的’与‘大家都知道的’函数指针的数量,这些指针通常能被全局的系统进程使用,也成为了黑客喜欢利用的目标特权。新机制仍有缺陷
新保护机制并非100%免疫堆栈溢出,第一个公布的绕过新堆栈保护机制的方法,是针对了边查表(lookaside)列表的不存在校验的缺点提出的。边查表的第一个dword项,作为内存块简单连接表的开始,被标记为‘忙’的状态,但却可以随时接受内存分配。当内存分配发生时,返回值可能是相应的边查表的开始区域:在边查表中只是用新分配区域块的flink指针简单替换边查表中原先的flink指针。过程见图... 下一页