栈溢出 shellcode编写

it2026-01-02  1

暴力破解 0x77e0000 或者 0xbff00000 开始搜索,通常是系统栈开始位置。 寻找"MZ"或者"PE"linkshellcode exploit-db.com

栈溢出实例分析

环境:windows-xp;vc6.0

首先我们创建一个调用windows的api的弹窗程序messagebox.c //messagebox.c //https://blog.csdn.net/weixin_43745072 #include <windows.h> int main(int argc, char** argv) { MessageBox(NULL,"网络攻防ShellCode 测试!","网络安全",MB_OK); } 在vc6.0中Ctrl+F7编译,并Ctrl+F5运行,可以看到弹窗 Ctrl+F10并点击图中按钮进入到反汇编界面,可以观察到参数的入栈顺序以及函数调用的地址(0x0042a2ac存放的值为0x77d507ea,访问这个地址会调用messagebox函数)

4. 编写stack_overflow.cpp,并编译,复制内存窗口得到机器码

//stack_overflow.cpp //https://blog.csdn.net/weixin_43745072 #include<Windows.h> int main(){ LoadLibrary("user32.dll"); _asm{ push ebp mov ebp,esp sub esp,0x40 //"网络安全",地址保存到ebx push 0x00202020 push 0xabc8b2b0 push 0xe7c2f8cd mov ebx,esp //"网络攻防shell code测试!",地址保存到ecx push 0x002021d4 push 0xcae2b265 push 0x646f436c push 0x6c656853 push 0xe7c2f8cd mov ecx,esp //4个参数的入栈操作 push 0x1 push ebx//"网络安全" push ecx//"网络攻防shell code测试!" xor eax,eax //eax对自己进行异或操作,执行结束之后,eax=0 push eax//push 0 mov eax,0x77d507ea//message box的绝对地址 call eax//执行message box弹窗 //正常退出,否则会报错,原理不大清楚 xor eax, eax //zero out eax (NULL) push eax // put zero to stack (exitcode parameter) mov eax,0x7c81cafa // ExitProcess(exitcode) call eax // exit cleanly } return 0; }

执行效果 F10的窗口,也就是说从0x00401010(0x55) 开始复制到0x00401084 (0xFFD0)

1: #include<Windows.h> 2: int main(){ 00401010 55 push ebp 00401011 8B EC mov ebp,esp 00401013 83 EC 40 sub esp,40h 00401016 53 push ebx 00401017 56 push esi 00401018 57 push edi 00401019 8D 7D C0 lea edi,[ebp-40h] 0040101C B9 10 00 00 00 mov ecx,10h 00401021 B8 CC CC CC CC mov eax,0CCCCCCCCh 00401026 F3 AB rep stos dword ptr [edi] 3: LoadLibrary("user32.dll"); 00401028 8B F4 mov esi,esp 0040102A 68 1C 20 42 00 push offset string "user32.dll" (0042201c) 0040102F FF 15 48 A1 42 00 call dword ptr [__imp__LoadLibraryA@4 (0042a148)] 00401035 3B F4 cmp esi,esp 00401037 E8 74 00 00 00 call __chkesp (004010b0) 4: _asm{ 5: push ebp 0040103C 55 push ebp 6: mov ebp,esp 0040103D 8B EC mov ebp,esp 7: sub esp,0x40 0040103F 83 EC 40 sub esp,40h 8: 9: //"网络安全",地址保存到ebx 10: push 0x00202020 00401042 68 20 20 20 00 push 202020h 11: push 0xabc8b2b0 00401047 68 B0 B2 C8 AB push 0ABC8B2B0h 12: push 0xe7c2f8cd 0040104C 68 CD F8 C2 E7 push 0E7C2F8CDh 13: 14: mov ebx,esp 00401051 8B DC mov ebx,esp 15: 16: //"网络攻防shell code测试!",地址保存到ecx 17: push 0x002021d4 00401053 68 D4 21 20 00 push 2021D4h 18: push 0xcae2b265 00401058 68 65 B2 E2 CA push 0CAE2B265h 19: push 0x646f436c 0040105D 68 6C 43 6F 64 push 646F436Ch 20: push 0x6c656853 00401062 68 53 68 65 6C push 6C656853h 21: push 0xe7c2f8cd 00401067 68 CD F8 C2 E7 push 0E7C2F8CDh 22: 23: mov ecx,esp 0040106C 8B CC mov ecx,esp 24: 25: //4个参数的入栈操作 26: push 0x1 0040106E 6A 01 push 1 27: push ebx//"网络安全" 00401070 53 push ebx 28: push ecx//"网络攻防shell code测试!" 00401071 51 push ecx 29: xor eax,eax //eax对自己进行异或操作,执行结束之后,eax=0 00401072 33 C0 xor eax,eax 30: push eax//push 0 00401074 50 push eax 31: 32: mov eax,0x77d507ea//message box的绝对地址 00401075 B8 EA 07 D5 77 mov eax,77D507EAh 33: call eax//执行message box弹窗 0040107A FF D0 call eax 34: 35: //正常退出,否则会报错,原理不大清楚 36: xor eax, eax //zero out eax (NULL) 0040107C 33 C0 xor eax,eax 37: push eax // put zero to stack (exitcode parameter) 0040107E 50 push eax 38: mov eax,0x7c81cafa // ExitProcess(exitcode) 0040107F B8 FA CA 81 7C mov eax,7C81CAFAh 39: call eax // exit cleanly 00401084 FF D0 call eax 40: 41: } 42: return 0; 00401086 33 C0 xor eax,eax 43: } 00401088 5F pop edi 00401089 5E pop esi 0040108A 5B pop ebx 0040108B 83 C4 40 add esp,40h 0040108E 3B EC cmp ebp,esp 00401090 E8 1B 00 00 00 call __chkesp (004010b0) 00401095 8B E5 mov esp,ebp 00401097 5D pop ebp 00401098 C3 ret

整理机器码得到

\x55\x8B\xEC\x83\xEC\x40\x68\x20\x20\x20\x00\x68\xB0\xB2\xC8\xAB\x68\xCD\xF8\xC2\xE7\x8B\xDC\x68\xD4\x21\x20\x00\x68\x65\xB2\xE2\xCA\x68\x6C\x43\x6F\x64\x68\x53\x68\x65\x6C\x68\xCD\xF8\xC2\xE7\x8B\xCC\x6A\x01\x53\x51\x33\xC0\x50\xB8\xEA\x07\xD5\x77\xFF\xD0\x33\xC0\x50\xB8\xFA\xCA\x81\x7C\xFF\xD0 新建test.c文件,code就是上面的机器码 //test.c //https://blog.csdn.net/weixin_43745072 #include <windows.h> #include<stdio.h> char code[]="\x55\x8B\xEC\x83\xEC\x40\x68\x20\x20\x20\x00\x68\xB0\xB2\xC8\xAB\x68\xCD\xF8\xC2\xE7\x8B\xDC\x68\xD4\x21\x20\x00\x68\x65\xB2\xE2\xCA\x68\x6C\x43\x6F\x64\x68\x53\x68\x65\x6C\x68\xCD\xF8\xC2\xE7\x8B\xCC\x6A\x01\x53\x51\x33\xC0\x50\xB8\xEA\x07\xD5\x77\xFF\xD0\x33\xC0\x50\xB8\xFA\xCA\x81\x7C\xFF\xD0"; int main(int argc, char **argv) { int(*func)(); func = (int(*)()) code; LoadLibrary("user32.dll"); (int)(*func)(); } 编译test.c执行,得到弹窗
最新回复(0)