您的位置首页  基金资讯

windbg调试从二进制漏洞分析入门到辅助分析脚本诞生

  • 来源:互联网
  • |
  • 2016-10-12
  • |
  • 0 条评论
  • |
  • |
  • T小字 T大字

Firstchanceexceptionsarereportedbeforeanyexceptionhandling.Thiceptionmaybeexpectedandhandled.

41414141

Target[5]=fgetc(hFile);

}

if(dword_443540(result=dword_443548,dword_443548))

在windbg中,涉及到寄存器操作的都需要加上r,而涉及到一些if,else,while命令的,则需要加上一个“.”,windbg有很多种调用脚本的方法,这里介绍

.if(@eip==$t1)

idapro直接观察打开pe文件开头就可以获得

PCManFTPD2+0x29db:

冲区,而没有进行长度控制的情况下,会造成缓冲区溢出。

41414141

ff154c554300

004029d5

}

dword

比起windbg的脚本,idapro提供了一套自己的功能,在代码编写方面和C很像,需要通过#include方法,把idc提供的api库导入,这样才能使用ida可识

ss=0023ds=0023es=0023fs=003bgs=0000

nvupei

iopl=0

GetLocalTime(SystemTime);v4=*((_DWORD*)v2+9);if(v4)

fseek(hFile,37,1);

Target[3]=fgetc(hFile);

eip=004029d5esp=0012edacebp=00a61ba0

cs=001b

eax=00000886ebx=00000000ecx=001694d8edx=0012edc4esi=00000000edi=00000402

push

autoi,temp;

//

temp=temp-windbg_image_base_addr+ida_image_base_addr;SetColor(temp,1,0x98fb98);

41414141

0012edd4

41414141

$$a

(四)写在最后

(三)idahelp.和winidc.idc

Target[7]=fgetc(hFile);

{

Target[2]=fgetc(hFile);

PCManFTPD2+0x29df:

%d/%d/%d[%02d:%02d](%05d)%s%s\r\n,SystemTime.wYear,

(d4.220):Accessviolation-codec0000005(firstchance)

eax=00000886ebx=00000000ecx=001694d8edx=7c92e4f4esi=00000000edi=00000402

AAAAAAAAAAAAAAAA

0012edc4

Target[4]=fgetc(hFile);

设置首页-搜狗输入法-支付中心-搜狐招聘-广告服务-客服中心-联系方式-隐私权-AboutSOHU-公司介绍-网站地图-全部新闻-全部博文

.break

}

}

0012ee14

通过kb命令,我们可以看到在程序执行到崩溃场景前调用的函数内容,而这个调用往往是嵌套调用,就是栈增长方向是外层函数,因为熟悉堆栈的小伙伴应该知道,栈的开辟是由高地址向低地址开辟,堆是由低地址向高地址开辟,也就是每次调用内层函数的时候,栈就会向低地址方向开辟一片空间使用,我们可以这样简单理解函数调用关系。

2016-08-1716:50:00红黑联盟论坛(一)写在前面

41414141

nc

efl=00010212

efl=00000202

造成软件或者系统崩溃的原因有很多,比如某些关键地址,关键指针被覆盖,导致引用时发生错误,比如空指针引用,比如越界操作内存等等,而二进制漏洞分析就是要分析为什么会造成崩溃的发生,这样无论对于修补漏洞,还是编写利用工具,都有极大的帮助。

offsetPCManFTPD2+0x411dc(004411dc)

jQuery8586489856_30

004029df

41414141

nvupeiplnzacponc

.printfeip:0x%.08x\n,@eip;

41414141

004029db

41414141

我们在使用idapro脚本进行标记。

.printfTryrunwithrightaddress;

{

int__thiscallsub_403E60(void*this,int*a2)

Target[1]=fgetc(hFile);

$$如果再次命中,证明不是最后一次漏洞触发过程

ss=0023ds=0023

#include

efl=00000246

一般当我们第一次开始学习漏洞分析的时候,拿到一个崩溃场景,往往会碰到这样的崩溃场景。

Target[4]=fgetc(hFile);

两种常用的调用方法。

41414120

externida_image_base_addr,windbg_image_base_addr,offset;

0:000p

}

(0043554c)]

eip=41414141esp=0012edb8

.text:00403F6Bretn4

41414141

fseek(hFile,9,1);

.break;

函数调用先后顺序的标记

.if(@eip==$t2)

ss=0023ds=0023es=0023fs=003bgs=0000

cs=001b

eax=0012edc4ebx=00000000ecx=000000fcedx=00a61aa4esi=00000000edi=00000402

.logopenC:\ida.log

{

SystemTime.wHour,

temp=xtol(Target);

temp=xtol(Target);

nvupeiplzrnapenc

PCManFTPD2+0x29d5:

AAAAAAAAAAAAAAAA

{

for(i=1;i

这样,就完成了对这个指令区间的,接下来我们来看一下winidc.idc。

.printfeip:0x%.08x\n,@eip;t

这就需要我们利用脚本对想的地址区间进行设定,然后脚本会不断,同时通过logopen命令来将整个时的径保存至一个文件里,方便之后

在漏洞分析过程中,避免不了这样一个过程----回溯。刚才提到,漏洞分析就是要分析为什么会造成崩溃的发生,那么就少不了对程序执行流程的回溯,通常在windbg中,我们使用“kb”命令回溯堆栈调用的情况。

cs=001b

}

68dc114400

eax=00000000ebx=00000000ecx=00000000edx=0000000cesi=0012edc4edi=00000004

{

说到二进制漏洞分析,在windows下,入门阶段最好用的两款工具就是windbg和IDApro对于这两款工具,网上相关的介绍有很多,这里我就不再多做赘述,在我进行漏洞分析的过程中,经常用的方法就是windbg的动态调试,配合上IDApro的静态分析,其中windbg提供了很强大的动态调试功能,包括堆栈的回溯,,加载符号表中特定的变量,结构体等等;而idapro则提供了静态分析的功能,比如指令流流程,伪代码还原等等。

0012ede4

ptr[PCManFTPD2+0x3554c

$$如果命中最后结束地址

//主函数staticmain(void)

(三)从PcManFTP漏洞看辅助分析脚本

这里AskStr是获取用户输入字符串,AskFile则是获取用户文件,这里打开的文件,就是刚才我们通过windbg脚本生成的文件ida.log,之后通过fseek的方法跳转到指令开头部分,随后会获取相应的地址,并且进行标记,同时需要用户输入ida的对应领空基址以及windbg对应领空基址,这是为了对抗aslr。

eip=004029dfesp=0012edbcebp=00a61ba0iopl=0

SystemTime.wMinute,*((_DWORD*)v2+3),v5,

别的脚本函数,来完成我们的功能。来看一下winidc.idc的代码。

.while(1)

41414141

void*v2;//;//;//eax@3

AAAAAAAAAAAAAAAA

Target[7]=fgetc(hFile);

从接触二进制漏洞以来一直在边学边思考,有没有一些共通的地方,可以通过一些简单的脚本或者工具来简化一些过程,不得不承认二进制漏洞无论在挖掘,分析,还是最后写exp上都是有一定难度的,经过不断的请教,大牛们的作品,也逐渐摸到了一些门道,下面的分享如有不当之处请多多指教,大牛轻喷:)

可以看到,执已经被标记出来了,再看一程图。

ss=0023ds=0023es=0023fs=003bgs=0000

我们需要在ida中动态这个调试过程,追踪从接收到PoC中的畸形数据,到触发漏洞的整个过程,才能较为完整的完成对漏洞的分析,那么实际上在一个函数内部,涉及到大量的条件判断,跳转等功能,在ida的指令流程图中可以看出这个过程在静态分析中,会耗去很多时间。

0012ee04

{

地址有效性的判断

其他可能存在的bug

$$启始地址必须是当前命中的地址

FileLength=filelength(hFile)-30-34;Fileline=FileLength/17;

0:000p

r@$t4=@eip

.else

在004029d5接收到recv之后,观察一下此时接收到的数据。

AAAAAAAAAAAAAAAA

FileName=AskFile(0,*.*,PleasechooseWindbgInstructionstreamfile);hFile=fopen(FileName,r+);

//获取输入Windbg和IDA中模块的基址

41414141

v5=*((_DWORD*)v2+1);

v5=*(_DWORD*)(v4+8);else

lea

第一种调用的是不带参数的,第二种则是调用带参数的,在我的脚本里,需要两个参数,在脚本开头已经传入t1,t2模拟寄存器里。

.printfeip:0x%.08x\n,@eip;t$$开始

intv5;//;//;//;//ct_SYSTEMTIMESystemTime;//[sp+8h][bp-814h]@3DWORDNumberOfBytesWritten;//[sp+18h][bp-804h]@7charBuffer;//[sp+1Ch][bp-800h]@6

.else

这两个参数分别对应脚本执行的起始地址和结束地址,在上述的分析过程中,我们提到在回溯调用的过程中,需要由外层函数向内层函数不断动态,

这里我以PcManFTP这个漏洞为例,先结合漏洞的分析过程,再辅助分析脚本的编写及功能,首先这个漏洞是由于PcManFTP在对用户传输的数据进行处理的过程中,没有对传输的内容进行长度控制和内容检查,从而导致可以通过ftp指令+畸形字符串来覆盖返回地址,最后导致远程代码执行,在发送PoC之后,这边用windbg对进程进行附加,可以捕获到崩溃场景。

在ida的文件菜单中有一个功能叫command,可以导入这个idc的脚本。

ABORAAAAAAAAAAA

41414141

es=0023fs=003bgs=0000

已经是畸形字符串了,接下来进行连续。我们到一处函数sub_403E60,这处函数中会执行一处sprintf操作,正是这个过程会将payload拷贝到缓

Target[2]=fgetc(hFile);

在windbg下,支持使用脚本,同样在idapro下,也支持使用.idc的脚本,首先我来一下windbg下的脚本,以及编写,首先来看一下idahelp.。

{

.if(@$t4!=$t1)

0:000gBreakpoint0hit

Target[6]=fgetc(hFile);

edx,[esp+8]

AAAAAAAAAAAAAAAA

524f4241

Target[1]=fgetc(hFile);

.echohelloworld

执行脚本之后,程序会按照流程动态执行,并且将整个执行的过程记录在txt中。

41414141

call

{

41414141

plnznapo

temp=temp-windbg_image_base_addr+ida_image_base_addr;SetColor(temp,1,0x98fb98);

.logcloseC:\log.txt

(二)为什么要写辅助分析脚本

r@$t1=${$arg1}r@$t2=${$arg2}r@$t3=@esp

那么实际上,我写的这个辅助分析脚本,其实也是为了针对这种情况而诞生的。

Target[6]=fgetc(hFile);

Target[0]=fgetc(hFile);

41414141

41414141

41414141

41414141

eip=004029dbesp=0012edbcebp=00a61ba0iopl=0

{

.printfThisisnotthelasttunnel\n;

41414141

ebp=00a61b40iopl=0

感谢蛙师傅给予的灵感!

在对这个过程进行动态调试的过程中,涉及到很多函数的嵌套调用,以及很多的跳转,这无论在windbg还是idapro中通过地址比对来动静结合是很耗时间的,因为要经过很多的地址比对,甚至有时在面对ASLR的情况下还需要进行地址换算,于是就有了这个辅助分析脚本。

v2=this;

41414141

{

相应的脚本也已经开源放在我的github下,欢迎大家多提意见,也可以进行修改,后续我也会根据我逐步学习逐步改进增强工具的功能。这里之所以说是辅助分析工具,是因为我还想不到一种方法能够完全自动化分析漏洞的成因,只能说简化一些漏洞分析过程中的过程。

$$纪录第一次并跳过

对应函数的执也都很清晰的展示出来,省去了对地址比对分析的过程。

nvupeiplzrnapenc

SystemTime.wDay,

SystemTime.wMonth,

edx

通过回溯,我们找到了一处callrecv的调用,这个调用会获取畸形的payload。

$$

最后执行到返回后会因为返回地址被覆盖导致任意代码执行。

}

Target[0]=fgetc(hFile);

}

temp=AskStr(00401000,PleaseinputIDAsimageBase,Forexample:);ida_image_base_addr=xtol(temp);

v6=sprintf(Buffer,

搜狐不良信息举报邮箱:

//

这里我和大家分享了二进制漏洞分析入门的一些技巧方法,并且结合一个实例漏洞分享了我写的辅助分析脚本,比较基础,希望能对大家有所帮助,这个辅助分析脚本也存在一定的不足,以后会继续完善升级功能,并且弥补存在的一些bug。

在二进制漏洞的入门学习中,我个人感觉相比漏洞挖掘,构造PoC,编写Exp,只有漏洞分析是最核心也是最容易入手的,通过已有的PoC,搭建复现漏洞的,获得存在漏洞的软件,复现漏洞后就可以进行分析了,而我写的这个脚本,也是为了简化一些漏洞分析过程,从而更清晰直观的看到漏洞执行流程。

cs=001b

temp=AskStr(00401000,PleaseinputWindbgsimageBase,Forexample:);windbg_image_base_addr=xtol(temp);

8d542408

ds:0023:0043554c={WSOCK32!recv(71a42e70)}

0:000dc

通过import按钮导入idc脚本,再通过run执行,进行相应的设置,这里我们选择打开之前windbg生成的文件。进行对应的参数设置之后观察一下效果。

41414141

Target[3]=fgetc(hFile);

a2);

41414141

41414141

autoFileName,FileLength,hFile,str,Target=66666666;autoFileline;

efl=00000246

Target[5]=fgetc(hFile);

两者获取基址的方法,windbg通过lm命令查看加载模块获得基址。

???

0012edf4

免责声明:本站所有信息均搜集自互联网,并不代表本站观点,本站不对其真实合法性负责。如有信息侵犯了您的权益,请告知,本站将立刻处理。联系QQ:1640731186
友荐云推荐