Loading... 1. 创建MessageBox,用到一下API 1. GetProcessAddress() 14Byte 2. LoadLibraryExA() 14Byte 3. ExitProcess() 11Byte 4. User32.dll 10Byte 5. Messagebox() 11Byte 在实现的时候要使用60字节。并且这些在内存中可以直接看到。那么就可以使用HASH算法对字段加密。就可以省掉很多空间 ![image.png](http://www.irohane.top/usr/uploads/2021/01/3609293349.png) - 将一个字节数据左移25位,使其变成一个四字节数据 - 0x00000011 -> 0x11000000 - 将一个4字节数据右移07,使其变成一个3字节数据。 - 0x11111111 -> 0x00111111 - 然后将这个两个数用按位或的方式拼接。 - 0x11000000 | 0x00111111 - 得到的数大多情况下不会产生0 - 0x11111111 --- # 对必要的函数都进行字符串加密 ```cpp int Hash_GetDigest(char* strFunName) { unsigned int nDigest = 0; while (*strFunName) { nDigest = ((nDigest << 25) | (nDigest >> 7)); nDigest = nDigest + *strFunName; strFunName++; } return nDigest; } int main() { char buf[] = "GetProcAddress"; int e= Hash_GetDigest(buf); printf("%x", e); } ``` # 全代码 在遍历导出名称表,对其同样的字符串加密,对加密之后的值进行比对。增强了隐蔽性。 ``` int main() { //__asm //{ // 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 ebx,[esi+0x08] // ebx = 获取Kernel32.dll 基址 //} __asm { PUSHAD SUB ESP, 0x20 //开辟一段栈空间,增加健壮性 jmp tag_Shellcode // [tag_Next-0x51] "GetProcAddress" bbafdf85 _asm _emit(0x85)_asm _emit(0xdf)_asm _emit(0xaf)_asm _emit(0xbb) //[tag_Next-0x4D] "GetProcAddress" 47 65 74 50 72 6F 63 41 64 64 72 65 73 73 _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) //[tag_Next-0x3B/] "LoadLibraryExA" 4C 6F 61 64 4C 69 62 72 61 72 79 45 78 41 _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-0x30] "user32.dll" 55 73 65 72 33 32 2E 64 6C 6C _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-0x25] "MessageBoxA" 4D 65 73 73 61 67 65 42 6F 78 41 _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-0x19] "ExitProcess" 45 78 69 74 50 72 6F 63 65 73 73 _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-0xD] "irohane" 49 72 6F 68 61 6E 65 _asm _emit(0x49)_asm _emit(0x72)_asm _emit(0x6F)_asm _emit(0x68)_asm _emit(0x61)_asm _emit(0x6E)_asm _emit(0x65)_asm _emit(0x00) tag_Shellcode: //1. GetPc CALL tag_Next tag_Next : pop ebx //ebx = BaseAddr tag_Next的地址 //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 = kernelbase.dll基址 在64位发生了变化 //3. 获取GetProcAddress的函数基址 原调用方法 /*push edx push ebx push edx call fun_GetProcAddress*/ push edx //imageBase mov edi,[ebx-0x51] push edi //nHashDigest call fun_GetFunAddrByHash //int nHashDigest 需要比对的hash imageBase基址 mov esi, eax //4. 获取LoadLibraryExA的函数地址 lea ecx, [ebx - 0x3F] //LoadLibraryExW push edx push ecx //-lpProcName = loadlibraryExw push edx //hModule = kernel32.dll call eax //GetProcAddress //5. 调用Payload pop edx push ebx push esi push eax push edx call fun_payload //Paly_load 攻击部分 fun_Payload: push ebp mov ebp, esp sub esp, 0x08 mov ebx, [ebp + 0x14] //1. 获取MessageBoxA lea ecx, [ebx - 0x30] //kerner32.dll push 0 push 0 push ecx call[ebp + 0x0c] //LoadLibFileName lea ecx, [ebx - 0x25] //MessageboxA push ecx push eax call[ebp + 0x10] //GetProcAddress mov[ebp - 0x04], eax //2. 获取ExitProcess的函数地址 lea ecx, [ebx - 0x19] push ecx push[ebp + 0x08] call[ebp + 0x10] //ExitProcess mov[ebp - 0x08], eax //3. 显示irohane lea ecx, [ebx - 0xD] //irohane push 0 push ecx push ecx push 0 call[ebp - 0x04] push 0 call[ebp - 0x08] mov esp, ebp pop ebp retn 0x10 fun_GetFunAddrByHash: //int nHashDigest 需要比对的hash imageBase基址 push ebp mov ebp,esp sub esp,0x0c push edx //1. 获取EAT ENT 与 EOT 地址 mov edx,[ebp+0x0c] //获取堆中的参数 mov esi,[edx+0x3c] //IMAGE_DOS_HEADER.e_lfanew lea esi,[edx+esi] //PE 文件头 mov esi,[esi+0x78] //EXPORT.VirtualAddress lea esi,[edx+esi] //导出表首地址 mov edi,[esi+0x1c] //导出函数表 lea edi,[edx+edi] //EAT 首地址 mov [ebp-0x04],edi //放入局部变量 mov edi,[esi+0x20] //ENT 首地址 lea edi,[edx+edi] //ENT VA mov [ebp-0x08],edi //放入局部变量 mov edi,[esi+0x24] //EOT 序号表地址 lea edi,[edx+edi] //EOT VA mov [ebp-0x0c],edi //EOT 首地址 //循环 EAT 中的函数名 xor ecx,ecx jmp tag_FirstCmp tag_cmpFunNameLoop: inc ecx tag_FirstCmp: mov esi,[ebp-0x8] //获取名称表地址 mov esi,[esi+4*ecx] //地址4字节 从ecx 开始 数组形式 lea esi,[edx+esi] //获取字符串的VA push [ebp+0x08] //ENT push esi //字符串地址 call fun_Hash_CmpString //对函数名进行同样的加密然后对hash进行比对 //相等为1 不等为0 test eax,eax jz tag_cmpFunNameLoop //循环比对 //成功找到后找到对应序号 mov esi,[ebp-0x0c] //EOT xor edi,edi mov di,[esi+ecx*2] //使用下表在序号中找到对应序号 //序号为索引 mov edx,[ebp-0x04] //edx = EAT mov esi,[edx+edi*4] //找到对应序号的函数地址 mov edx,[ebp+0x0c] //返回GetProcAddress地址 //获取到关键函数地址 lea eax,[edx+esi] //获取函数的VA pop edx mov esp,ebp pop ebp retn 0x08 fun_Hash_CmpString://(funName,base) push ebp mov ebp,esp sub esp,0x04 //开一局部变量 mov dword ptr [ebp-0x04],0x00 //清除上面的局部变量 push ebx //保存标志位 push ecx push edx mov esi,[ebp+0x08] //名称 xor ecx,ecx xor eax,eax //清除标志位 tag_HashLoop: mov al,[esi+ecx] //获取 指向字符串的第一个字符 test al,al // 比较是不是0 jz tag_HashEnd mov ebx,[ebp-0x04] //获取局部变量 第一次进入 为0 shl ebx,0x19 //左移25位 mov edx,[ebp-0x04] //获取局部变量 shr edx,0x07 //右移动7位 or ebx,edx //与运算 add ebx,eax //左移25位的数加上与运算之后的数 mov [ebp-0x04],ebx //把算出的值重新赋值到局部变量 inc ecx //ecx++计算下一个字符 jmp tag_HashLoop //循环 ↑ tag_HashEnd: //遇到0 mov ebx,[ebp+0x0C] //获取需要比对的字符串的hash mov edx,[ebp-0x04] //获取计算出字符串的hash xor eax,eax //清除eax cmp ebx,edx //比较两个值是否相等 jnz tag_FunEnd //如果不相等 mov eax,1 //相等eax = 1 tag_FunEnd: //不相等就正常退出 eax = 0 pop edx pop ecx pop ebx mov esp,ebp pop ebp retn 0x08 } } ``` 成功运行 ![image.png](http://www.irohane.top/usr/uploads/2021/01/3871742690.png)![image.png](http://www.irohane.top/usr/uploads/2021/01/2731612993.png) ![image.png](http://www.irohane.top/usr/uploads/2021/01/302101725.png) 最后修改:2021 年 01 月 19 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏