-
-
[原创]漏洞挖掘之个人见解
-
发表于:
2011-9-26 10:02
10044
-
漏洞挖掘是每个想成为顶级黑客高手的必修课,但是这门技术一直被各个顶级的黑客高手私藏着,很少有人在公开场合讨论这个技术。而小菜我经过几个星期的苦思冥想,在如何实现高效与快速的挖掘漏洞上给出了自己的方案,希望各位大牛们不要见笑,给个评价。小菜我感激不尽。(本文只讨论基于二进制的反汇编漏洞挖掘技术)
漏洞可利用的本质:
要能够利用一个程序,改变它的执行流程,那么唯一的方法是我们能够控制EIP,而目前能够改变EIP的指令有哪些呢?
在win32的平台上目前就三个指令:ret,jxx(跳转指令),call,这三个指令改变EIP的原理我就不多说了,我们可以按打进EIP的值的来源把它们分为三类:
1.EIP来自立即数:因为立即数无法改变,所以我们没有讨论的空间。
2.EIP来自寄存器:如,jmp eax,call eax等指令。
3.EIP来自内存:如,jmp [eax] call [eax]等指令,当然ret指令的默认操作数是内存(ESP指向)。
由上可知,我们要改变程序的流程,就必须能够控制相应的寄存器和内存。所以判别一个jxx,
call,ret能否被利用就是看我们输入的数据能否影响到相应的寄存器和内存。
寄存器:
在判定我们输入的数据能否影响到相应寄存器方面我们可以使用静态反汇编和动态调试相结合,这里就是反汇编技术问题了。我就不讨论了。
内存:
在内存方面我们输入的数据只要能够改变jxx、call和ret所使用的内存,那么我们就能控制程序的流程。所以我们关键是要看操作内存的指令和API,看它能否实现我们的愿望。
关键指令:
在汇编语言中操作内存的指令很多,但是根据我对很多漏洞的分析,发现最容易引起漏洞的
指令不外乎就是rep movsb、rep movsd和mov [reg],xx,前面两个指令是最容易溢出的,而mov [reg],xxz如果与jxx back(会跳循环)结合也常引发溢出,mov [reg],xx还可引发向任意内存写数据的漏洞。
关键API:
我们只需关注那些操做内存API,有内存的申请,内存的使用,内存的释放,在内存申请的时候我们如果能够控制申请的内存大小,就可能产生溢出,内存使用API最常见的就是溢出了如wsprintf,在内存释放的时候我们如果能够控制释放内存的大小那也可以产生溢出。
漏洞挖掘:
由上分析可知,我们在进行漏洞挖掘时只需要关注的指令有:rep movsd,rep movsb和mov [reg],xx,jxx reg ,call reg。
关注的函数有,操作内存的函数,特权函数。
在这里我说一下我挖漏洞的方法:
1.使用IDA进行静态反汇编。
2.查找输入接口,如:createfile、recv、recvfrom等。可以使用动态调试下断点。
3.使用IDA从输入接口一直往下看,查找关键的指令和操作内存的API。
4.动静结合分析关键指令和内存操作函数,如:如果指令是 rep movsd我们可以反汇编看ESI是否指向我们的字符串,是否能够溢出,如果是有判断,我们可以查看是否存在绕过,如整形溢出。如果是mov [reg],xx的话我们可以查看是否可以控制reg而达到向任意内存写数据,而如果mov [reg],xx在循环中,我们看是否可以产生溢出。如果是jxx reg和 call reg我们可以查看我们是否可以控制reg。如果是API我们可以查看是否是内存操作API,如果是我们可以查看是否可以引发漏洞。
技巧:
1.使用IDA脚本给关键的指令加注释,这样就没有必要查看每条指令了。如我写的查找rep movsd脚本:
//本程序为查找rep movsd
#include <idc.idc>
static main() {
auto ea,x,count;
auto fstart,fend;
auto forword;
auto last;
count=0;
Message("**************************************************程序开始执行*************************************************\n");
//列举所以的函数
for ( ea=NextFunction(0);ea!=BADADDR;ea=NextFunction(ea) ) {
fstart=GetFunctionAttr(ea,FUNCATTR_START);
fend=GetFunctionAttr(ea,FUNCATTR_END);
//对每个函数进行搜索
while(fstart<fend){
fstart=FindCode(fstart,SEARCH_DOWN|SEARCH_NEXT);
if(fstart==BADADDR){
break;
}else{
if(Byte(fstart)==0xF3&&Byte(fstart+1)==0xA5)
{
Message("rep movsd:bp 0x%x hack\n",fstart);
MakeComm(fstart,"***********HACK***********");//加注释,方便查找
count++;
}
}
}
}
Message("程序执行完毕,一共找到%i个\n",count);
}
2.使用IDA的图形和动态调试器比较方便。
3.大部分的mov指令是mov [esp+xx],xx,一般因为esp我们是无法控制的所有这些指令可以忽略,其他指令只要我们多去实践分析也可以总结出规律,而不必每条指令都去分析。但是API还是自己去分析。
总结:
本漏洞挖掘的优点是比较全面,漏洞挖掘的关键是我们能否突破各种条件的限制,使其执行关键的指令和API,在IE漏洞比较常见的是call eax,而eax又是突破了各种条件以后被我们控制。所有关键的是如何突破条件使我们的关键指令和函数引发漏洞
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课