- 暴力破解
0x77e0000 或者 0xbff00000 开始搜索,通常是系统栈开始位置。
寻找"MZ"或者"PE"link - shellcode
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执行,得到弹窗