天天看點

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的偏移位址就是函數的入口位址。

繼續閱讀