<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>

    【技術分享】深耕保護模式(四)

    VSole2022-07-19 08:29:14

    在x86系統下,總說一個進程有4GB空間,那么按照這個說法來說,在windows上起一個進程就要占用4GB空間,兩個進程就要占用8GB空間,但是實際上是我們電腦的物理內存往往只有8GB,16GB多一點的可能有32GB,我們卻啟動了幾十個進程,這顯然是矛盾的。

    實際上,我們所說的進程有4GB內存空間,這個概念是虛擬的。cpu會經過一定算法從虛擬內存地址找到物理內存地址。

    這里還有幾個概念:線性地址、有效地址、物理地址

    如下指令:

    MOV eax,dword ptr ds:[0x12345678]

    其中,0x12345678 是有效地址

    ds.Base + 0x12345678 是線性地址

    物理地址就是真正在內存條上的地址,不是虛擬出來的。

    每個進程都有一個CR3,(準確的說是都一個CR3的值,CR3本身是個寄存器,一個核,只有一套寄存器)

    CR3指向一個物理頁,一共4096字節,從CR3到物理頁的過程如圖:

    下面在10-10-12分頁模式下從線性地址找到物理地址。要想當前xp系統是10-10-12分頁,需要修改boot.ini文件。

    將noexecute 改成 execute。

    寫入一句話到記事本,并通過CE找到他的線性地址。

    采用10-10-12分頁方式拆解這個線性地址。(十位,十位和十二位)

    拆完以后CPU首先去找CR3寄存器,CR3寄存器是一個唯一存儲物理地址的寄存器,CR3中存了一個值,這個值指向一個物理頁,這個也有4096個字節,也就是他的第一級,第一部分分的高十位就是確定這個地址在第一級的哪個位置,第二個十位就是確定在第二級的哪個位置,最后12位就是確定在4096個字節的物理頁的v哪個地址,4096 = 2 ^ 12;第一級中每個成員是4個字節,4096個字節可以存放1024 = 2 ^ 10個地址,同樣第二級也是一樣。

    通過windbg獲取notepad的cr3。

    這里還得計算幾個偏移。前面兩個都是目錄,由于一個是4個字節所以需要乘以4。

    在!dd表示查看物理地址。這里第一層是0

    kd> !dd 15d45000+0
    

    第一級找到了,要去掉最后三位,這三位是屬性。

    kd> !dd 15bad000+2A8
    

    第三級一樣的。使用!db一個字節一個字節的查看。

    kd> !dd 15ba8000+A40kd> !db 15ba8a40
    

    物理地址就已經找到了。

    在白皮書描述中整個過程如下(線性地址到物理地址):

    PDE和PTE

    Cr3寄存器起到了不可或缺的作用。那Cr3寄存器中存儲的究竟是什么呢?

    Cr3寄存器不同于其他寄存器,在所有的寄存器中,只有Cr3寄存器存儲的地址是 物理地址,其他寄存器存儲的都是 線性地址

    Cr3寄存器所存儲的物理地址指向了一個頁目錄表(Page-Directory Table,PDT),也就是我們前面所說的查找時的第一級。在Windows中,一個頁的大小通常為4KB(有4MB的),即一個頁(頁目錄表)可以存儲1024個頁目錄表項(PDE)。

    而第二級為頁表(PTT), 每個頁表的大小為4KB,即一個頁表可以存儲1024個頁表項(PTE)。

    這種設計方式正是10-10-12分頁的由來,由于前面兩級是四個字節一組,那么索引為2的10次方就可以獲取到每一項(整個是4096字節),也就是10位;而最后一級物理頁,一個字節一組,所以需要4096組,索引也要指到4096,也就是2的12次方,正好12位。

    上面說到10-10-12分頁還有一個大頁(4MB),實際上是沒有頁表(PTT)這一級,也就是PDE直接去索引物理頁,那么就是2^10*2^12,正好是4MB。

    頁表項(PTE)具有以下特征:

    1. PTE可以指向一個物理頁,也可以不指向物理頁
    2. 多個PTE可以指向同一個物理頁
    3. 一個PTE只能指向一個物理頁

    實驗

    我們都知道地址0是絕對不能寫入的,如果寫入回報0xC0000005錯誤,那么是什么原因不能寫入呢?他的本質實際上就是0地址沒有對應的物理頁,也就是上面所說的“PTE可以指向一個物理頁,也可以不指向物理頁”,0地址實際上就沒有對應的物理頁。

    那么我們可以自己將線性地址0的PTE掛載到物理頁上,這樣就可以讀寫了。運行這樣一段代碼:

    #include "stdafx.h"int main(int argc, char* argv[]){    int x = 1;    printf("x的地址:%x\n",&x);
        *(int*)0 = 123;    printf("0地址數據:%d\n",*(int*)0);    return 0;
    }
    

    我們要做的就是將線性地址0的物理頁掛載到局部變量x的物理頁,讓兩個PTE指向的是同一個物理頁。

    還是先找到當前進程的cr3。

    獲取x的線性地址:0x0012ff7c,并對其經行分解。

    然后找到其對應的物理地址

    kd> !dd 1a9e9000 + 0kd> !dd 1a9b4000 + 4BCkd> !db 1a790000 + f7c
    

    讓線性地址0的PTE指向同一塊物理地址。

    如果線性地址為0,那么他就沒有PTE,所以這里要寫一個PTE。

    kd> !dd 1a9b4000
    

    由于二級偏移也是0,那么這里就把二級偏移直接寫成物理頁的首地址。也就是1a790067。

    kd> !ed 1a9b4000 1a790067
    

    回到程序重新執行,在線性地址0的位置已經寫入了123。

    此時用圖形化表示為:

    PDE&PTE屬性

    PDE和PTE的低12位實際上是表明屬性,這個在之前的練習中已經了解過了。

    物理頁的屬性

    物理頁的屬性 = PDE屬性 & PTE屬性

    P位和段的P位是一樣的,表示當前PDE或者PTE是否有效,所以PDE與PTE的P位 P=1 才是有效的物理頁。

    R/W屬性

    R/W位表示是否是可讀可寫的。R/W = 0 只讀,R/W = 1 可讀可寫,只有當PDE和PTE的R/W位都為1的時候,該物理頁才是可讀可寫的。

    觀察下面一段代碼:

    #include "stdafx.h"#include <windows.h>int main(int argc, char* argv[]){    char* str = "Hello World";    printf("線性地址:%x\n",str);
        getchar();
        DWORD dwVal = (DWORD)str;
        *(char*)dwVal = 'M';    printf("%s",str);    return 0;
    }
    

    直接執行是會報錯的,因為str指向的是常量區中的一個字符串,這是不可以寫的,但是如果我們更改物理頁對應的PDE和PTE的R/W屬性,則可以成功改寫。

    直接執行Access Violation。

    拆分線性地址:

    通過Cr3找到PTE,發現最后12位屬性中R/W位為0。(屬性為025)

    那么這里就需要讓R/W位為1,屬性變為027。

    !ed 30b4088 19c48027
    

    代碼能夠順利執行,字符串成功被修改。

    U/S屬性

    • U/S = 0 特權用戶
    • U/S = 1 普通用戶

    特權用戶也就意味著只有高權限才能訪問,普通用戶普通權限即可訪問。

    觀察這樣一段代碼,直接訪問肯定是失敗。

    int main(int argc, char* argv[]){
        PDWORD p = (PDWORD)0x8003F00C;
        getchar();    printf("高2G地址:%x\n",*p);    return 0;
    }
    

    我們三環程序是無法直接訪問高兩G內存空間的,這里可以用之前的調用門提權訪問,也可以通過修改頁屬性來訪問。

    這里具體細節和上面修改R/W差不多。

    可以發現這個地址的PDE和PTE的U/S位都是0。

    kd> !ed 1d50a800 0003b167kd> !ed 3b0fc 0003f167
    
    這里一不小心把程序放過去了,直接結束了沒截圖,并沒有報錯,也就不重新做這個實驗了。

    P/S位

    只對PDE有意義,PS == PageSize的意思 當PS==1的時候 PDE直接指向

    物理頁 無PTE,低22位是頁內偏移。

    線性地址只能拆成2段:大小為4MB 俗稱“大頁”

    A 位

    是否被訪問(讀或者寫)過 訪問過置1 即使只訪問一個字節也會導致PDE PTE置1

    D 位

    臟位 是否被寫過 0沒有被寫過 1被寫過

    頁目錄表(PDE)基址

    如果系統要保證某個線性地址是有效的,那么必須為其填充正確的PDE與PTE,如果我們想填充PDE與PTE那么必須能夠訪問PDT與PTT。那么存在2個問題:

    1、一定已經有“人”為我們訪問PDT與PTT掛好了PDE與PTE,我們只有找到這個線性地址就可以了。

    2、這個為我們掛好PDE與PTE的“人”是誰?

    結論就是有一個特殊的地址:0xC0300000。存儲的值就是PDT。

    獲取cr3

    kd> !dd 131fb000  + c00kd> !dd 131fb000 + c00kd> !dd 131fb000

    可以看到通過這個線性地址實際上是重新解析了cr3寄存器。

    也就是說,以后不需要Cr3,只需在當前程序內,通過C0300000這個線性地址就可以得到當前程序PDT的首地址了。

    那么PDT的首地址可以找到,PTT的首地址呢?

    頁表(PTT)基址

    還是有個特殊的線性地址:0xC0000000

    獲取debugview的線性地址。

    這個線性地址對應的就是PDT表,而PDE表中第一個地址為第一張PTT表。

    kd> !dd 18ae9000kd> !dd 0bc7a000
    

    PDT表中第二個地址為第二張PTT表。

    kd> !dd 18ae9000kd> !dd 194b9000
    

    然后我們拆分c0000000地址。

    kd> !dd 18ae9000 + c00kd> !dd 18ae9000kd> !dd 0bc7a000
    

    可以看到0xc0000000對應的物理地址就是第一張PTT表。

    再拆分c0001000地址。

    kd> !dd 18ae9000 + c00kd> !dd 18ae9000 + 4kd> !dd 0bc7a000
    

    0xc0001000對應的物理地址就是第二張PTT表。

    所以實際上的對應關系應該如下圖所示:

    根本就不存在什么PDT表,PDT表知識PTT表中的一個特殊的部分。

    掌握了0xC0001000和0xC0300000,就掌握了一個進程所有的物理內存讀寫權限。

    PDI和PTI分別指的是再PDT表和PTT表中的索引。

    訪問頁目錄表(PDT)的公式:

    0xC0300000 + PDI*4

    訪問頁表(PTT)公式:

    0xC0000000 + PDI*4096 + PTI*4

    總結

    1、頁表被映射到了從0xC0000000到0xC03FFFFF的4M地址空間。

    2、在這1024個表中有一張特殊的表:頁目錄表。

    3、頁目錄被映射到了0xC0300000開始處的4K地址空間。

    寫入shellcode到0地址執行

    這里直接看注釋,要自己捋一下。

    // CallGate0Address.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <windows.h>char buf[] = {0x6a,0x00,0x6a,0,0x6a,0,0x6a,0,0xE8,0,0,0,0,0xc3};
    __declspec(naked) void callGate(){
        _asm
        {
            push 0x30;
            pop fs;
            pushad;
            pushfd;
            lea eax,buf;
            mov ebx,dword ptr ds:[0xc0300000];        //當0xc0300000位置上的值是0時,表明地址0對應的PDE沒有掛上,跳轉代碼為掛上buf對應的物理頁。
            //不是0掛PTE就行了
            test ebx,ebx;
            je __gPDE;
            shr eax,12;        and eax,0xfffff;
            shl eax,2;
            add eax, 0xc0000000;
            mov eax,[eax];
            mov dword ptr ds:[0xc0000000],eax;
            jmp __retR;
        __gPDE:        //獲取前10位偏移
            shr eax,22;        and eax,0x3ff;        //乘以4
            shl eax,2;        //將buf對應的PDE掛到0地址
            add eax, 0xc0300000;
            mov eax,[eax];
            mov dword ptr ds:[0xc0300000],eax;
        __retR:    
                popfd;
                popad;
                retf;
        }
    }int main(int argc, char* argv[]){    unsigned int functionAddress = (unsigned int)MessageBox;    //獲取在物理頁上的偏移,后12位。
        int offset1 = ((unsigned int)buf) & 0xfff;
        *((unsigned int*)&buf[9]) = functionAddress - (13 + offset1);    char segmentGate[] = {0,0,0,0,0x48,0};    printf("MessageBox:%x  callGate:%x buf:%x\n",MessageBox,callGate,buf);
        system("pause");
        _asm
        {
            call fword ptr segmentGate;
            push 0x3b;
            pop fs;
            mov eax,offset1;
            call eax;
        }    return 0;
    }
    

    添加調用門

    kd> eq 8003f048 0040ec00`0008100a
    

    pteptt
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    在x86系統下,總說一個進程有4GB空間,那么按照這個說法來說,在windows上起一個進程就要占用4GB空間,兩個進程就要占用8GB空間,但是實際上是我們電腦的物理內存往往只有8GB,16GB多一點的可能有32GB,我們卻啟動了幾十個進程,這顯然是矛盾的。
    美國商務部工業安全局將四家公司列入出口控制的實體名單:以色列公司 NSO Group 和 Candiru,俄羅斯公司 Positive Technologies 和新加坡公司 Computer Security Initiative Consultancy PTE. LTD.。
    美國制裁了四家開發監視惡意軟件或銷售民族國家行為者(包括 NSO Group)使用的黑客工具的公司。
    (由于PTE控制著4KB物理頁的屬性,因此目標代碼所屬的整個物理頁都被設置為不可執行。若是,則修改PTE的執行屬性并進行事件注入至 #DB,內核異常處理函數將會將該異常派發給調試器。若不是,則仍需要修復PTE的可執行屬性,置位rflags.TF以便于下條指令觸發 #DB 異常被vmm接管,修復cr2并進行事件注入 #PF。
    本月初曝光的谷歌Chrome zero day漏洞已被積極利用,但現已修復。“我們認為這些襲擊具有高度的針對性”。在黎巴嫩發現的感染序列始于攻擊者破壞一家新聞機構員工使用的網站,該網站用于從演員控制的域注入惡意JavaScript代碼,該域負責將潛在受害者重定向到攻擊服務器。Avast評估了收集的信息,以確保漏洞僅被交付給預期目標。
    上?篇?章中已經簡單介紹過了CET的基本原理和實際應?的?些技術,站在防守?的視?下,CET確實是?個能 ?較有效防御ROP攻擊技術的措施。那么在攻擊者的視?來看,研究清楚CET的技術細節,進?判斷CET是否是? 個完美的防御?案,還是存在?定的局限性,則是攻擊?的重中之重。 本?由淺?深地講述CET的實現細節,最后提出?個理論可?的繞過?案,供研究者參考。
    OOB技術通常需要易受攻擊的實體生成出站TCP/UDP/ICMP請求,然后允許攻擊者泄露數據。OOB攻擊的成功基于出口防火墻規則,即是否允許來自易受攻擊的系統和外圍防火墻的出站請求。而從域名服務器中提取數據,則被認為是最隱蔽有效的方法。
    截至目前,天融信已擁有九大培訓資質,累計為國家培養了上萬名專業持證人員。截至目前,已累計開展網絡安全培訓20期,共計6萬余學時課時,累計培養專業人員2000余人。2022年,在中央網信辦指導下,網絡安全學院學生創新資助計劃正式啟動。截至目前,天融信已完成上海交大、中科大、武漢大學、北京郵電大學等十所一流網絡安全學院示范高校。
    自2019年起,天融信科技集團與中國信息安全測評中心達成專項證書運營協議,成為CISP-DSG授權運營中心,全面負責CISP-DSG運營管理工作。7月14日-15日,CISP-DSG授權運營中心組織授權機構開展考試,共有300余名考生完成在線考試。數據泄漏事件在各國帶來的影響巨大、造成的損失慘重。
    7月1日,在中央網信辦指導下,天融信科技集團等網信企業與一流網絡安全學院、中國網絡空間安全協會、中國互聯網發展基金會共同發起網絡安全學院學生創新資助計劃。中央網信辦網絡安全協調局負責人表示。天融信作為資助方之一,與其他網信企業、中國互聯網發展基金會網絡安全專項基金共計出資7800萬元,連續五年資助1200名學生開展創新研究,并對資助學生擇優獎勵。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类