天天看点

shellcode初识

这是对shellcode学习的一个初步实践,采用经典的winexec shellcode函数来做实践,采用的工具是VC6.0作为获取工具。其过程如下:
           
1.书写正常的执行代码:
           
<span style="font-family: Arial, Helvetica, sans-serif;">#include "stdafx.h"</span>
           
#include <windows.h>

int main(int argc, char* argv[])
{
	char buff[9];
	buff[0]='c';
	buff[1]='a';
	buff[2]='l';
	buff[3]='c';
	buff[4]='.';
	buff[5]='e';
	buff[6]='x';
	buff[7]='e';
	buff[8]='\0';
	WinExec(buff,SW_HIDE);return 0;
}
           

2.对程序进行编译后,F10来debug一下,然后按Alt+8查看汇编代码,该程序的汇编代码如下:

55                   push        ebp
8B EC                mov         ebp,esp
83 EC 4C             sub         esp,4Ch
53                   push        ebx
56                   push        esi
57                   push        edi
8D 7D B4             lea         edi,[ebp-4Ch]
B9 13 00 00 00       mov         ecx,13h
B8 CC CC CC CC       mov         eax,0CCCCCCCCh
F3 AB                rep stos    dword ptr [edi]
19:       char buff[9];
20:       buff[0]='c';
C6 45 F4 63          mov         byte ptr [ebp-0Ch],63h
21:       buff[1]='a';
C6 45 F5 61          mov         byte ptr [ebp-0Bh],61h
22:       buff[2]='l';
C6 45 F6 6C          mov         byte ptr [ebp-0Ah],6Ch
23:       buff[3]='c';
C6 45 F7 63          mov         byte ptr [ebp-9],63h
24:       buff[4]='.';
C6 45 F8 2E          mov         byte ptr [ebp-8],2Eh
25:       buff[5]='e';
C6 45 F9 65          mov         byte ptr [ebp-7],65h
26:       buff[6]='x';
C6 45 FA 78          mov         byte ptr [ebp-6],78h
27:       buff[7]='e';
C6 45 FB 65          mov         byte ptr [ebp-5],65h
28:       buff[8]='\0';
C6 45 FC 00          mov         byte ptr [ebp-4],0
29:       WinExec(buff,SW_HIDE);
8B F4                mov         esi,esp
6A 00                push        0
8D 45 F4             lea         eax,[ebp-0Ch]
50                   push        eax
FF 15 14 A2 42 00    call        dword ptr [KERNEL32_NULL_THUNK_DATA (0042a214)]
3B F4                cmp         esi,esp
E8 2F 00 00 00       call        __chkesp (00401090)
           

其中

0042a214
           

是 WinExec的执行地址的存放地址,到0x0042a214下去查看函数地址:

shellcode初识
shellcode初识

可以看出,该函数地址为0x7605f22e,然后对汇编代码进行整理后获得的汇编程序如下:

</pre><pre code_snippet_id="394634" snippet_file_name="blog_20140616_7_9412625" name="code" class="cpp">#include "stdafx.h"
#include <windows.h>

int main(int argc, char* argv[]){	
	__asm{
			//保存现场
			push        ebp
			mov         ebp,esp
			push        ebx
			push        esi
			push        edi
			//设置第一个参数
			mov         byte ptr [ebp-0Ch],63h
			mov         byte ptr [ebp-0Bh],61h
			mov         byte ptr [ebp-0Ah],6Ch
			mov         byte ptr [ebp-9],63h
			mov         byte ptr [ebp-8],2Eh
			mov         byte ptr [ebp-7],65h
			mov         byte ptr [ebp-6],78h
			mov         byte ptr [ebp-5],65h
			mov         byte ptr [ebp-4],0
			//设置第二个参数
			push        3
			//压栈
			lea         eax,[ebp-0Ch]
			push        eax
			//call winexec
			mov	    eax,0x7605F22E
			call        eax
			//恢复现场
			mov         esp,ebp
			pop         ebp
	}
}
           

3.保存后对其进行编译并debug,同样按Alt+8来查看:

__asm{
<span style="color:#ff0000;">55                   </span>push        ebp
<span style="color:#ff0000;">8B EC</span>                mov         ebp,esp
           
<span style="color:#ff0000;">53 </span>                  push        ebx
<span style="color:#ff0000;">56 </span>                  push        esi
<span style="color:#ff0000;">57</span>                   push        edi
<span style="color:#ff0000;">C6 45 F4 63</span>          mov         byte ptr [ebp-0Ch],63h
<span style="color:#ff0000;">C6 45 F5 61</span>          mov         byte ptr [ebp-0Bh],61h
<span style="color:#ff0000;">C6 45 F6 6C</span>          mov         byte ptr [ebp-0Ah],6Ch
<span style="color:#ff0000;">C6 45 F7 63</span>          mov         byte ptr [ebp-9],63h
<span style="color:#ff0000;">C6 45 F8 2E </span>         mov         byte ptr [ebp-8],2Eh
<span style="color:#ff0000;">C6 45 F9 65</span>          mov         byte ptr [ebp-7],65h
<span style="color:#ff0000;">C6 45 FA 78 </span>         mov         byte ptr [ebp-6],78h
<span style="color:#ff0000;">C6 45 FB 65</span>          mov         byte ptr [ebp-5],65h
<span style="color:#ff0000;">C6 45 FC 00</span>          mov         byte ptr [ebp-4],0
<span style="color:#ff0000;">6A 03</span>                push        3
<span style="color:#ff0000;">8D 45 F4 </span>            lea         eax,[ebp-0Ch]
<span style="color:#ff0000;">50  </span>                 push        eax
<span style="color:#ff0000;">B8 2E F2 05 76</span>       mov         eax,7605F22Eh
<span style="color:#ff0000;">FF D0</span>                call        eax
<span style="color:#ff0000;">8B E5 </span>               mov         esp,ebp
<span style="color:#ff0000;">5D</span>                   pop         ebp
}
           

头部红色的部分就是要获取的shellcode,在内存中的情况如下:

shellcode初识
shellcode初识

提取后的shellcode为:

char buff[] =
"\x55\x8B\xEC\x53\x56\x57\xC6"
"\x45\xF4\x63\xC6\x45\xF5\x61"
"\xC6\x45\xF6\x6C\xC6\x45\xF7"
"\x63\xC6\x45\xF8\x2E\xC6\x45"
"\xF9\x65\xC6\x45\xFA\x78\xC6"
"\x45\xFB\x65\xC6\x45\xFC\x00"
"\x6A\x03\x8D\x45\xF4\x50\xB8"
"\x2E\xF2\x05\x76\xFF\xD0\x8B"
"\xE5\x5D";
int main(){
__asm{
   lea eax,buff;
   call eax;
}
   return 0;
}
           

最后成功弹出了calc.exe

 当然,查询函数入口地址时,也可以用depends对编译好的程序进行查看,查看方式是:

dll的基地址(base)+函数偏移(entry point)地址

如Winexec的入口地址为,kernal.dll的地址+winexec的偏移地址就是函数的入口地址。

继续阅读