PDA

View Full Version : FIY: Printable “Windows Kernel Address Protection” paper out


j00ru vx tech blog
December 4th, 2011, 07:24
That’s just a short notification that I decided to release the Windows Security Hardening Through Kernel Address Protection article published in Hack in the Box Magazine #7 over a month ago (see HITB #7 on the wild, at last). The paper is now available in a nicely formatted, printer-friendly format. If you missed it then, [...]

http://j00ru.vexillium.org/?p=1038

Indy
December 4th, 2011, 17:20
Quote:
Stack Cookies[24], Heap Protection [8] (heap cookies, safe unlinking etc.), Exception-
Handling Protection [7] (SafeSEH, SEHOP etc.), Data Execution Prevention
[21] and Address Space Layout Randomization [6].


You did not describe the main mechanism - bugchecks. And the new Int 0x29

These two mechanisms have great potential..

About /safeseh see pm.

Quote:
nt!HalDispatchTable


This is not true. As a backdoor should be used a great number of other mechanism's. For example to create a descriptor to the IDT.

Quote:
Since all kernel stacks are allocated from non-pageable memory


The kernel stack may be discharged - see EnableStackSwap etc. By the way there is still DPC-stack

j00ru
December 6th, 2011, 06:17
Quote:
[Originally Posted by Indy;91493]You did not describe the main mechanism - bugchecks. And the new Int 0x29

These two mechanisms have great potential..


Although the article was released after Windows 8 Developer's Preview, the new operating system is out of scope of this paper (as mentioned in the original blog post about HITB #7).

Quote:
[Originally Posted by Indy;91493]About /safeseh see pm.


Waiting for the pm.

Quote:
[Originally Posted by Indy;91493]This is not true. As a backdoor should be used a great number of other mechanism's. For example to create a descriptor to the IDT.


What do you specifically disagree with? To my best knowledge, the "HalDispatchTable+4" technique is by far the most common one, and one of the easiest to pull off. Can you elaborate more on the advantages of using IDT over HalDispatchTable, except for the availability of the IDT address (which is not an issue, since Microsoft has not yet dealt with the kernel address information disclosure problems)?

Quote:
[Originally Posted by Indy;91493]The kernel stack may be discharged - see EnableStackSwap etc. By the way there is still DPC-stack


Oh. You might be right on that, let me do some investigation and follow up with that.

Indy
December 6th, 2011, 09:57
j00ru

Bugcheck's is the primary mechanism of protection.

Quote:
Waiting for the pm.


epic fail )

2525

Quote:
What do you specifically disagree with?


You describe the ancient techniques. Why do I need your hal table, if you can create a gate in the IDT, and cause it to immediately remove =)

j00ru
December 6th, 2011, 17:24
Quote:
[Originally Posted by Indy;91500]Bugcheck's is the primary mechanism of protection.


Could you please elaborate (with some specific information) on how are bugchecks related to the few exploitation mitigation mechanisms listed in my paper?

Quote:
[Originally Posted by Indy;91500]epic fail )


Speaking of epic fails, you tried to send a message to an account used exclusively for importing my blog posts, and not my regular one...

Quote:
[Originally Posted by Indy;91500]You describe the ancient techniques. Why do I need your hal table, if you can create a gate in the IDT, and cause it to immediately remove =)


Calling something an "ancient technique" is not an argument for me. In both cases, you need to restore the original bytes you overwrote in order to avoid leaving trivial evidence of exploitation.

Again - can you give any specific advantages of IDT over HalDispatchTable, or refer to some sources? Additionally, maybe you could provide me with a link to a public kernel exploit making use of a fake idt entry?

Indy
December 7th, 2011, 02:54
Code:
Could you please elaborate (with some specific information) on how are bugchecks related to the few exploitation mitigation mechanisms listed in my paper?

Add a vector to Inbv. And call bugcheck. This is a standard defense mechanism.

Necessary to form an t-frame. In the beginning it is necessary to find a HalTable. Why, if you can write a link to your SDT into the thread and call the service ?

Code:

; +
; 3 #BP INT 3
; 4 #OF INTO
;>5 #BR BOUND
; 6 #UD Invalid Opcode
;
MakeAndCallTrapGate proc StartupParameter:PVOID
Local Idt[2]WORD
sidt [Idt]
add Idt[IDTR_FIELD._Base],(5*8 - 2)
invoke CsrWriteFourToKernelSpace, Idt[IDTR_FIELD._Base]
.if !Eax
add Idt[IDTR_FIELD._Base],8
invoke CsrWriteFourToKernelSpace, Idt[IDTR_FIELD._Base]
.if !Eax
push esp
push esp
bound eax,qword ptr [esp]
.endif
.endif
push eax
$CALL pRtlExitUserThread
jmp $
pRtlExitUserThread::
PVOID ?
MakeAndCallTrapGate endp


Similarly you can call the gate:
Code:
CHK_4R_KM macro p4R
Local Load
push ebx
pushfd ; IF
cli
mov ebx,p4R
sub esp,2*4
sidt [esp]
Call Load
add esp,4*4 ; !CF
jmp @f
Load:
mov edx,[esp + 2] ; IDT base
mov cx,[edx + 14*8 + 6] ; hi ptr
mov ax,[edx + 14*8] ; lo ptr
pop word ptr [edx + 14*8]
pop word ptr [edx + 14*8 + 6]
mov ebx,[ebx] ; test R
stc ; CF
@@:
lea esp,[esp + 2*4]
mov [edx + 14*8],ax
mov [edx + 14*8 + 6],cx
popfd ; IF
pop ebx
endm

j00ru
December 7th, 2011, 05:23
Quote:
[Originally Posted by Indy;91506]
Code:
Could you please elaborate (with some specific information) on how are bugchecks related to the few exploitation mitigation mechanisms listed in my paper?

Add a vector to Inbv. And call bugcheck. This is a standard defense mechanism.


^_-;

Quote:
[Originally Posted by Indy;91506]Necessary to form an t-frame. In the beginning it is necessary to find a HalTable. Why, if you can write a link to your SDT into the thread and call the service ?


Necessary to form a trap-frame? At which point of exploitation do you think one needs to forge the t-frame? When using the HalDispatchTable technique, the attacker-specified pointer is called from within a syscall handler or its subroutine, so it does not care about anything other than executing the payload (elevation of process privileges etc). It then returns and leaves the rest of the work (returning back to r-3) to the nt!NtQueryIntervalProfile routine.

Necessary to find HalDispatchTable - that's correct, however doing so is currently a trivial task, since it is an exported symbol. You just need to find the kernel base address (e.g. through NtQuerySystemInformation) and use the correct offset (e.g. done by a LoadLibraryEx + GetProcAddress). Nothing harder to achieve than using SIDT, as in your example.

Last but not least, in order to set-up a valid, fully controlled IDT entry, you need to be able to write 8 controlled bytes in the kernel space (unless you just want to change some specific fields of the IDT_ENTRY structure, but that's not the case in your example). On X86 platforms, it is not always possible to achieve since several other common conditions (such as a pool-based buffer overflow) result in a 4-byte write-what-where. Given the above, I still believe it is more feasible to use the "ancient" HalDispatchTable for as long as Microsoft doesn't restrict access to kernel address space information (the IDT technique might be indeed useful in such a scenario).

Indy
December 7th, 2011, 09:48
j00ru

Callbacks is a lot. You have chosen Hal, this is not acceptable. First it will cause a reactionAV. Second dynamic detective(wincheck etc.). The above creation of SDT ideal. You do not need to know basis or kernel, or export to analyze. In addition, as it will behave at W8 ?
That the table used R.Santamarta(reversemode.com). It has long been a detective. And information about this backdoor is older than I am

Why did you decide that AV does not filter the challenge ?

For example the simplest task - set the interrupt vector. How do you be a t-frame ?

j00ru
December 10th, 2011, 12:14
Quote:
[Originally Posted by Indy;91509]Callbacks is a lot. You have chosen Hal, this is not acceptable.


Whether a solution is acceptable or not depends on the context, and HalDispatchTable was just an example for triggering ring-0 execution through an overwritten static function pointer, suitable in many cases.

Quote:
[Originally Posted by Indy;91509]First it will cause a reactionAV. Second dynamic detective(wincheck etc.). The above creation of SDT ideal.


I am unsure of what you're referring to, but in general, mangling with the IDT is as noisy and easy to detect as anything else (if not easier).

Quote:
[Originally Posted by Indy;91509]You do not need to know basis or kernel, or export to analyze.


Yes, that's a nice advantage indeed, but it makes no difference on the Windows editions available today, with lots of other kernel leakages described in the paper. However, it might make a difference in a few years, who knows

Quote:
[Originally Posted by Indy;91509]In addition, as it will behave at W8 ?


I haven't had a chance to verify that yet, but my guess is that it works just fine (if you mean Windows 8, that is).

Quote:
[Originally Posted by Indy;91509]That the table used R.Santamarta(reversemode.com). It has long been a detective. And information about this backdoor is older than I am


I don't know of any other sources describing the techniques before Ruben, who did so in 2007. You must be really young...

Quote:
[Originally Posted by Indy;91509]Why did you decide that AV does not filter the challenge ?

For example the simplest task - set the interrupt vector. How do you be a t-frame ?


Could you rephrase?

Honestly, I can't really see the point of this discussion. The paper lists all of the potential exploitation vectors made available by lack of kernel address space information restrictions, no matter of how good or bad they can be in real scenarios (although using most of them is usually feasible). And IDT is discussed, as well...

Indy
December 10th, 2011, 14:07
j00ru
Quote:
I am unsure of what you're referring to, but in general, mangling with the IDT is as noisy and easy to detect as anything else (if not easier).

Not IDT, but SDT. The purpose - call the code to !CPL. And the call must be in the t-frame. This is a normal call service. Load your SDT and call service. After that restore the SDT:
Code:
SDT:
; SST[0]
PVOID offset ServiceTable
PVOID 0 ; CounterTable
ULONG 1 ; ServiceLimit
PBYTE ArgumentTable
; SST[1], shadow not used.
ServiceTable:
PVOID offset DispatchService
ArgumentTable:
BYTE 2*4 ; Arg's

; UM:
; KTHREAD.ServiceTable -> offset SDT

push [KTHREAD.ServiceTable]
push KTHREAD.ServiceTable
xor eax,eax
mov edx,esp
Int 2Eh
add esp,2*4

; KM:
DispatchService proc ThServiceTable:ULONG, pServiceTable:PVOID
mov eax,dword ptr fs:[124H] ; KPRCB.CurrentThread: PETHREAD
mov ecx,ThServiceTable
mov edx,pServiceTable
mov dword ptr [eax + ecx],edx
; .. payload

j00ru
December 13th, 2011, 00:25
Quote:
[Originally Posted by Indy;91521]Not IDT, but SDT. The purpose - call the code to !CPL. And the call must be in the t-frame. This is a normal call service. Load your SDT and call service. After that restore the SDT:


Ah, that sounds interesting, neat idea