Rootkit

Aktuální verze stránky ještě nebyla zkontrolována zkušenými přispěvateli a může se výrazně lišit od verze recenzované 20. srpna 2020; kontroly vyžadují 12 úprav .

Rootkit ( anglicky  rootkit , tedy „sada root -a “) je sada softwarových nástrojů (například spustitelné soubory, skripty, konfigurační soubory ), které poskytují:

Termín Rootkit historicky pocházel ze světa UNIXu a tento termín označuje sadu utilit nebo speciální modul jádra , který útočník nainstaluje do počítačového systému, který hacknul ihned po získání práv superuživatele. Tato sada zpravidla obsahuje různé nástroje pro zakrytí stop po průniku do systému, zneviditelnění snifferů , skenerů, keyloggerů , trojských koní , které nahrazují hlavní nástroje UNIX (v případě nejaderného rootkitu). Rootkit umožňuje útočníkovi získat oporu v kompromitovaném systému a skrýt stopy své činnosti tím, že skryje soubory, procesy a samotnou přítomnost rootkitu v systému.

Rootkit lze do systému nainstalovat různými způsoby: stažením přes exploit , po získání přístupu k shellu (v tomto případě lze ke stažení rootkitu ze vzdáleného zařízení použít nástroj jako wget nebo původní FTP klient ), ve zdrojovém kódu nebo zdrojích softwarového produktu.

Klasifikace rootkitů

Základní metody implementace

V systému Microsoft Windows

Existují různé technologie rootkitů, nejběžnější jsou zachycení tabulky volání (IAT, IDT, SSDT, GDT ), zachycení funkcí (například úprava počátečních bajtů), přímá úprava systémových objektů (DKOM), způsoby použití ovladačů.

Zachycení tabulek hovorů

Tabulka volání je pole, ve kterém každý prvek ukládá adresu odpovídající procedury. Takové tabulky existují jak v režimu jádra (IDT, CPU MSRs, GDT, SSDT, IRP dispatch table), tak v uživatelském režimu (IAT).

Importovat tabulku adres (IAT) je hlavní tabulka volání modulu v uživatelském režimu. Většina spustitelných souborů má jeden nebo více vestavěných IAT obsahujících adresy knihovních rutin importovaných z DLL [2] .

Na víceprocesorovém stroji existuje více instancí tabulek volání (např. IDT, GDT , MSR ). Protože každý procesor má své vlastní systémové registry (zejména GDTR - registr globální tabulky deskriptorů (GDT), IDTR - registr tabulky deskriptorů přerušení (IDT) a IA32_SYSENTER_EIP - obsahuje virtuální adresu vstupního bodu režimu jádra (MSR)) , má také vlastní systémové struktury [3] .

Při změně záznamu v tabulce volání je vykonávání programů řízeno a v případě potřeby přesměrováno na požadované funkce. Zachycený postup může [4] :

  • blokovat volání určitých aplikací (např. antivirus )
  • nahradit původní postup
  • monitorovat systém zachycením vstupních parametrů
  • výstupní parametry filtru

Obecná myšlenka zachycení je následující:

  • Identifikujte tabulku hovorů, získejte její adresu
  • Uložit existující záznam do tabulky
  • Nahraďte záznam novou adresou
  • Obnovit původní záznam

Pokud funkce odposlechu zahrnuje volání původní procedury, pak se před voláním provede blokování a monitorování, poté filtrování parametrů.

IAT je tabulka volání umístěná ve struktuře souborů aplikace. IAT ukládá adresu procedur exportovaných konkrétní knihovnou DLL . Každá knihovna DLL, na kterou aplikace odkazuje při spouštění, má svůj vlastní IAT. Chcete-li zachytit IAT, musíte provést následující:

  • Získejte přístup k adresnímu prostoru procesoru
  • Lokalizovat IAT v obrazu paměti procesoru
  • Upravte požadované IAT

Pro manipulaci s IAT je nutný přístup do adresního prostoru aplikace, ke které tabulka patří. Jedním ze způsobů je vložení DLL. Mezi metodami pro vložení DLL do adresního prostoru procesu lze uvést [5] :

  • Úprava hodnoty registru AppInit_DLL
  • SetWindowsHookEx() volání API
  • Pomocí vzdálených vláken
Zachycení úpravou kódu funkce

Princip činnosti je založen na skutečnosti, že první bajty zachycených funkcí jsou nahrazeny kódem zachycovače. Je třeba zdůraznit, že při instalaci interceptoru není analyzován kód zachycené funkce: je změněno prvních N bajtů, nikoli prvních N strojových instrukcí. Důsledkem této skutečnosti je [6] :

  1. kód zachycovače lze nastavit pouze na začátku funkce;
  2. pro každé volání odposlouchávané funkce musí zachycovač obnovit svůj strojový kód před voláním a znovu zachytit po dokončení volání.

Rootkitový algoritmus:

  1. V těle interceptoru je vytvořeno pole, do kterého je zapsáno prvních N bajtů každé ze zachycených funkcí (obvykle velikost upraveného kódu nepřesahuje 20 bajtů)
  2. Pole je vyplněno referenčním strojovým kódem zachycených funkcí.
  3. Na začátku každé zachycené funkce je napsán kód, který přenáší řízení na interceptor.

Algoritmus provozu interceptoru:

  1. Posloupnost akcí definovaná útočníkem.
  2. Obnovení prvních N bajtů zachycené funkce.
  3. Volání zachycené funkce.
  4. Opětovná úprava strojového kódu zachycované funkce: přepsání kódu, který přenáší řízení na zachycovač v prvních bajtech.
  5. Analýza a případně úprava výsledků původní funkce.
  6. Provedení operace ret, vrácení řízení programu, který funkci vyvolal.

K zachycení stačí upravit prvních pět bajtů funkce, místo kterých je zapsána operace jmp, čímž se řízení přenese na zachycovač rootkitu.

Je třeba poznamenat, že nejjednodušší systémy pro ochranu před útoky tohoto typu kontrolují první bajt volaných funkcí na přítomnost operačního kódu stroje jmp. Jako protiopatření používají vývojáři rootkitů techniky k „maskování“ kódu napsaného na začátku funkce interceptoru (pomocí příkazů jako PUSH / RET, umístění několika operátorů NOP nebo nesmyslného kódu jako PUSH AX / POP AX, stejně jako prvků polymorfismu. ).

Způsob úpravy prvních bajtů funkcí má řadu nevýhod souvisejících především s nutností obnovit strojový kód zachycených funkcí před jejich voláním a opětovným zachycením po volání. Tyto operace snižují výkon systému a mohou způsobit pád aplikací s více vlákny .

DKOM (Direct Kernel Object Manipulation)

Operační systémy řady Windows NT používají standardní objektové modely. Různé součásti prováděcího systému definují jeden nebo více typů objektů. Každá komponenta exportuje v režimu jádra sadu podporovaných funkcí a vlastností, nazývaných rozhraní COM, pro manipulaci s tímto typem objektu. Žádná komponenta nemůže přímo přistupovat k jinému objektu komponenty. Typické objekty v režimu jádra jsou [7] :

  • objekt typu zařízení (typ objektu privilegovaného režimu definovaný správcem I/O, používaný k reprezentaci fyzického, logického nebo virtuálního zařízení)
  • souborový objekt
  • symbolické odkazy
  • klíče registru
  • vlákna a procesy
  • objekt dispečera (třída typu objektu privilegovaného režimu používaná k řízení procesů odesílání a synchronizace)

Tento návrh poskytuje flexibilitu a přenositelnost, například budoucí vydání operačního systému mohou obsahovat součásti jádra, které definují podobné objekty, ale mají zcela odlišnou vnitřní strukturu. Pokud takové komponenty budou exportovat funkce se zachovanými názvy a parametry, změna nebude mít žádný účinek [3] .

Přímá manipulace s objekty jádra je poměrně výkonná technologie, kterou je těžké objevit. Existuje však řada nevýhod, jako je nestabilita metod, závislost na verzi, složitost implementace kvůli chybějícímu dokumentovanému popisu struktur a vlastností objektů. Navzdory těmto omezením vám tato metoda umožňuje skrýt procesy, ovladače zařízení, porty a zvýšit oprávnění vláken (potažmo procesů).

EPROCESS je struktura, která slouží jako vnitřní reprezentace procesu (objektu procesu). Systém Windows používá kruhový dvojitě propojený seznam struktur EPROCESS ke sledování průběhu provádění. Odkazy propojující objekty EPROCESS jsou obsaženy v poli ActiveProcessLink, jehož struktura je LIST_ENTRY [8] :

typedef struct _LIST_ENTRY { struct _LIST_ENTRY * Flink ; struct _LIST_ENTRY * Blink ; } LIST_ENTRY , * PLIST_ENTRY ;

Nejjednodušší algoritmus skrývání procesu:

  1. Získání ukazatele na proces, ke kterému patří aktuální vlákno, voláním PsGetCurrentProcess()
  2. Získání PID procesu
  3. Pokud PID neodpovídá požadovanému, provede se přechod pomocí dvojitě propojeného seznamu (pole ActiveProcessLinks, typ LIST_ENTRY)
  4. Změna polí ActiveProcessLinks. Konkrétně je odkaz na další blok EPROCESS bloku A nastaven na blok C, podobně jako odkaz na předchozí blok v bloku C. Odkazy bloku B jsou v jejich záznamu uzavřeny. Vzniknou tak dva seznamy, z nichž jeden se skládá z jednoho prvku

Vyloučení procesu ze seznamu procesů neovlivní jeho provedení. Ve Windows je spuštění kódu naplánováno na úrovni vláken, procesy definují kontext , ve kterém vlákna běží. Skrytí procesu se provádí externě v nástrojích, které se spoléhají na objekty procesu EPROCESS, jako je Správce úloh. Dispečer jádra používá jiné účetní schéma, které se opírá o jiné datové struktury (především objekt ETHREAD). Tato metoda umožňuje skrýt procesy bez ztráty funkčnosti [9] .

Ovladače

Model ovladače Microsoft podporuje vrstvenou architekturu, takže I/O požadavek (I/O požadavek, výměna dat mezi aplikacemi a ovladači) může být obsluhován řadou připojených ovladačů , z nichž každý plní svůj vlastní úkol. Řetěz ovladačů obsluhujících fyzické zařízení se nazývá zásobník. Tento modulární přístup umožňuje zahrnutí nových ovladačů do zásobníku pro zvýšení funkčnosti. V tomto případě se změní nebo přidá pouze samostatná část řetězu. Některé periferie také používají stejné řadiče (a tedy I/O sběrnice). Modularita umožňuje optimalizovat použití stejných bloků kódu namísto psaní samostatného ovladače pro každé zařízení.

V modelu WDM jsou definovány tři typy ovladačů: ovladač sběrnice, ovladače funkcí a ovladače filtrů. Ovladače filtrů jsou obvykle umístěny mezi ostatními moduly a zachycují IRP , které jimi procházejí . Před odesláním IRP sousednímu ovladači může filtr prozkoumat obsah nebo jej upravit, aby ovlivnil další chování systému. Například při pořizování obrazu disku z kritického serveru pro prostoje lze použít ovladač filtru ke změně datového toku tak, aby skryl některé soubory.

IRP paket (I/O request packet) je datová struktura jádra Windows, která zajišťuje výměnu dat mezi aplikacemi a ovladačem a také mezi ovladačem a ovladačem. Když aplikace obdrží požadavek, I/O manažer vygeneruje příslušné IRP, které lokalizuje a předá nejvyššímu objektu v zásobníku ovladačů. Pokud byl nejvyšší ovladač schopen zpracovat příchozí IRP sám, dokončí požadavek a vrátí IRP správci I/O. Jinak ovladač provede částečné zpracování, lokalizuje podkladový objekt v zásobníku a požádá správce I/O, aby předal IRP dalšímu ovladači.

Při vytváření IRP správce I/O rezervuje oblast paměti za hlavičkou. Alokovaná paměť se používá k zápisu pole struktur IO_STACK_LOCATION přidělených pro každý ovladač zásobníku:

Velikost paměti odpovídá počtu ovladačů v zásobníku. Pole je očíslováno od 1, což odpovídá ovladači spodního zásobníku. Struktura obsahuje informace o funkci ovládání ovladače, kterou volá I/O manažer (pole MajorFunction a MinorFunction), parametry předávané funkci (pole Parametry, obsah se liší v závislosti na funkci), ukazatel na objekt ovladače (DeviceObject), ukazatel na funkci dokončení (pole CompletionRoutine, tato funkce je v ovladači nejvyšší úrovně).

Funkce řízení ovladače po prvním přijetí IRP obnoví parametry z příslušné pozice I/O zásobníku voláním IoGetCurrentIrpStackLocation(). Dále se provedou předepsané akce, po kterých se v případě předání IRP ovladači spodního zásobníku stane následující:

  • nastavení pozice I/O zásobníku v IRP
  • registrace funkce ukončení (volitelné)
  • odeslání IRP navazujícímu ovladači
  • návratový stavový kód (NTSTATUS)

Existují dva standardní způsoby, jak nastavit pozici zásobníku pro následující ovladač [10] :

  • Aktuální pozice je odeslána beze změn, funkce:
VOID IoSkipCurrentIrpStackLocation ( IN PIRP Irp );

Funkce sníží ukazatel na pole IO_STACK_LOCATION o jednu. Při předávání IRP se tedy ukazatel obnoví (automaticky se zvýší o jednu), v důsledku toho bude použita stejná část zásobníku. Při použití této metody bude na konci zásobníku nevyužitá oblast.

  • Pokud je nutné předat obsah aktuální pozice zásobníku, kromě ukazatele na funkci dokončení (pole CompletionRoutine), použijte:
VOID IoCopyCurrentIrpStackLocationToNext ( IN PIRP Irp );

Předání IRP dalšímu ovladači se provádí pomocí funkce:

NTSTATUS IoCallDriver ( IN PDEVICE_OBJECT DeviceObject , IN OUT PIRP Irp );

První argument je ukazatel na základní objekt ovladače. Způsob získání takové adresy je určen konkrétní řídicí funkcí, standardní metoda neexistuje.

Každý požadavek musí být ukončen buď posledním ovladačem v zásobníku (žádné další předávání IRP není možné) nebo jedním z nadřazených ovladačů.

Správce I/O zahájí proces dokončení pro daný IRP, když některý z ovladačů pro zpracování IRP zavolá funkci dokončení IoCompleteRoutine(). Při volání správce I/O vyplní zásobník I/O aktuálního ovladače nulami a potom zavolá ovladač vyšší úrovně s funkcí ukončení nastavenou na toto IRP. Pouze blok stavu I/O v IRP je k dispozici k určení, jak je požadavek zpracován ovladačem nižší úrovně funkce dokončení ovladače vyšší úrovně.

Takto nainstalovaný ovladač filtru ve skutečnosti umožňuje zpracovávat nejen příchozí IRP pakety (například blokové čtení určitého sektoru disku), ale také spravovat výsledky zpracování downstream ovladačů inicializací funkce ukončení [11] .

Další metodou implementace rootkitů je úprava MBR a zavedení jádra operačního systému – bootkitů (například BackDoor.MaosBoot).

Tento typ škodlivého kódu v prostředí Windows je znám již od počátku 90. let pod názvem stealth viry .

V systémech UNIX a Linux

  • implementováno nahrazením hlavních systémových utilit (velmi snadno detekovatelné kontrolami integrity, navíc jsou snadno blokovány povinnými nástroji pro kontrolu přístupu , jako je SELinux nebo AppArmor );
  • implementovaný jako modul jádra a založený na záplatování VFS nebo zachycování tabulky systémových volání (sys_call_table);
  • založené na úpravě fyzické paměti jádra.

Další funkce

Kromě sebe může rootkit zpravidla maskovat přítomnost všech adresářů a souborů popsaných v jeho konfiguraci na disku, klíčů v registru v systému . Z tohoto důvodu se přirozeně objevily „namontované“ knihovny rootkitů. Mnoho rootkitů instaluje do systému vlastní ovladače a služby (samozřejmě jsou také „neviditelné“).

Rootkity pro a proti DRM

Rootkity jsou ve skutečnosti většinou softwaru na ochranu proti kopírování (a prostředky, jak tyto ochrany obejít – například emulátory jednotek CD a DVD ) .

V roce 2005 společnost Sony BMG Corporation začlenila do svých zvukových disků CD ochranu založenou na rootkitech , která se instalovala bez vědomí uživatele.

Anti-rootkity

Jedná se o utility nebo rezidentní moduly, které detekují přítomnost rootkitů v systému a (v různé míře) je odstraňují. Na to existuje mnoho konkurenčních nástrojů – placených i bezplatných, ale všechny využívají podobné principy.

Metody detekce rootkitů

Existuje známý algoritmus pro chytání MEP rootkitů. Jeho podstata spočívá v tom, že stejné informace jsou registrovány několika způsoby - pomocí API a "přímo", poté se přijatá data porovnávají při hledání nesrovnalostí. Nejčastěji se skenují importní tabulky a tabulky  volání Native API , stejně jako strukturálně celý souborový systém.

Základní arzenál nástrojů pro zachycení rootkitů je založen na následujících metodách.

  1. vyhledávání podpisů. Používá se již od dob prvních antivirů a jedná se o hledání jedinečného bajtového řetězce (podpisu), který je vlastní škodlivému programu v naskenovaném souboru.
  2. Heuristický nebo behaviorální analyzátor. Tato technologie je založena na hledání odchylek v nastavení systému, konfiguračních souborech Linuxu nebo registru Windows, podezřelém chování procesů a modulů a podobně.
  3. Kontrola integrity. Tento typ vyhledávání je založen na porovnávání kontrolního součtu (MD5 a podobně) nebo digitálního podpisu různých systémových souborů s bází obsahující kontrolní součet původních souborů. V případě neshody program usoudí, že soubor byl změněn nebo zcela nahrazen.

Poznámky

  1. Kolesničenko, 2006 , s. 29.
  2. Kolesnichenko, 2006 , Přepis adres funkce.
  3. 1 2 Solomon, Russinovich, Ionescu, 2012 .
  4. Blunden, 2009 .
  5. Blunden, 2009 , Vložení knihovny DLL.
  6. Zaitsev, 2006 , Zachycování modifikací prvních bajtů funkce.
  7. Správa objektů jádra  : [ eng. ] // MSDN .
  8. Blunden, 2009 , Kapitola 7 Změna objektů jádra.
  9. Blunden, 2009 , Kapitola 7. Změna objektů jádra.
  10. Různé způsoby zpracování IRP – Rychlý přehled  : [ eng. ] // MSDN .
  11. Zaitsev, 2006 , Špion na klávesnici založený na ovladači filtru.

Literatura

  • Zaitsev O. Rootkity, SpyWare_AdWare, Keyloggery a zadní vrátka. Detekce a ochrana / Oleg Zajcev. - Petrohrad: BHV-Petersburg, 2006.
  • Blunden B. The Rootkit Arsenal / Bill Blunden. — Plano, Texas: Wordware Publishing, Inc., 2009.
  • Kolesnichenko D. ROOTKITS pod Windows / Denis Kolesnichenko. - Petrohrad: Věda a technika, 2006.
  • Solomon D., Russinovich M., Ionescu A. Windows Internals / David Solomon, Mark Russinovich, Alex Ionescu. — Microsoft Press, 2012.

Odkazy