Zajímavý způsob, jak skrýt škodlivé změny v SSDT - v oblasti, která je velmi dobře známá a kterou většina antirootkitů pečlivě kontroluje.
V článku věnovaném SSDT jsem se zmínil, že SSDT jsou dvě. První tabulka obsahuje adresy rutin jádra (práce s procesy, vlákny, synchronizace atd.) a nachází se v hlavním modulu jádra (často ntoskrnl.exe). Druhá struktura (KeServiceDescriptorTableShadow) se nachází v modulu win32k.sys. Tato "stínová SSDT" obsahuje v sobě dvě SSDT (je to pole) - první položkou je stejná SSDT jako v ntoskrnl.exe a druhá obsahuje adresy rutin funkcí GDI a USER. Odpovídající si tabulky v ntoskrnl.exe a win32k.sys mají jednu velmi zajímavou vlastnost - sdílejí společou SDT (Service Dispatch Table) a SPT (Service Parameter Table). Celá situace je na následujícím obrázku.
Když se nad touto strukturou trochu zamyslíme, napadne nás hned otázka: Proč to tak je? Proč nestačí jenom struktura ve win32k.sys? Abych řekl pravdu, odpověď na tuto otázku neznám. Je však pravda, že systém v drtivé většině případů využívá tabulek ve win32k.sys. Každé vlákno má totiž v jedné ze svých důležitých struktur uloženo, jakou SSDT má používat. Když vlákno vznikne, je tam adresa SSDT z ntoskrnl.exe. Jakmile však zavolá nějakou funkci GDI nebo USER, začne používat tabulku z win32k.sys a bude tak činit až do svého konce.
Ještě jeden fakt: KeServiceDescriptorTableShadow není exportována a přitom je velmi často používána. A zde mě napadlo vyzkoušet malý trik... Jelikož obě struktury sdílejí SDT a SPT pro rutiny jádra, je úplně jedno, jestli se k jejich adresám dostáváme z ntoskrnl.exe nebo z win32k.sys. Co se ale stane, když toto sdílení zrušíme?
Zrušit toto sdílení je velmi jednoduché. Prostě alokujeme blok paměti, překopírujeme do něho příslušnou SDT a přesměrujeme tam odkaz např. ze struktury v ntoskrnl.exe. Celou situaci vidíte na tomto obrázku:
Z obrázku vidíte, jak většina antirootkitů zjišťuje umístění SSDT - pomocí symbolu KeServiceDescriptorTable v ntoskrnl.exe. Když uvážíme to, že struktura v ntoskrnl.exe je málo využívána, zjistíme průšvih. Pokud rootkit provede výše popsaný trik, naskýtá se mu zajímavá možnost skrýt změny, které v SSDT provedl. Nechá nt!KeServiceDescriptorTable beze změny a upraví pouze win32k!KeServiceDescriptorTableShadow, která je často využívána. Většina antirootkitů se dívá do ntoskrnl.exe, kde najde naprosto čistou SSDT, takže nadšeně ohlásí, že je vše v pořádku. Přitom ale není - KeServiceDescriptorTableShadow je změněna a pomáhá rootkitu dělat svou práci.
Po vyzkoušení tohoto triku jsem se rozhodl otestovat několik antirootkitů, zda se nechají zmást či nikoliv. Výsledky jsou zajímavé a musím přiznat, že jsem je neočekával: jediný Rootkit Unhooker v3.7 (UG North) odhalil změny v KeServiceDescriptorTableShadow. IceSword, Radix a Rootkit Hook Analyzer selhaly.
Výsledky se mohou zdát alarmující. Na druhou stranu je pravda, že pokud rootkit použije tuto techniku, nebude jeho krytí fungovat vždy - protože pořád může někde existovat nějaké vlákno, které ještě nezavolalo žádnou funkci GDI nebo USER, a tudíž používá SSDT z ntoskrnl.exe...