Axtarış...

Windows Api Hooking

Bu məqalədə sizlərə Windows funksiyalarının Hook edilməsini və bu yolla Ring3 rootkitlərin işləmə prinsiplərindən bəhs edəcəyik.  İlk öncə qısaca məlumat üçün deyək ki, rootkilər sistemdə özlərini gizlədə bilən alətlərə verilən ümümi addır. Əlbətdə rootkitlər daha qarışıq bir sistemdir. Ancaq rootkiləri birləşdirən əsas elementlərdən biri Windows əməliyyat sistemindəki Api funksiayaları hook etmək qabiliyyətləridir. Daha aydın izah etmək üçün belə deyək sistemdə fəaliyyət göstərən proqram təmınatlarından biri sistemdə olan hər hansı bir faylı silmək üçün kernel32.dll Kitabxanasında olan DeleteFile(A->Ascii W-Unicode) funksıyasını çağırmalıdır. 


Məsələn test üçün gəlın pythonda os modulundan istifadə edərək C:\\ qovluğundakı test.txt adlı faylı silək və əslində nələr olduğunu görək.

Görundüyü kimi default olaraq os modulundakı unlink metodu faylı silmək üçün DeleteFile funksiyasından Unicode dəstəkləyəcək şəkildə istifadə edir. 

Gəlin eyni kodu C dilində yazaq və debuggerlə aydın bir şəkildə nələr olduğunu görək.

#include <windows.h>

int main(){

char file[] = "c:\\test.exe";

DeleteFileA(file);
return 0;
};

 

 

Gördüyünüz kimi PUSH EAX instructionu ilə ilk parametr stack-ə yazılır daha sonra isə DataSegmentdə olan kernel32.DeleteFileA(Import) yerləşdiyi adresə call edilir.

 

 

Həmin adresdə isə DeleteFileA funksiyası yerləşir.

 

 

Əməliyyat məhz bu cür davam edir.

Bəs Hook nədir? Hook dilimizə tərcümədə qarmaq mənasını verir. Əsas məqsəd isə api funksıyaları yaxalamaqdır.

Bəs rootkilər bundan necə istifadə edir? Bir öncəki DLL inyeksiya adlı məqaləmizdə sizlərə proseslərin yaddaşına öz DLL faylımızı necə inject etmək lazım oldüğünü göstərmişdik.
İndi belə bir şey fikirləşək. Demelı proqram faylı silmək üçün address spacesində olan kernel32.dll faylındakı DeleteFileA funksıyasının olduğu adrese call edir.
Misal olaraq adresimiz olsun 0x7C891EC5. Bu adresdə faylın silinməsi əməliyyatı həyata keçirilir.
İndi biz belə bir sey edə bilərik mi?
Öz dll fayımızı prosesə inject edirik.
DLL fayımızın tərkibində saxta DeleteFile funksiyamız olsun
Orjinal DeleteFile

msdn.microsoft.com/en-us/library/windows/desktop/aa363915(v=vs.85).aspx

MyDeleteFileA(char *filename)

Biz orjinal DeleteFileA funskıyasının olduğu adresı JMP instruction ilə öz MyDeleteFile funksiyamıza yonləndirir və beleliklə proqramı oz istidədiyimiz kimi idarə edirik.

Biz ne edəcəyik.Biz DeleteFileA funksiyasını hook edib proqramın sildiyi faylı ona silinirmiş kimi göstərib amma əslində faylı silməsinə icazə vermiyəciyik və silmək istədiyi faylı OutputDebugString
Fuksiyasl ilə debuggərə ötürəcəyik.
Bunun üçün yuxarıda ki dokumentasiyada kı return value bölməsinə baxın.
Əgər funksıya uğurla nəticələnərsə yəni fayl silinərsə funksiya geriyə BOOL tipində 0 dan fərqlı dəyər qaytaracaq.
Əks təqdirdə isə 0.

Uyğun olmadığı üçün tam funksiyanın kodlarını sizə təqdim edə bilmiyəciyik.
Lakin bunu manualla yolla etməyi sizə göstərəcəyik.

Hərəkət yolu isə bu cür olacaq.
 

 

Test üçün python ctypes modulundan istifadə edəcəyəm yəni faylı python kernel32-yə call edərək siləcək.
İlk əvvəl pythonu işə salırıq.
Daha sonra DLL faylımızı yaradırıq (SHAREABLE).
MyDeleteFileA funksıyasının adresını oyrənmək üçün DLL_attach zamanı MessageBox ilə adresı ekrana yazdırırıq.
Funksiya call near = __stdcall

#include <windows.h>
#include <stdio.h>


char dbg[128] = {0};

 

__declspec (dllexport) BOOL __stdcall MyDeleteFileA(char *filename){
OutputDebugString(filename);
return 1;
};


BOOL WINAPI DllMain(HMODULE hDLL,DWORD reason,LPVOID Reserved){

switch(reason)
{
case DLL_PROCESS_ATTACH:
//break;
sprintf_s(dbg,128,"%X",&MyDeleteFileA);
MessageBox(NULL,dbg,"MyDeleteFileA Address",64);


case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}

return TRUE;
};

DLLımızı inject edirik.
 

 

Bəli gördüyünüz kimi MyDeleteFileA funksıyamız 0x10001000 adresindədir.
İndi OllyDebugger ilə python prosesinə attach veririk.
Daha sonra kernel32.dll kitabxanasındaki DeleteFileA funksiyasını tapırıq.
 

 

Və gedirik həmin ünvana DeleteFileA və öz instructionumuzu yazırıq.

JMP 0x10001000
 

 

 

Bəli və nəticə.
Gördüyünüz kimi çağrılan funksiya 0 dan fərqli nəticə qaytarır bu o deməkdır ki fayl silinib amma əslində fayl olduğu kimi qalıb.
Əlbətdə məqaləmizdə bunu manual yolla necə edildiyini sizə başa salmaq istədik.
Real şəraitdə isə bütün bunları kompleks şəkildə yazmaq lazımdır.

msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v=vs.85).aspx

www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra

www.codeproject.com/Articles/2082/API-hooking-revealed

© 2011-2024 Bütün Hüquqlar Qorunur