ტერმინი rootkit ისტორიულად მოვიდა Unix-ის სამყაროდან, სადაც ამ ტერმინის ქვეშ იგულისხმება პროგრამების, მოდულების და უტილიტების კრებული, რომელსაც ეგრედწოდებული ჰაკერი აყენებს მის მიერ გატეხილ კომპიუტერზე, მას შემდეგ რაც მიიღებს თავდაპირველ წვდომას. ეს, როგორც წესი, ჰაკერის ხელსაწყოებია (sniffers,scanners) და ტროიანული პროგრამები, რომლებიც იტევენ Unix-ის ძირითად უტილიტებს. რუთკიტი ჰაკერს საშუალებას აძლევს გამაგრდეს გატეხილ სისტემაში და დამალოს თავისი მოქმედების კვალი.
სისტემა Windows-ში, რუთკიტის ქვეშ მიღებულია ჩაითვალოს პროგრამა, რომელიც შეერწყმება სისტემას და ხელში ჩაიგდებს სისტემურ ფუნქციებს ან მოახდენს სისტემური ბიბლიოთეკის შეცვლას (ჩანაცვლებას). დაბალი დონის API ფუნქციების ხელში ჩაგდება და მოდიფიკაცია პირველ რიგში ასეთ პროგრამას საშუალებას აძლევს საკმაოდ ხარისხიანად შეინიღბოს და სისტემაში არ გამოავლინოს თავისი ქმედებები, რომელიც იცავს მას გამოვლენისაგან და ანტივირუსების დაფიქსირებისგან. ამის გარდა, მრავალ რუთკიტს შეუძლია შენიღბოს სისტემაში მყოფი მასში აღწერილი ნებისმიერი კონფიგურაციის პროცესი, ფოლდერები და ფაილები დისკზე, რეესტრში გამოყენებული გასაღებები. მრავალი რუთკიტი სისტემაში აყენებს თავის დრაივერებს და სერვისებს.
რუთკიტთან ეფექტური ბრძოლისთვის საჭიროა მისი მუშაობის პრინციპებისა და მექანიზმების გაგება. პირობითად, ყველა რუთკიტი შეიძლება დავყოთ ორ კატეგორიად: მომხმარებლის რეჟიმში მომუშავე (user-mode) და ბირთვის რეჟიმში მომუშავე (kernel-mode). რუთკიტის პირველი კატეგორია დაფუძნებულია მომხმარებლის რეჟიმის ბიბლიოთეკის ფუნქციების ხელში ჩაგდებით, მეორე კი სისტემაში დრაივერის დაყენებით, რომელიც ბირთვის დონის ფუნქციების ხელში ჩაგდებას განახორციელებს. შემდეგ ფუნქციის ხელში ჩაგდების მეთოდების აღწერა მიმდიონარეობს რუთკიტის გამოყენებით, მაგრამ უნდა გვახსოვდეს, რომ მეთოდიკის აღწერა უნივერსალურია და გამოიყენება მრავალი მარგებელი პროგრამის და უტილიტის მიერ.
მეთოდების ხელში ჩაგდების აღწერის ფუნქციები აღჭურვილია მათი მუშაობის სქემებით, წითელი ისრები მიუთითებს მუშაობის ლოგიკიდან გადახრას, რომელიც გამოწვეულია რუთკიტის ჩარევით.
ფუნქციის ხელში ჩაგდება რუთკიტს საშუალებას აძლევს მისი მუშაობის შედეგების მოდიფიკაციისა. მაგალითად, ფაილის დისკზე ძებნის ფუნქციის ხელში ჩაგდება საშუალებას გვაძლევს ძებნიდან გამოვრიცხოთ შენიღბული ფაილები, ხოლო ntdll.ZwQuerySystemInformation - ტიპის ფუნქციების ხელში ჩაგდება, საშუალებას გვაძლევს შევნიღბოთ გაშვებული პროცესები და ჩატვირთული ბიბლიოთეკები.
სანამ მომხმარებლის რეჟიმში რუთკიტის მუშაობის პრინციპებს განვიხილავდეთ, აუცილებელია მოკლედ და გამარტივებულად გადავხედოთ ფუნქციის გამოძახების პრინციპს, რომელიც განთავსებულია DLL-ში. ცნობილია ორი საბაზისო ხერხი:
გვიანი კავშირი განსხვავდება ადრეულ დაკავშირებასთან იმით, რომ DLL-ის ჩატვირთვა გაეშვება დინამიურად API LoadLibrary ფუნქციის საშუალებით. ეს ფუნქცია მდებარეობს kernel32.dll-ში, ამიტომაც თუ არ მივალთ ჰაკერულ სვლებამდე, შეგვიაძლია სტატიკურად გავუშვათ იგი. LoadLibrary-ის დახმარებით პროგრამას შეუძლია ჩატვირთოს მისთვის საინტერესო ბიბლიოთეკა დროის ნებისმიერ მონაკვეთში. შესაბამისად ფუნქციის მისამართის მისაღებად გამოიყენება kernel32.dll GetProcAddress ფუნქცია. ნახაზზე (ნაბ 4.) შეესაბამება ბიბლიოთეკის ჩატვირთვას LoadLibrary-ის დახმარებით და დგინდება მისამართები GetProcAddress-ის საშულებით. შემდეგ შეგვიაძლია გამოვიძახოთ ფუნქცია DLL (ნაბ 5.), მაგრამ რათქმაუნდა ამასთან იმპორტის ცხრილი არ გვჭირდება. იმისთვის, რომ არ გამოვიძახოთ GetProcAddress DLL-დან ფუნქციის ყოველ გამოძახებაზე, შეგვიძლია ერთჯერადად დავადგინოთ მისთვის საინტერესო მისამართები და ფუნქციები, შევინახოთ ისინი მასივში ან ზოგიერთ ცვლადებში.
სისტემა Windows-ში, რუთკიტის ქვეშ მიღებულია ჩაითვალოს პროგრამა, რომელიც შეერწყმება სისტემას და ხელში ჩაიგდებს სისტემურ ფუნქციებს ან მოახდენს სისტემური ბიბლიოთეკის შეცვლას (ჩანაცვლებას). დაბალი დონის API ფუნქციების ხელში ჩაგდება და მოდიფიკაცია პირველ რიგში ასეთ პროგრამას საშუალებას აძლევს საკმაოდ ხარისხიანად შეინიღბოს და სისტემაში არ გამოავლინოს თავისი ქმედებები, რომელიც იცავს მას გამოვლენისაგან და ანტივირუსების დაფიქსირებისგან. ამის გარდა, მრავალ რუთკიტს შეუძლია შენიღბოს სისტემაში მყოფი მასში აღწერილი ნებისმიერი კონფიგურაციის პროცესი, ფოლდერები და ფაილები დისკზე, რეესტრში გამოყენებული გასაღებები. მრავალი რუთკიტი სისტემაში აყენებს თავის დრაივერებს და სერვისებს.
რუთკიტთან ეფექტური ბრძოლისთვის საჭიროა მისი მუშაობის პრინციპებისა და მექანიზმების გაგება. პირობითად, ყველა რუთკიტი შეიძლება დავყოთ ორ კატეგორიად: მომხმარებლის რეჟიმში მომუშავე (user-mode) და ბირთვის რეჟიმში მომუშავე (kernel-mode). რუთკიტის პირველი კატეგორია დაფუძნებულია მომხმარებლის რეჟიმის ბიბლიოთეკის ფუნქციების ხელში ჩაგდებით, მეორე კი სისტემაში დრაივერის დაყენებით, რომელიც ბირთვის დონის ფუნქციების ხელში ჩაგდებას განახორციელებს. შემდეგ ფუნქციის ხელში ჩაგდების მეთოდების აღწერა მიმდიონარეობს რუთკიტის გამოყენებით, მაგრამ უნდა გვახსოვდეს, რომ მეთოდიკის აღწერა უნივერსალურია და გამოიყენება მრავალი მარგებელი პროგრამის და უტილიტის მიერ.
API ფუნქციების ხელში ჩაგდების მეთოდები მომხმარებლის რეჟიმში (user-mode)
მეთოდების ხელში ჩაგდების აღწერის ფუნქციები აღჭურვილია მათი მუშაობის სქემებით, წითელი ისრები მიუთითებს მუშაობის ლოგიკიდან გადახრას, რომელიც გამოწვეულია რუთკიტის ჩარევით.
ფუნქციის ხელში ჩაგდება რუთკიტს საშუალებას აძლევს მისი მუშაობის შედეგების მოდიფიკაციისა. მაგალითად, ფაილის დისკზე ძებნის ფუნქციის ხელში ჩაგდება საშუალებას გვაძლევს ძებნიდან გამოვრიცხოთ შენიღბული ფაილები, ხოლო ntdll.ZwQuerySystemInformation - ტიპის ფუნქციების ხელში ჩაგდება, საშუალებას გვაძლევს შევნიღბოთ გაშვებული პროცესები და ჩატვირთული ბიბლიოთეკები.
API ფუნქციის გამოძახების პრინციპები
სანამ მომხმარებლის რეჟიმში რუთკიტის მუშაობის პრინციპებს განვიხილავდეთ, აუცილებელია მოკლედ და გამარტივებულად გადავხედოთ ფუნქციის გამოძახების პრინციპს, რომელიც განთავსებულია DLL-ში. ცნობილია ორი საბაზისო ხერხი:
- ადრეული დაკავშირება (სტატისტიკურად ინპორტირებული ფუნქციები) ↴
2. გვიანი კავშირი ↴
სისტემაში კავშირის მეთოდების მიუხედავად, საჭიროა ვიცოდეთ, რომელ ფუნქციებს აექსპორტებს DLL, ამისთვის ყოველ DLL-ს აქვს ექსპორტის ცხრილი, რომელშიც ჩამოთვლილია დაექსპორტებული DLL ფუნქციები, მათი ნომრები (ორდინალები) და ფუნქციის ფარდობითი მისამართი (RVA).