GDT and LDT in Windows kernel vulnerability exploitation

A few weeks ago j00ru has visited me, and, as one can figure out, some more or less interesting ideas came to be. One of such ideas was to use the Call-Gate mechanism in kernel/driver exploit development on Windows, or, to be more precise, to use a write-what-where condition to convert a custom LDT entry into a Call-Gate (this can be done by modifying just one byte), and using the Call-Gate to elevate the code privilege from user-land to ring0. The idea was turned into some PoC exploits, and finally, into the paper presented below.

But first, I would like to thank Unavowed for a great amount of time to correct the English in the paper, and also for converting the paper to LaTeX (we started with using OO.org, then converting it into Word 2007, and we finished with the paper being in LaTeX). I would also like to thank Agnieszka 'Sorrento Aishikami' Zerka for parallel English-checking of the paper :)

GDT and LDT in Windows kernel vulnerability exploitation by Matthew "j00ru" Jurczyk and Gynvael Coldwind
PDF: call_gate_exploitation.pdf (680KB)
PoC: ldtsource.zip (13kb) (the file is also attached to the PDF)

1. Abstract
2. The need of a stable exploit path
3. Windows GDT and LDT
4. Creating a Call-Gate entry in LDT
4.1. 4-byte write-what-where exploitation
4.2. 1-byte write-what-where exploitation
4.3. Custom LDT goes User Mode
5. Summary
+ References
+ Attachments

All comments are mostly welcomed, both here and on j00ru's blog! :)

Update (17 January 2010, 19:32 GMT+1): We've found out that some one PoC exploit in the source package contained some old experimental code instead of the new one. It's fixed now. Sorry about that :)
MD5 of the old/bugged (ldt)sources.zip / pdf: 95f1b1551e34d7f28789fa17693f0c17 / 6cb745e451be165f49a66876557cb518
MD5 of the new fixed (ldt)sources.zip / pdf: 63657de78b1a2a35b46fc29aa8df81cf / 6840185722dc69048e0bf5434f19d5cb

Update 2: Indy on the woodmann.com forum started a very interesting discussion about the technical aspect of this method :)


2010-01-17 11:48:29 = Ruben
Neat paper, congrats for both of you.

I see a contradiction though, you state that "The actual problem with the majority of the techniques
presented in the above publications is the fact
that they are mostly based on undocumented, internal
Windows behavior, that is not guaranteed to remain in
the same form across system updates, service packs or
respective system versions" which is true. However, despite LDT is a well-known x86 architecture artifact, the ways you use to obtain the required offsets seem to be heavily relying in undocumented methods.

Anyway, good work!
2010-01-17 13:04:05 = j00ru
Hi Ruben!

You are particularly right at a point, if referring to the third method presented in the paper ("Custom LDT goes User Mode"). Using NtQueryInformation / KPROCESS structure offsets cannot be considered ultra-compatible, indeed.

However, the main goal we wanted to achieve - stability - was the purpose of creating the 4.1 and 4.2 sections; the only Windows-dependent component there, is a well-documented GetThreadSelectorEntry function. On the other hand, we also wanted to show that there is a great number of attack vectors related to GDT/LDTs in general, and all of them are worth to be researched / used in practical exploitation ;>

Add a comment:

URL (optional):
Math captcha: 8 ∗ 8 + 8 =