<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    EXP編寫學習之繞過SafeSEH

    VSole2023-04-17 10:16:35

    SafeSEH對異常處理的保護原理:

    編譯選項/SafeSEH啟動,VS2003以后默認啟用。

    生成SafeSEH表,放在PE文件中,調用異常處理函數的時候,將地址與SafeSEH表中的地址比較。

    檢查異常處理鏈是否位于當前程序的棧中,如果不在棧中,則程序終止異常處理函數的調用。

    檢查異常處理函數指針是否在程序的棧中,如果指向當前棧中,則終止異常處理函數的調用。

    前面兩項檢查都通過后,程序調用一個全新的函數 RtlIsValidHandler ,對異常處理函數的有效性進行驗證。

    RtlIsValidHandler檢測原理:

    首先,該函數判斷異常處理函數地址是不是在加載模塊的內存空間,如果屬于加載模塊的內存空間,校驗函數將依次進行如下校驗:

    (1)判斷程序是否設置了IMAGE_DLLCHARACTERISTICS_NO_SEH 標識。如果設置了這個標識,這個程序內的異常會被忽略。所以當這個標志被設置時,函數直接返回校驗失敗。

    (2)檢測程序是否包含安全S.E.H 表。如果程序包含安全S.E.H 表,則將當前的異常處理函數地址與該表進行匹配,匹配成功則返回校驗成功,匹配失敗則返回校驗失敗。

    (3)判斷程序是否設置ILonly 標識。如果設置了這個標識,說明該程序只包含.NET 編譯人中間語言,函數直接返回校驗失敗。

    (4)判斷異常處理函數地址是否位于不可執行頁(non-executable page)上。當異常處理函數地址位于不可執行頁上時,校驗函數將檢測DEP 是否開啟,如果系統未開啟DEP 則返回校驗成功,否則程序拋出訪問違例的異常。

    如果異常處理函數的地址沒有包含在加載模塊的內存空間,校驗函數將直接進行DEP 相關檢測,函數依次進行如下校驗:

    (1)判斷異常處理函數地址是否位于不可執行頁(non-executable page)上。當異常處理函數地址位于不可執行頁上時,校驗函數將檢測DEP 是否開啟,如果系統未開啟DEP 則返回校驗成功,否則程序拋出訪問違例的異常。

    (2)判斷系統是否允許跳轉到加載模塊的內存空間外執行,如果允許則返回校驗成功,否則返回校驗失敗。

    RtlIsValidHandler允許異常函數執行的情況

    1)異常處理函數位于加載模塊內存范圍之外,DEP 關閉。

    2)異常處理函數位于加載模塊內存范圍之內,相應模塊未啟用SafeSEH(安全S.E.H 表為空),同時相應模塊不是純IL。

    3)異常處理函數位于加載模塊內存范圍之內,相應模塊啟用SafeSEH(安全S.E.H 表不為空),異常處理函數地址包含在安全SEH表中。

    分析一下這三種情況的可行性。

    (1)現在我們只考慮SafeSEH,不考慮DEP。排除DEP 干擾后,我們只需在加載模塊內存范圍之外找到一個跳板指令就可以轉入shellcode 執行,這點還是比較容易實現的。

    (2)在第二種情況中,我們可以利用未啟用SafeSEH 模塊中的指令作為跳板,轉入shellcode執行,這也是為什么我們說SafeSEH 需要操作系統與編譯器的雙重支持。在加載模塊中找到一個未啟用的SafeSEH 模塊也不是一件很困難的事情。

    (3)這種情況下我們有兩種思路可以考慮,一是清空安全S.E.H 表,造成該模塊未啟用SafeSEH 的假象;二是將我們的指令注冊到安全S.E.H 表中。由于安全S.E.H 表的信息在內存中是加密存放的,所以突破它的可能性也不大,這條路我們就先放棄吧。

    利用SafeSEH的缺陷

    利用S.E.H 的終極特權!這種安全校驗存在一個嚴重的缺陷——如果S.E.H 中的異常函數指針指向堆區,即使安全校驗發現了S.E.H 已經不可信,仍然會調用其已被修改過的異常處理函數,因此只要將shellcode 布置到堆區就可以直接跳轉執行!

    繞過SafeSEH

    1.攻擊返回地址繞過

    2.虛函數繞過

    3.從堆中繞過 :shellcode布置在堆中 ,SEH處理函數指向這個地址即可

    4.利用未啟用SafeSEH模塊繞過 :可以把這個模塊的指令作為跳板,去執行shellcode

    5.加載模塊之外的地址繞過 :內存中有一些Map類型的映射文件,在這些文件中找到跳板指令覆蓋SEH處理函數地址即可繞過

    6.利用未啟用SafeSEH的控件,且控件包含溢出漏洞可以被觸發(IE瀏覽器控件)

    實踐利用加載模塊之外的地址

    1.我們使用上一篇中的代碼,稍微修改來測試,關閉GS DEP ASLR, 開啟 SafeSEH ,如果你有VC6 ,最好使用它來編譯。

    #include 
    #include 
     
    int zero = 0;
     
    int MyException()
    {
        printf("Error OverFlow %d", zero);
        return 1;
    }
     
    void __stdcall test(char* str, char* out)
    {
        char buf[0x500] = { 0 };
     
        __try
        {
            strcpy(buf, str);
            zero  = 1 / zero;
     
        }
        __except (MyException())
        {
     
        }
    }
     
     
    int main(int arc, char** argv)
    {
        char buf1[200];
        test(argv[1], buf1);
        return 0;
    }
    

    2.先用IDA查看一下代碼,因為我用VS2019編譯, 編譯器會擴展SEH。

    可以看到, 這里使用了第3代的異常處理模型 ,往棧中放入了不少東西,會影響我們的偏移。

    用od插件搜索一下,都開啟了SafeSEH保護。

    3.調試一下看看,可以看到,輸入0x500個字節的A后, 還差12個字節才可以覆蓋到Handler。

    修改參數 ,再次調試查看。

    好的,現在可以看到,Handler已經被覆蓋為 C , 那么現在需要找到跳板地址來跳到shellcode。

    之前已經看過,所有模塊都啟用了SafeSEH,那么我們需要找到加載模塊之外的跳板地址,內存映射查看 MAP類型的地址。

    那么我們需要什么樣的跳板指令呢?

    觀察寄存器,發現eax指向我們溢出的緩沖區,那么是否可以利用 jmp eax , call eax,來跳轉到shellcode執行(答案是不行,eax是一個易失寄存器,在轉到異常處理函數的過程中會被修改)。

    好的, Next先不管,Handler需要什么樣的跳板指令呢,按照之前利用SEH的總結, 我們需要 pop pop ret指令。

    隨便填寫一個地址測試是否成功轉到該地址 ,我們在MAP類型內存映射中,找到了 0x7FFA5BE8地址,7FFA2017 它的指令是 jmp eax。

    好的,修改Handler為這個地址, 看一下是否可以轉到這個地址執行 ,答案是可以,但是無法下斷跟蹤(且提示訪問0地址)。

    之后我又選擇了一個 pop ret指令的地址, 沒辦法,只能找到這個指令了,推算一下, 也就是 jmp [esp+4]。

    根據微軟的解釋 EstablisherFrame 是此函數的固定堆棧分配的基地址 ,也就是我們得到的地址是 系統設置的異常處理函數的ebp(好吧,日后詳細研究一下)。

     

    好的好的,可以看到程序已經轉到棧上執行,如果有合適的跳板指令可以利用(沒辦法了,我使用win10進行測試)。

    結語

    1.可以看到限制我們進行漏洞利用的因素有很多,我們不得不研究新的手段來對抗微軟的保護機制。

    2.經過測試,如果你不是使用加載模塊地址之外的地址,確實會與safeSEH表來進行對比,會提示異常 無效的異常處理程序。

    3.經過這次實踐,碰到了各種各樣的問題,此時才能理解前人的智慧,不得不佩服。

    地址異常處理
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    概述在windows系統上,涉及到內核對象的功能函數,都需要從應用層權限轉換到內核層權限,然后再執行想要的內核函數,最終將函數結果返回給應用層。本文就是用OpenProcess函數來觀察函數從應用層到內核層的整體調用流程。OpenProcess函數,根據指定的進程ID,返回進程句柄。NTSTATUS Status; //保存函數執行狀態。OBJECT_ATTRIBUTES Obja; //待打開對象的對象屬性。HANDLE Handle; //存儲打開的句柄。CLIENT_ID ClientId; //進程、線程ID. dwDesiredAccess, //預打開進程并獲取對應的權限。ObjectNamePresent = ARGUMENT_PRESENT ; //判斷對象名稱是否為空
    盡管之前的漏洞也很優秀,但這個漏洞我認為是優秀者中的佼佼者。本文側重于介紹內存構造的思路,最后給出了調試結果。后來,Siberas團隊在其官網公布了此漏洞的詳細細節及利用方法,它是AFD.sys驅動上的一處雙重釋放漏洞,通殺Wdinwos系統,影響較大。
    堆區分為兩大區:Young區和Old區,又稱新生代和老年代。在不同的JVM實現及不同的回收機制中,堆內存的劃分方式是不一樣的。相對于基于寄存器的運行環境來說,JVM是基于棧結構的運行環境。在活動線程中,只有位于棧頂的幀才是有效的,稱為當前棧幀。正在執行的方法稱為當前方法,棧幀是方法運行的基本結構。在執行引擎運行時,所有指令都只能針對當前棧幀進行操作。而StackOverflowError表示請求的棧溢出,導致內存耗盡,通常出現在遞歸方法中。
    軟件漏洞分析簡述
    2022-07-18 07:08:06
    然后電腦壞了,借了一臺win11的,湊合著用吧。第一處我們直接看一下他寫的waf. 邏輯比較簡單,利用正則,所有通過 GET 傳參得到的參數經過verify_str函數調用inject_check_sql函數進行參數檢查過濾,如果匹配黑名單,就退出。但是又有test_input函數進行限制。可以看到$web_urls會被放入數據庫語句執行,由于$web_urls獲取沒有經過過濾函數,所以可以
    內核學習-異常處理
    2021-12-31 16:22:12
    異常產生后,首先是要記錄異常信息,然后要尋找異常處理函數,稱為異常的分發,最后找到異常處理函數并調用,稱為異常處理異常處理異常分發,異常處理 展開。
    網上關于ShellCode編寫的文章很多,但介紹如何在ShellCode里面使用異常處理的卻很少。Windows程序的異常處理,其實是三者結合的:操作系統、編譯器和程序代碼。因為x86下異常處理的文章太多,所以本文只介紹Win64下的。而Win64的異常處理,是基于表的。也就是說,編譯器在編譯代碼的時候,會同時對每個函數生成一個異常表,最后鏈接到PE的異常表里。相對來說,這個比X86更加安全和高效。
    用od插件搜索一下,都開啟了SafeSEH保護。修改參數 ,再次調試查看。好的,現在可以看到,Handler已經被覆蓋為 C , 那么現在需要找到跳板地址來跳到shellcode。之后我又選擇了一個 pop ret指令的地址, 沒辦法,只能找到這個指令了,推算一下, 也就是 jmp [esp+4]。
    假如想在x86平臺運行arm程序,稱arm為source ISA, 而x86為target ISA, 在虛擬化的角度來說arm就是Guest, x86為Host。這種問題被稱為Code-Discovery Problem。每個體系結構對應的helper函數在target/xxx/helper.h頭文件中定義。
    0x00 日常查殼無殼64位0x01 CFGGETC在講這題ollvm與異常處理之前,有必要先搞懂我們到底是怎么輸入的。一共有三處getc處理我們第一段輸入的地方。程序最先開始運行的是 407629,這里我們可以輸入上下左右箭頭與特定的數字。隨后到 40553A 讀取為5B。
    Windows中主要的異常處理機制:VEH、SEH、C++EH。 SEH中文全稱:結構化異常處理。就是平時用的__try __finally __try __except,是對c的擴展。 VEH中文全稱:向量異常處理。一般來說用AddVectoredExceptionHandler去添加一個異常處理函數,可以通過第一個參數決定是否將VEH函數插入到VEH鏈表頭,插入到鏈表頭的函數先執行,如果為
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类