seminarski rad: procesna zaštitna...

23
Sveučilište u Zagrebu Fakultet elektrotehnike i računarstva Martin Grmek Seminarski rad: Procesna zaštitna stijena Zagreb, rujan 2005.

Upload: vandan

Post on 16-Mar-2019

229 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Sveučilište u Zagrebu Fakultet elektrotehnike i računarstva

Martin Grmek

Seminarski rad: Procesna zaštitna stijena

Zagreb, rujan 2005.

Page 2: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

II

Sadržaj

1. Uvod ............................................................................................................................................1

2. Detekcija pokretanja aplikacije (procesa)..................................................................................2

2.1. Uporaba dinamičke biblioteke........................................................................................................2 2.1.1. Uporaba Registry-a ....................................................................................................................................3 2.1.2. Uporaba sveobuhvatnih sistemskih Windows zakački ..............................................................................3

2.2. Uporabom API funkcije PsSetCreateProcessNotifyRoutine().....................................................5 2.2.1. Kako radi komunikacija između jezgrenog upravljačkog program i nadzorne aplikacije .........................5 2.2.2. NT jezgreni upravljački program...............................................................................................................5 2.2.3. Problem zaustavljanja procesa ...................................................................................................................6

2.3. Modifikacijom tablice SSDT...........................................................................................................7 2.3.1. Modifikacija SSDT tablice u praksi...........................................................................................................8

3. Praktični rad .............................................................................................................................10

3.1. Manipulacija procesima ................................................................................................................10

3.2. Detekcija novog procesa s provjerom sigurnosne politike .........................................................11 3.2.1. Detekcija novog procesa ..........................................................................................................................12 3.2.2. Sustav sigurnosne politike .......................................................................................................................14

4. Upute za korištenje ...................................................................................................................16

4.1. Instalacija .......................................................................................................................................19

5. Zaključak ..................................................................................................................................20

6. Literatura ..................................................................................................................................21

I

Page 3: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

1

1. Uvod

Ideja je napraviti zaštitu koja bi štitila operacijski sustav od pokretanja neželjenih aplikacija kao što su crvi, trojanski konji i druge aplikacije sa skrivenim destruktivnim svojstvima (sadržajem). Zaštita bi radila na principu kao i zaštitne stijene za mrežu. Definirala bi se sigurnosna politika koja bi definirala ponašanje aplikacija, odnosno procesa. Drugim riječima, prilikom pokretanja aplikacije za koju nije definirana sigurnosna politika (kao i kod zaštitne stijene za mrežu) korisniku bi se dalo na izbor, što želi učiniti s trenutno pokrenutom aplikacijom:

• dopustiti da se pokrene • zabraniti da se pokrene.

Svaka odluka, po želji korisnika, pamtila bi se i spremala u sustav sigurnosne politike. Ovakav način zaštite sustava pouzdaniji je od bilo kojeg antivirusnog programa. Npr. ako je

virus novi, i nema ga u bazi virusa, anti-virusni program nije ga u mogućnosti prepoznati sve dok proizvođač antivirusnog programa ne izda proširenje baze virusa. Do tog trenutka može proći i više dana, a do tada već može biti kobno za operacijski sustav. Možda je za „običnog“ korisnika ovakav sustav zaštite prekompliciran, ali postoji rješenje da administrator računala snimi već definiranu sigurnosnu politiku i time olakša korištenje za „običnog“ korisnika.

Page 4: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

2

2. Detekcija pokretanja aplikacije (procesa)

Postoji više metoda detekcije pokretanja aplikacije odnosno procesa. Spomenuti ću neke od metoda koje ću u daljnjem tekstu detaljnije objasniti:

1. Uporaba dinamičke biblioteke (DLL) 2. Uporabom API funkcije PsSetCreateProcessNotifyRoutine() 3. Modifikacijom tablice SSDT (System Service Dispatch Table)

2.1. Uporaba dinamičke biblioteke Stvara se dinamička biblioteka datoteka koja u DllMain funkciji detektira poruke

DLL_PROCESS_ATTACH. Kada neka aplikacija otvara dinamičku biblioteku, tada se u DllMain funkciji, unutar dinamičke biblioteke, signalizira poruka DLL_PROCESS_ATTACH. Ideja je da se svaki proces „prisili“ na učitavanje naše dinamičke biblioteke prilikom pokretanja, koja bi onda detektirala pokretanja procesa. Ostaje problem kako učitati dinamičku biblioteku u svaki proces, tj. kako „prisiliti“ svaki proces da prilikom pokretanja učita našu dinamičku biblioteku. To je moguće uporabom:

1. registry-a 2. sveobuhvatnih sistemskih Windows zakački

Nakon što detektiramo poruku DLL_PROCESS_ATTACH, pozivom API funkcije

GetCurrentProcessId() možemo dobiti oznaku procesa. Preko oznake procesa korištenjem ostalih API funkcija možemo doći do imena datoteke procesa i drugih stvari koje su nam potrebne za provjeru procesa u sustavu sigurnosne politike. Slijedi primjer DllMain funkcije:

Slika 2.1: Primjer DllMain funkcije

BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { if( ul_reason_for_call == DLL_PROCESS_ATTACH ) { // dohvati ime procesa u kojem je u čitan DLL char lib_name[MAX_PATH]; ::GetModuleFileName(hModule, lib_name, MAX_PATH); DWORD pID = ::GetCurrentProcessId(); // Javi aplikaciji da je proces kreiran ... } return TRUE; }

Page 5: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

3

2.1.1. Uporaba Registry-a

Da bi novi proces, koji koristi dinamičku biblioteku USER32.DLL, učitao unaprijed pripremljenu dinamička biblioteku, možemo jednostavno ubaciti naziv naše dinamičke biblioteke u sljedeći registry ključ:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Cu rrentVersion\Windows\AppInit_DLLs

Vrijednost ovog ključa sadrži naziv jedne dinamičke biblioteke ili grupe dinamičkih biblioteka

odvojenih ili zarezom ili razmakom. Prema MSDN dokumentaciji [1], sve dinamičke biblioteke navedene kao vrijednost tog ključa, učitavaju se od svake Windows aplikacije pokrenute u trenutnoj sjednici. Zanimljivo je da je stvarno učitavanje navedenih dinamičkih biblioteka dio inicijalizacijskog postupka USER32.DLL datoteke. USER32 u svojoj DllMain funkciji čita vrijednost navedenog registry ključa i poziva funkciju LoadLibrary() za svaku od navedenih datoteku.

Međutim ovaj trik se primjenjuje samo na aplikacije koje koriste USER32.DLL. Drugo ograničenje je da je ovaj mehanizam podržan samo u Windows-ima NT, 2k i XP. Premda je ovo bezopasan način učitavanja dinamičke biblioteke u procese Windows-a postoji nekolicina nedostataka:

• U želji da aktiviramo odnosno deaktiviramo proces učitavanja dinamičke biblioteke,

moramo ponovno pokrenuti operacijski sustav. • Dinamička biblioteka koju želimo učitati će se jedino u procese koje koriste USER32.DLL

datoteku, stoga nećemo dobiti informaciju o pokretanju konzolnih aplikacija, budući da one obično ne koriste USER32.DLL datoteku.

• Nemamo nikakvu kontrolu nad učitavanjem dinamičke biblioteke u procese. To znači da se dinamička biblioteka učitava u svaku GUI aplikaciju, bez obzira željeli mi to ili ne. Time se pojavljuje redundantni dodatak, koji može poprilično narast ukoliko je trenutno aktivan velik broj aplikacija.

• Problem zaustavljanja procesa, nešto kasnije više o ovom problemu (poglavlje 2.2.3.).

2.1.2. Uporaba sveobuhvatnih sistemskih Windows zak ački

Jako popularan način učitavanja dinamičke biblioteke u ciljani proces bazira se na Windows zakačkama (Windows Hooks). Kako je pokazano u MSDN-u zakačka je zamka u sustavu baratanja porukama.

Aplikacija može instalirati filtar funkciju koja će pratiti promet poruka u sustavu i pojedinom procesu prije nego one stignu na cilj.

Zakačka se uobičajeno implementira u dinamičkoj biblioteci kako bi se udovoljili osnovni

zahtjevi za sveobuhvatne sistemske zakačke (system-wide hooks). Osnovni koncept ove vrste zakački je da se procedure povratnog poziva zakačke izvrši u adresnom prostoru svakog zakačenog procesa u sustavu. Da bi instalirali zakačku koristimo API funkciju SetWindowsHookEx() s odgovarajućim parametrima. Jednom kada aplikacija instalira sveobuhvatnu sistemsku zakačku, operacijski sustav raspoređuje dinamičku biblioteku u adresni prostor svakog procesa.

Zbog toga će globalne varijable u dinamičkoj biblioteci biti u svakom procesu posebno i ne

mogu se dijeliti između procesa koji su učitani unutar zakačene dinamičke biblioteke. Sve varijable koje sadrže dijeljene podatke moraju biti postavljeni unutar shared data sekcije. Sljedeći dijagram pokazuje primjer registriranja zakačke od strane Hook Server procesa i učitavanje u adresni prostor aplikacija Apllication One i Application Two. (dijagram i dio teksta preuzeto iz [2]).

Page 6: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

4

Slika 2.2: Način rada sveobuhvatne sistemske zakačke Sveobuhvatna sistemska zakačka registrirana je samo jednom nakon pokretanja API funkcije

SetWindowsHookEx() . Ako nije došlo do pogreške, funkcija vraća hvataljku na zakačku. Vraćena vrijednost potreban je na kraju naše proizvoljne funkcije zakačke, kada se poziva API funkcija CallNextHookEx() . Nakon uspješnog poziva API funkcije SetWindowsHookEx() , operacijski sustav automatski učitava (ali ne nužno i odmah) dinamičku biblioteku u sve procese koji udovoljavaju zahtjevima konkretnog filtara zakačke.

Slika 2.3: Proizvoljne funkcije zakačke

Ne postoji drugi način da se rastereti jednom zakačena dinamička biblioteka (učitana je u adresni

prostor ciljnog procesa) nego da proces koji je registrirao zakačku pozove API funkciju UnhookWindowsHookEx() ili da se aplikacija koja je bila zakačena ugasi.

Evo nekih prednosti ovog pristupa:

• Ovaj mehanizam podržan je od Windows-a NT/2K/XP i familije Windows 9x, a vjerojatno će biti i podržan i u budućim verzijama Windows-a.

• Za razliku od registry metode, ovaj mehanizam omogućuje učitavanje i rasterećivanje dinamičke biblioteke po potrebi.

Iako je ovakav način učitavanja dinamičke biblioteke zgodan, prate ga neki nedostaci:

• Windows zakačke mogu značajno degradirati performanse cijelog sustava, zato što povećavaju količinu procesiranja koji sustav mora obaviti za svaku poruku.

LRESULT CALLBACK CBTProc( int nCode, WPARAM wParam, LPARAM lParam) { if ( (nCode==HCBT_ACTIVATE) || (nCode==HCBT_SYSCOM MAND) || (nCode==HCBT_QS) || (nCode==HCBT_CREATEWND) ) { //pokrenut je novi proces, izvrši obradu i javi a plikaciji } // Sve poruke moramo proslijediti dalje sa CallNex tHookEx. return ::CallNextHookEx(sg_hGetMsgHook, nCode, wPa ram, lParam); }

Page 7: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

5

• Vrlo je teško uklanjati pogreške kod ovog mehanizam • Ova vrsta zakački utječe na procesiranje cijelog sustava i u nekim slučajevima (greške -

bug) mora se resetirati sustav kako bi se ispravila greška. • Ova metoda neće raditi sa sistemskim servisima (system services). • Problem zaustavljanja procesa, nešto kasnije više o ovom problemu (poglavlje 2.2.3.).

2.2. Uporabom API funkcije PsSetCreateProcessNotifyRoutine() Windows NT/2K/XP pružaju API funkcije, poznate kao „Process Structure Routines“ [3]

eksportirane od strane NTOSKRNL.DLL. Jedna od tih funkcija je PsSetCreateProcessNotifyRoutine() i ona nudi mogućnost registriranja sveobuhvatne sistemske funkcije povratnog poziva, koji operacijski sustav poziva svaki puta kada ne pokreće novi proces ili se postojeći uništava. Korištenjem spomenute funkcije lako se implementira metoda praćenja stvaranja i uništavanja procesa jednostavnim NT jezgrenim upravljačkim programom, koji će nadzornoj aplikaciji javljati stanja procesa. Uloga upravljačkog programa je detekcija izvođenja procesa i obavješćivanje nadzorne aplikacije o tim događajima.

Prednosti ove metode su:

• Dinamički je moguće učitati i rasteretit jezgreni upravljački program. • Omogućeno je registriranje i odjava funkcije povratnog poziva.

Nedostatak ove metode je isti onaj kao i kod metode detekcije uporabom dinamičke biblioteke, a

to je problem zaustavljanja procesa.

2.2.1. Kako radi komunikacija izme đu jezgrenog upravlja čkog program i nadzorne aplikacije

Jezgreni upravljački program tada kreira imenovani događaj koji se koristi za signalizaciju nadzorne aplikacije u trenutku kada je došlo do događaja (npr. proces je pokrenuo ili završio). Nadzorna aplikacija otvara isti događaj i kreira osluškujući dretvu koja čeka na događaj.

Nadzorna aplikacija pošalje zahtjev upravljačkom programu za početak nadgledanja. Upravljački

program pozove funkciju PsSetCreateProcessNotifyRoutine() s odgovarajuća dva parametra. Prvi specificira adresu funkcije povratnog poziva, odgovorne za primanje obavijesti o kreiranju ili uništavanju procesa od operacijskog sustava. Na temelju obavijesti iz funkcije povratnog poziva, upravljački program signalizira događaj kako bi se obavijestila nadzorna aplikacija da se nešto desilo. Nadzorna aplikacija tada dobiva podatak, o konkretnom događaju, iz upravljačkog programa i sprema ga u specijalni red za čekanje za daljnju obradu.

Ukoliko nema više potrebe za nadzorom, nadzorna aplikacija šalje zahtjev upravljačkom programu za prestanak nadzora. Upravljački program tada deaktivira nadzorni mehanizam.

2.2.2. NT jezgreni upravlja čki program

Ulazna točka DriverEntry() izvodi jedino inicijalizaciju upravljačkog programa. I/O menadžer poziva ovu funkciju kada je upravljački program učitan. Pošto PsSetCreateProcessNotifyRoutine() dopušta registraciju i odjavu funkcije povratnog poziva, implementirat ćemo proces registracije i odjave u otpremnoj rutini upravljačkog programa (driver's dispatch routine). To će nam omogućiti dinamičko pokretanje i zaustavljanje procesa za nadziranje koristeći IOCTL signale (kontrolni kod IOCTL_PROCESSFIREWALL_ACTIVATE_MONITORING). Jednom kad je funkcija povratnog poziva registrirana, svaki puta kada se proces pokrene ili uništi, operacijski sustav pozvat će funkciju povratnog poziva. Ova funkcija punit će spremnik koji će se čitati iz nadzorne aplikacije. Sljedeće što se dešava je da upravljački program signalizira imenovani događaj

Page 8: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

6

čime će nadzorna aplikacija, koja čeka taj događaj, biti obaviještena da ima dostupnih podataka za dohvatiti.

2.2.3. Problem zaustavljanja procesa

Zasad nijedna od familije Windows operacijskih sustava nema dokumentiranu API funkciju za zaustavljanja proces, kao što postoji funkcija SuspendThread() za zaustavljanje dretvi.

Proces bi se trebao zaustaviti prilikom svog pokretanja. To bi nam omogućilo da proces provjerimo u sustavu sigurnosne politike, prije nego što on počine djelovati. Nakon što se utvrdi prema sustavu sigurnosne politike, proces se može nastaviti ili uništiti.

Problem smo riješili na sljedeći način: Prolazeći kroz listu dretvi koje pripadaju određenom

procesu, svaku dretvu zaustavljamo funkcijom SuspendThread() . Nažalost postoje neki problemi:

• Pozivanjem funkcije SuspendThread() za dretvu koja posjeduje sinkronizacijski objekt, muteks ili kritični odsječak, može dovesti do potpunog zastoja ukoliko neka dretva pokušava održati sinkronizaciju sa dretvom koja je zaustavljena.

• Nisu svi programi predviđeni da budu zaustavljeni, pogotovo oni više dretveni. Tako da neki programi se mogu ponašati neprirodno nakon ponovnog pokretanja.

• Može se dogoditi da nakon dohvaćanja liste dretvi procesa, proces kreira novu dretvu koja nije u listi, i koja onda neće biti zaustavljena.

Dohvaćanje liste dretvi željenog procesa moguće je korištenjem CreateToolhelp32Snapshot()

funkcije. Evo kôda funkcije PauseProcess() :

Slika 2.4: Funkcija PauseProcess , za zaustavljanje procesa

BOOL PauseProcess(DWORD dwOwnerPID) { HANDLE hThreadSnap = NULL; BOOL bRet = FALSE; THREADENTRY32 te32 = {0}; // Napravimo snimak svih dretvi u sustavu hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAP THREAD, 0); if (hThreadSnap == INVALID_HANDLE_VALUE) return (F ALSE); // Pripremimo strukturu za prihva ćanje informacija o dretvi. te32.dwSize = sizeof(THREADENTRY32); // Slijedi nastavak ...

Page 9: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

7

Slika 2.5: Nastavak funkcija PauseProcess , za zaustavljanje procesa

Analogno PauseProcess() funkciji definiramo i ResumeProcess() funkciju, jedino umjesto

SuspendThread() koristimo funkciju ResumeThread() .

2.3. Modifikacijom tablice SSDT Po mojem mišljenju, modifikacija SSDT (System Service Dispatch Table) tablice jedna od

najboljih, ali i najsloženijih metoda za detekciju pokretanja procesa. Temelji se na modifikaciji ponašanja sustava, stavljanjem zakačke na izvorne API funkcije jezgre (Kernel Native API), odnosno samo na funkciju ZwCreateProcess() .

Ova tehnika implementira se modifikacijom zapisa unutar jezgrene sistemsko servisne otpremne tablice (System Service Dispatch Table). Ovakve modifikacije osiguravaju da zakačena funkcija biva pozvana prije originalne temeljne API funkcije (Native API). Zakačena funkcija najčešće na kraju poziva originalnu temeljnu API funkciju i mijenja izlazne rezultate prije vraćanja rezultata u pozivajući program. Ova tehnika nam pored detekcije pokretanja procesa omoguće i sakrivanje datoteka i procesa, sprečavanje uništavanje procesa i dr.

Prednost uporabe ove metode:

• Kao glavnu prednost ove metode mogao bi istaknuti da se procesi detektiraju u realnom vremenu i ne može se dogoditi da obavijest o kreiranju procesa kasni.

• Ovdje se ne javlja problem zaustavljanja procesa, jer se proces provjerava u sustavu sigurnosne politike i prije nego što biva kreiran. Time se ujedno i štede sredstva koje bi proces zauzeo prilikom svog kreiranja.

Nedostaci:

• Nažalost ovu metodu koriste i neki zlonamjerni programi (kernel rootkits) pa se može dogoditi da neki antivirusni programi ili neki drugi programi za zaštitu detektiraju naš program kao zlonamjerni program.

... // Prolazimo kroz snimak, i tražimo dretve koje pr ipadaju traženom procesu // Ukoliko dretva pripada, suspendirajmo ju if (Thread32First(hThreadSnap, &te32)) { do { if (te32.th32OwnerProcessID == dwOwnerPID) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESU ME, FALSE, te32.th32ThreadID); SuspendThread(hThread); CloseHandle(hThread); } } while (Thread32Next(hThreadSnap, &te32)); bRet = TRUE; } else bRet = FALSE; CloseHandle (hThreadSnap); return (bRet); }

Page 10: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

8

Da je ova metoda vrlo kvalitetna i učinkovita pokazuje da se ona koristi u nekim vrlo kvalitetnim programima za zaštitu od upada kao što su Kerio Personal Firewall 4, DiamondCD Process Guard 2 i Sebek 2.1.5.

2.3.1. Modifikacija SSDT tablice u praksi

Pokazat ćemo način zakačivana funkcije ZwWriteFile() . U Windows-ima, aplikacije za

zapisivanje podataka u datoteke koriste API funkciju WriteFile() eksportiranu od strane KERNEL32.DLL. U KERNEL32.DLL implementacija funkcije WriteFile() poziva temeljnu API funkciju ZwWriteFile() eksportiranu od strane NTDLL.DLL . Posao obavljen od strane ZwWriteFile() obavlja se u jezgrenom prostoru, tj. u prostoru jezgre operacijskog sustava. Zato implementacija ZwWriteFile() u NTDLL.DLL sadrži samo minimalni kôd koji se prenosi u prostor jezgre operacijskog sustava korištenjem prekida 0x2E .

Slika 2.6: Rastavljanje (disassembly) funkcije ZwWriteFile()

Čarobni broj 0xED u prvoj liniji je servisni broj (Service Number) za funkciju ZwWriteFile() u

Windows-ima 2k. Koristi se kao indeks u jezgrinoj servisno otpremnoj tablici (SSDT) za pronalaženje adrese funkcije koja sadrži stvarni kôd za zapisivanje podataka u datoteku. Adresa SSDT-a može se pronaći unutar servisne opisne tablice (Service Descriptor Table – SDT).

Referenciranje na SDT moguće je KeServiceDescriptorTable simbolom, koji je eksportiran od strane NTOSKRNL.EXE.

Slika 2.7: Struktura KeServiceDescriptorTable simbola

Prvi član strukture, SDT.ServiceDescriptor[0].KiServiceTable , sadrži pokazivač na SSDT

sistemskih funkcija implementiranih od NTOSKRNL.EXE. Kako je bilo spomenuto ranije, SSDT sadrži polje funkcijskih pokazivača koji pokazuju na temeljne API pozive. Broj ServiceLimit sadrži broj funkcijskih pokazivača u polju.

Vrijednost tipa DWORD KiServiceTable[0xED] je funkcijski pokazivač na NtWriteFile()

funkciju, koja sadrži stvarni kôd za zapisivanje u datoteku. Dakle, da bi promijenili ponašanje API funkcije WriteFile() , jednostavno trebamo napisati zamjensku funkciju, učitat je u prostor jezgre operacijskog sustava kao upravljački program, i izmijeniti KiServiceTable[0xED] da pokazuje na zamjensku funkciju. Zamjenska funkcija treba zadržati kopiju originalnog funkcijskog pokazivača

1- MOV EAX, 0ED 2- LEA EDX, DWORD PTR SS:[ESP+4] 3- INT 2E 4- RETN 24

typedef struct ServiceDescriptorTable { SDE ServiceDescriptor[4]; } SDT; typedef struct ServiceDescriptorEntry { PDWORD KiServiceTable; PDWORD CounterTableBase; DWORD ServiceLimit; PBYTE ArgumentTable; } SDE;

Page 11: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

9

(originalnu vrijednost KiServiceTable[0xED] ), tako da se originalna funkcija može pozvati te da se obavi namjeravani zadatak.

Pored modifikacije SSDT-a iz prostora jezgre operacijskog sustava pomoću jezgrenog

upravljačkog programa, SSDT moguće je promijeniti i iz korisničkog prostora (user-space) prostora, korištenjem metode direktnog zapisa u memoriju jezgre operacijskog sustava korištenjem \device\physicalmemorij . Više o ovoj metodi možete pronaći u dokumentu Defeating Kernel Native API Hookers by Direct Service Dispach Table Restoration [5].

Page 12: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

10

3. Prakti čni rad

Za razliku od jezgrenog upravljačkog programa koji je napisan u C-u, nadzorna aplikacija je napisana u Delphi-u. Aplikacija je više dretvena i sastavljena od tri dijela:

• manipulacije procesima • detekcija novog procesa s provjerom sigurnosne politike • manipulacija pravilima sigurnosne politike.

Slika 3.1: Dijagram toka poruke od upravljačkog programa do nadzorne aplikacije Način kako aplikacija radi je sljedeći: Aplikacija čeka na imenovani događaj koji signalizira

operacijski sustav. Kada je događaj signaliziran, aplikacija zaustavlja novonastali proces, njegove informacije ubacuje u listu za čekanje, te signalizira da u redu za čekanje ima elemenata. Sada se za svaki proces u listi za čekanje provjerava u sustavu sigurnosne politike. Ukoliko je definirano pravilo, s procesom se postupa prema pravilu, a ukoliko nije definirano pravilo, stanje se prijavljuje korisniku koji onda odlučuje kako postupiti.

3.1. Manipulacija procesima Aplikacija prikazuje popis svih trenutno aktivnih procesa sa sljedećim informacijama:

• ikona procesa • ime datoteke procesa (Image Name) • jedinstveni broj procesa (PID) • količina memorije koju proces koristi (Mem Usage) • prikaz Description polja iz verzije datoteke procesa (Description) • prikaz File version polja iz verzije datoteke procesa (Version) • puna putanja do datoteke procesa (File Path) • argumenti procesa (Command Line)

Za dobivanje popisa aktivnih procesa, upotrijebljena je nedokumentirana NTDLL funkcija

NtQuerySystemInfomation . Ova funkcija ima mnogo mogućnosti, među ostalima, dohvaća listu svih aktivnih procesa. Funkcija vraća pokazivač na polje tipa SYSTEM_PROCESS_INFORMATION.

Page 13: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

11

Za razliku od Task Managera, aplikacija omogućuje ubijanje i više procesa odjednom. Pošto aplikacija prilikom pokretanja postavlja SeDebugPrivilege ovlasti, nemože se dogoditi da se neki proces ne može ubiti ili da mu se ne može pristupiti.

Slika 3.2: Kôda funkcije za postavljanje SeDebugPrivilege

3.2. Detekcija novog procesa s provjerom sigurnosne politike Kao što je već ranije spomenuto na početku 3. poglavlja, aplikacija čeka na imenovani događaj

koji signalizira operacijski sustav. Kada je događaj signaliziran, aplikacija zaustavlja novonastali proces, njegove informacije ubacuje u listu za čekanje, te signalizira da u redu za čekanje ima elemenata. Sada se za svaki proces u listi za čekanje provjerava u sustavu sigurnosne politike. Ukoliko

function NTSetPrivilege(sPrivilege: string = 'SeDeb ugPrivilege'; bEnabled: Boolean= true): Boolean; var hToken: THandle; TokenPriv: TOKEN_PRIVILEGES; PrevTokenPriv: TOKEN_PRIVILEGES; ReturnLength: Cardinal; begin Result := True; // Only for Windows NT/2000/XP and later. if not (Win32Platform = VER_PLATFORM_WIN32_NT) th en Exit; Result := False; // obtain the processes token if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then begin try // Get the locally unique identifier (LUID) . if LookupPrivilegeValue(nil, PChar(sPrivilege ), TokenPriv.Privileges[0].Luid) then begin TokenPriv.PrivilegeCount := 1; // one privi lege to set case bEnabled of True: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; False: TokenPriv.Privileges[0].Attributes := 0; end; ReturnLength := 0; // replaces a var parame ter PrevTokenPriv := TokenPriv; // enable or disable the privilege AdjustTokenPrivileges(hToken, False, TokenP riv, SizeOf(PrevTokenPriv), PrevTokenPriv, Ret urnLength); end; finally CloseHandle(hToken); end; end; // test the return value of AdjustTokenPrivileges . Result := GetLastError = ERROR_SUCCESS; if not Result then raise Exception.Create(SysErrorMessage(GetLastE rror)); end;

Page 14: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

12

je definirano pravilo, s procesom se postupa prema pravilu, a ukoliko nije definirano pravilo, stanje se prijavljuje korisniku koji onda odlučuje kako postupiti.

3.2.1. Detekcija novog procesa

Detekcija procesa sastavljena je od tri klase: • TProcessNotification • TQueuedContainer • TProcessMonitor

Slika 3.3: Dijagram toka obrade poruke o nastanku novog procesa

TProcessNotification je dretva koja čeka događaj kreiran od strane upravljačkog programa. Čim je proces bio kreiran ili uništen, upravljački program signalizira objekt događaja i dretva TProcessNotification klase se probudi. Tada aplikacija prima podatke od upravljačkog programa. Nadalje se podaci dodaju u spremnik reda za čekanje (TQueuedContainer ) korištenjem metode Append() .

TQueuedContainer je dretveno siguran upravljački mehanizam reda za čekanje. Evo načina

kako javna metoda Append() za dodavanje novih elemenata u red radi:

1. Pauzira proces 2. Zaključa pristup do objekta 3. Doda podatke 4. Signalizira fElementAvailableEvent objekt događaja 5. Otključa objekt

Page 15: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

13

Slika 3.4: Funkcija Append , za dodavanje elemenata u red Budući da je dizajnirana da obavještava kada je dostupan element u redu čekanja, ona sadrži

dretvu, koja čeka sve dok element ne postane dostupan u lokalnom spremniku. Evo i pseudo kôda:

1. Čeka se na objekt događaja fElementAvailableEvent 2. Zaključa pristup do objekta 3. Izdvoji se podatak stavke 4. Otključa se objekt 5. Procesiraju se podaci koji su dohvaćeni iz reda čekanja

Slika 3.5: Metoda za obradu novih elemenata u redu čekanja

function TQueuedContainer.Append(Item: PProcessInfo ): Boolean; begin // Pause all created processes if Item^.bCreate then SuspendProcess(Item^.hProce ssID); //Wait to get fMonitor Result := WAIT_OBJECT_0 = WaitForSingleObject(fMo nitor, INFINITE); if Result then begin try // Add it to the queue fContainer.Push(Item); // Notify the waiting thread that there is av ailable // element in the queue for processing SetEvent(fElementAvailableEvent); finally ReleaseMutex(fMonitor); end; end; end;

procedure TQueuedContainer.DoOnProcessCreatedTermin ated; var RemoveFromQueue: Boolean; ret: DWord; begin RemoveFromQueue := True; while RemoveFromQueue do begin fxItem := nil; ret := WaitForSingleObject(fMonitor, INFINITE); if ret = WAIT_OBJECT_0 then begin RemoveFromQueue := fContainer.Count > 0; if RemoveFromQueue then // Is there anything in the queue fxItem := fContainer.Pop // Get the element from the queue else ResetEvent(fElementAvailableEvent); end; ReleaseMutex(fMonitor); // Process it only there is an element that ha s been picked up if RemoveFromQueue then begin Synchronize(xAssigned); //Generated event syn chronize with VCL end else Break; end; end;

Page 16: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

14

Klasa TProcessMonitor predstavlja okosnicu sustava za detekciju novog procesa. Ona sadrži prethodne dvije klase, koje koristi za signaliziranje događaja OnProcess , te dvije javne metode za pokretanje i zaustavljanje sustava za detekciju novog procesa.

Slika 3.6: Deklaracija klase TProcessMonitor

Metode za pokretanje i zaustavljanje sustava za detekciju novog procesa, šalju podatak upravljačkom programu o vrsti akcije koja se poduzima.

Slika 3.7: Metoda za zaustavljanje nadzornog mehanizma

3.2.2. Sustav sigurnosne politike

Sustav sigurnosne politike trebao bi provjeravati autentičnost svakog pokrenutog procesa. Moglo bi se definirati više načina detekcije autentičnosti, recimo:

1. Jednostavna – koja bi provjerava veličinu, vrijeme kreiranje, vrijeme modificiranja

izvršne datoteke procesa 2. Detaljna – koja bi pored jednostavne provjere izračunala hash izvršne datoteke procesa

pomoću md5.

TProcessMonitor = class private ... public ... function StartMonitoring: Boolean; function StopMonitoring: Boolean; property OnProcess: TProcessMonitorEvent read f ProcessE write fProcessE; end;

function TProcessMonitor.StopMonitoring: Boolean; var cmd: TDriverCommand; dwBytesReturned: DWord; begin Result := not fStarted; if Result then Exit; if fDriverHandle = 0 then begin fDriverHandle := CreateFile(PAnsiChar('\\.\'+fD riverName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_REA D or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, // Perform synchronous I/O 0); // No template Result := not (INVALID_HANDLE_VALUE = fDriverHa ndle); if not Result then Exit; end; cmd.bActivate := False; // Activate/Deactivate the process Result := DeviceIoControl(fDriverHandle, IOCTL_PROCESSFIREWALL_ACTIVATE_MONITORING, @cmd, sizeof(cmd), nil, 0, dwBytesReturned, nil); fStarted := not Result; end;

Page 17: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

15

Pored provjere autentičnosti, sustav sigurnosne politike za svaki proces bi pogledao da li je za taj proces definirano pravilo ponašanja. Ukoliko je definirano pravilo ponašanja, s procesom bi se postupilo prema pravilu, u suprotnom, korisniku bi se ponudila mogućnost odabira.

U početku ovakav sustav bio bi „naporan“ za korisnika. S vremenom, za često pokretane aplikacije definirala bi se pravila ponašanja, te bi se aplikacije izvršavale bez obavješćivanja korisnika.

Da se cijeli sustav ne bi previše usporio, implementiran je jednostavan način detekcije

autentičnosti. Klasa TSecurityPolicy podatke o pravilima ponašanja pohranjuje u dvostruko povezanu listu.

Element liste je tipa TParentNode :

Slika 3.8: Struktura TParentNode

Struktura NodeInfo sadrži dva pokazivača, na sljedeći i na prethodni element, dok su u

FileInfo zapisani podaci potrebni za detekciju autentičnosti. Ukoliko je postavljen parametar AllowChildProcess , tada se roditelju dozvoljava pokretanje procesa, s time da se još onda provjeravaju pravila za dijete. Ako je postavljen parametar AllowAllProcess , tada roditelj može pokrenuti bilo koji proces bez daljnje kontrole. Za svako dijete u listu se dodaje element tipa TChildNode :

Slika 3.9: Struktura TChildNode Postavljanjem parametra Allow , dopušta se pokretanje dijete procesa. Ukoliko dođe do

pokretanja izmijenjene datoteke procesa (promijenjene veličine, vremena kreiranje ili vremena modificiranja izvršne datoteke procesa) aplikacija će obavijestiti korisnika o tome, ako nije postavljen AllowModified parametar, i ako korisnik prihvati pokretanje procesa, tada će se osvježiti podaci potrebni za detekciju autentičnosti procesa.

Za svaki roditelj proces u listu se dodaje po jedan zapis o njegovom ponašanju. Svaki roditelj

ima pokazivač na dvostruko povezanu listu svoje djece. Ovakva organizacija ubrzava pretraživanje liste, zato što se prvo u jednoj manjoj listi traži roditelj, a zatim se u listi djece pronađenog roditelja traži dijete proces.

TParentNode = record NodeInfo: TSecurityNode; FileInfo: TSecurityFileInfo; ChildrenHead, ChildrenTail: PChildNode; AllowChildProcess, AllowAllProcess: Boolean; end;

TChildNode = record NodeInfo: TSecurityNode; FileInfo: TSecurityFileInfo; Allow, AllowModified: Boolean; end;

Page 18: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

16

PParentNode

Glava

PParentNode PParentNode

PChildNode

PChildNode

PChildNode

PChildNode

PChildNode

PChildNode

PParentNode

Slika 4: Organizacije liste procesa u sustavu sigurnosne politike Sva pravila moguće je snimiti u željenu datoteku. Snimanje se obavlja prilikom zatvaranja

aplikacije, dok se učitavanje obavlja prilikom pokretanja aplikacije.

4. Upute za korištenje

Program se nakon instalacije automatski pokreće i prikazuje se u SysTray-u.

Slika 4.1: Izgled aplikacije u SysTray-u Pritiskom desne tipke miša na ikonu otvara se izbornik, koji omogućuje otvaranje aplikacije (Show) ili izlaz iz aplikacije (Exit):

Page 19: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

17

Slika 4.2: Izbornik iz SysTray-a

Otvaranje aplikacije moguće je dvostrukim pritiskom lijeve tipke miša na ikonu aplikacije.

Slika 4.3: Glavni prozor aplikacije; prikaz aktivni procesa u sustavu

Pritiskom desne tipke miša na neki od obilježenih procesa otvara se izbornik koji omogućuje ubijanje procesa ili više njih odjednom. Ubijanje procesa moguće je i pritiskom tipke Del.

U izborniku Options moguće je podesiti brzinu osvježavanja liste aktivnih procesa. Postoje četiri mogućnosti:

• High, svakih 0.5 sekundi, • Normal, svake 1 sekunde, • Low, svakih 5 sekundi i • Pause, zaustavljeno osvježivanje liste procesa.

Page 20: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

18

Slika 4.4: Izbornik brzine osvježivanja liste aktivnih procesa Da bi se vidjelo stanje sigurnosne politike, odabire se opcija Security Policy.

Slika 4.5: Glavni prozor aplikacije; prikaz pravila iz sustava sigurnosne politike Ovdje su prikazana sva pravila iz sustava sigurnosne politike. Ukoliko pravilo nema postavljeno

polje Parent File Name, to znači da je to pravilo od roditelja. Poslije roditelja, dolaze i pravila za djecu tog roditelja. Pravila je moguće brisati odabirom opcije Delete iz izbornika koji se prikaže prilikom pritiskanja desne tipke miša na obilježeno pravilo. Brisanjem pravila roditelja, brišu se i sva pravila djece kojima je obrisan roditelj. Sva pravila se snimaju prilikom gašenja aplikacije, te se prilikom pokretanja aplikacije učitavaju.

Ako se želi izaći iz aplikacija, tada se mora odabrati opcija Exit iz izbornika File ili iz izbornika

koji se prikaže prilikom pritiskanja desne tipke miša na ikonu u SysTray-u.

Page 21: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

19

Kada se pokrene novi proces za kojeg nije definirano pravilo ponašanja u sustavu sigurnosne politike, korisniku se prikaže prozor sa mogućnošću odabira ponašanja.

Slika 4.6: Prozor s mogućnostima korisnika nakon pokretanja aplikacije za koju nije definirano pravilo u sustavu sigurnosne politike

Ako se odabere opcija Create a rule for this event and don't ask me again definirat će se pravilo

da se proces smije odnosno ne smije pokrenuti ako se pritisne gumb Permit odnosno Deny. Opcija Don't save the rule ima značenje da se, ukoliko se definira, pravilo ponašanja ne usnimi u datoteku sa svim pravilima ponašanja na izlasku iz aplikacije.

Obilježavanje opcije Create a rule for parent application, roditelj proces (u ovom slučaju Windows Explorer) moći će ili neće moći pokretati procese, ako pritisnemo gumb Permit odnosno Deny.

4.1. Instalacija Instalacijske program vodit će vas kroz korake instalacije programa. Da bi se program mogao

instalirati, korisnik mora imati mogućnost upisivanja u registry i mogućnost instalacije upravljačkog programa. Najjednostavnije rješenje je da korisnik ima administratorske ovlasti prilikom pokretanja instalacije programa.

Instalacija će zapisati putanju do izvršne datoteke pod nazivom ProcessFilewall u ključ HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Curre ntVersion\Run . Time će se omogućiti pokretanje aplikacije svaki puta prilikom pokretanja Windows-a. Nakon zapisivanja u registry, instalacija će kopirati datoteku ProcObsrv.sys u <Windows>\System32 direktorij, nakon čega će registrirati upravljački program za automatsko pokretanje prilikom pokretanja Windows-a.

Page 22: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

20

5. Zaklju čak

Detekcija pokretanja procesa modifikacijom SSDT tablice (System Service Dispatch Table) vrlo je komplicirana. Implementirana je nešto lakša, ali ne i jednostavna metoda detekcije pokretanja procesa uporabom API funkcije PsSetCreateProcessNotifyRoutine() .

Naizgled aplikacija radi dobro. Međutim javilo se nekoliko problema. Nadzorna aplikacija obavijesti korisnika o novom procesu, ali se proces „provuče“ pored funkcije za zaustavljanje procesa PauseProcess() .

Budući da su danas pisci nepoželjnih programa vrlo obrazovani, i moguće je da je virus napisan kao sistemski servis (system service), nažalost, ovaj program neće uspjeti detektirati njegovo pokretanje.

Implementacijom metode koja koristi modifikaciju SSDT tablice omogućilo bi se proširenje za

nadgledanje registry-a i drugih dijelova sustava, u svrhu zaštite sustava od neželjenih programa. Ubacivanjem mogućnosti nadzorne aplikacije u Task Manager, dodatno bi se približio program korisnicima.

Page 23: Seminarski rad: Procesna zaštitna stijenasigurnost.zemris.fer.hr/ostalo/rootkit/2005_grmek/download/Process... · Uporaba Registry -a ... Uporaba sveobuhvatnih sistemskih Windows

Procesna zaštitna stijena

21

6. Literatura

[1] MSDN Knowledge base Q197571

[2] API hooking revealed by Ivo Ivanov, dostupno na: http://www.codeproject.com/system/hooksys.asp

[3] Windows DDK Documentation, Process Structure Routines, dostupno na: http://msdn.microsoft.com/library/default.asp?url=/ library/en-us/kmarch/hh/kmarch/k108_2qwi.asp

[4] Detecting Windows NT/2K process execution by Ivo Ivanov, dostupno na: http://www.codeproject.com/threads/procmon.asp

[5] Defeating Kernel Native API Hookers by Direct Service Dispach Table Restoration, dostuno na: http://www.security.org.sg/code/SIG2_DefeatingNativ eAPIHookers.pdf