Computer Emergency Response Center

Windows kernel səviyyəsində ransomware aşkarlanması üçün ümumi tələ - Proof of Concept

Bundan öncə ki, məqalələrimizdə sizlərə ransomware zərərvericiləri haqqında məlumat vermişdik. Bu məqalədə bu tipli zərərvericiləri aşkarlamaq üçün hansı metodlardan istifadə edə bilər bu haqda məlumat veriləcək. Məqalədə istifadə ediləcək metod konsepsiyanın sübütü olaraq ələ alınmalı və araşdırma aparılaraq uyğun əlavələr ilə digər effektiv metod olaraq istifadə oluna bilər.

Yanaşma

Bildiyiniz kimi bu tipli zərərvericilərin əsas məqsədi sistemdə mövcüd olan, istifadəçinin kritik fayllarını (sənəd, şəkil, musiqi, mətn və s.) şifrələyərək istifadəçidən fidyə istəməkdir. Əsas məqsədimiz zərərverici bu tip əməliyyatları həyata keçirən zaman davranış patternlərini analiz edərək əməliyyatı həyata keçirən prosesin aşkarlanmasıdır. Bunun üçün sistemdə kiçik bir honeypot (bal qabı) hazırlamaq lazım olacaq. Honeypot mexanizmi uzun zamandır istifadə edilən bir metoddur. Zərərvericilər normal fəaliyyətləri zamanı özləri bilmədən sözü gedən tələyə düşür və digər tərəf isə bundan istifadə edərək zərərli proqram haqqında məlumat toplayırlar. Məndə bu tip zərərvericiləri aşkar etmək üçün sistemdə honeypot quraraq nəticənin nə olacağını öyrənmək istədim. Bunun üçün "Filter Manager" konsepsiyasından istifadə edəcəyəm. Bunun köməkliyi ilə honeypot olaraq hazırladığım fayllar üzərində hansı əməliyyatlar aparılır bunların qeydiyyatını apararaq zərərverici prosesi aşkarlamağa çalışacam. Filter Manager xüsusi sistem kernel mexanizmidir. Bu mexanizm istifadəçilərə öz file-system filter sürücülərini yazmağa imkan yaradır. File-system stack -də özünə yer ayıran bu sürücülər fayl əməliyyatları haqqında məlumat toplamaq və lazım gələr isə müdaxilə etmək imkanına sahibdirlər. Köhnə “legacy filter”- dən fərqli olaraq minifilter adı verilən bu mexanizm daha rahat və daha sürətli filter əməliyyatlarına imkan yaradır.

Daha ətraflı: https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/filter-manager-concepts

Hazırlayacağım honeypot üçün ilk olaraq sistemdə kritik fayl formatlarında saxta fayllar yaradacam. Əsas məqsəd "minifilter" köməkliyi ilə bu fayllar üzərində hansı əməliyyatlar aparılır bunları müşahidə etmək və hədəf faylın zərərverici olub olmadığına qərara verməkdir. Hər hansı bir proqram təminatı sistemdə olan fayllar üzərində əməliyyat apardığı zaman arxa fonda sistem funksiyaları çağrılır. Misal olaraq KERNLEL32.DLL kitabxanası tərəfindən ixrac edilən CreateFile funksiyasını öz növbəsində NTDLL.DLL içərisində NtCreateFile və ya NtOpenFile adı verilən funksiyaları çağırır. NT funksiyaları isə gate adı verilən qapılardan istifadə edərək cari axını kernel səviyyəsinə salır. Əməliyyat tamamlandıqdan sonra isə axın kernel səviyyəsindən yenidən istifadəçi səviyyəsinə geri qaytarılır.

Filter mexanizmi məhz bu əməliyyatlara müdaxilə etmək imkanı yaradır. Hazırlayacağımız sürücü kernel səviyyəsində fayl aktivliklərinin qeydiyyatını apararaq bizim saxta fayllara yazma və ya silmə əməliyyatılarını izləyəcək. Əgər əməliyyyat bir neçə honeypot faylı üzərində aşkarlanar isə əməliyyatı həyata keçirən proses zərərverici propses olaraq dəyərləndiriləcək. Qeyd edilənləri daha yaxşı anlamaq üçün aşağıdakı şəkilə diqqət yetirin.

Minifilter sürücüsünün hazırlanması

Minifilter sürücümüzü hazırlamaq üçün ilk öncə kiçik bir araşdırma aparmalıyıq. Daha dəqiq desək hansı IRP sorğuları izləməliyik bunu öyrənərək sürücümüzü buna uyğun yazmalıyıq. Test əməliyyatı WannaCry ransomware üzərində aparılacaqdır. Başlanğıc olaraq 2 ədəd fayl yaradaraq ransomware-nin bu fayllar üzərində hansı əməliyyatları apardığını öyrənirik.

Şəkildə gördüyünüz zərərli proses şifrələnəcək fayla IRP_MJ_WRITE sorğusu göndərir. Filter sürücümdə məhz bu sorğuları izləyərək əgər yaratdığım honeypot fayllarına məlumat yazılar isə həmin prosesi şüphəli proses kimi qəbul edəcəyəm. Lazım olan məlumatları topladıqdan sonra keçək kodların hazırlanmasına. Callback əməliyyatı zamanı IRP_MJ_WRITE sorğusunu izləmək üçün FsFilterPreWrite funksiyasını istifadə edirəm.

CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
	{IRP_MJ_WRITE, 0, FsFilterPreWrite, NULL},
	{IRP_MJ_OPERATION_END}
}

Gələn məlumatlar üzərindən ilk öncə hansı fayla məlumat yazıldığını aşkarlayırıq. Yazılan fayl bizim honeypot faylımız olarsa IRP_MJ_WRITE sorğusunu göndərən prosesin Proses identifikator (PID) dəyərini bir siyahı içərisində saxlayırıq. Eyni proses digər honeypot fayllarına oxşar sorğu ilə müraciət edərsə bu proses şüphəli proses olaraq qeydə alınacaq.

status = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT,
&FileNameInformation);

FltParseFileNameInformation fayl adını təhlil edirik. Sorğular zamanıı lazım olduğundan çox məlumat gəldiyi üçün təhlil edilən fayl adları içərisindən bizə lazım olan fayl uzantılarını qəbul etmək üçün RtlCompareUnicodeString funksiyasını çağrılır. Burada yalınız *.bmp və *.docx uzantılarına yazma əməliyyatlarını qeydə alıram.

status = FltParseFileNameInformation(FileNameInformation)
if (!NT_SUCCESS(status))
{
	FltReleaseFileNameInformation(FileNameInformation);
	return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

if (RtlCompareUnicodeString(&extension, &FileNameInformation->Extension, TRUE) != 0)
{
	FltReleaseFileNameInformation(FileNameInformation);
	return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

Bura qədər olan əməliyyatları test etmək üçün sürücümüzü kompilasiya edib Dbgview alətinin köməkliyi ilə loglara baxırıq.

Bundan sonra ilk olaraq Compare funksiyası ilə yazılan faylları müqayisə edirəm.

BOOLEAN Compare(PUNICODE_STRING FILENAME)
{
	if (RtlCompareUnicodeString(FILENAME, &honeypot_files[0], TRUE) == 0)
	{
		return TRUE;
	}
	
	if (RtlCompareUnicodeString(FILENAME, &honeypot_files[1], TRUE) == 0)
	{
		return TRUE;
	}
	
	return FALSE;
}

Əgər yazılan fayl bizim massiv içərisində saxlanılan fayl adları ilə eynidirsə bu zaman məlumatı yazan prosesin identifikatoru əldə edilir və başqa bir massiv içərisinə yazılır. Hər 2 fayla yazan proses identifikatorları eyni olarsa bu zaman sürücü ransomwarenin aşkarlandığı haqqında istifadəçiyə mesaj verir.

if (Compare(&DosFileName->Name))
{
	DbgPrint("%p\n", PsGetCurrentProcessId());
	if (dwCount == 1)
	{
		if (PsGetCurrentProcessId() == (HANDLE)pids[dwCount - 1])
		{
			DbgPrint("Ransomware aşkarlandı: %p\n", PsGetCurrentProcessId());
		}
	} else{
		pids[dwCount] == PsGetCurrentProcessId();
		dwCount += 1;
	}
}

Sürücümüzü rebuild edərək yenidən test edirik və nəticə:

Oxşar metodika ilə digər zərərvericiləridə aşkarlamaq üçün mexanizm hazırlana bilər. Burada vacib məsələ bu tipli zərərliləri analiz edərək oxşar tərəflərini təyin etmək və filter sürücüsünü buna uyğun şəkildə dizayn etməkdir.

Press ESC to close