“Ransomware” deyilən zaman ağlmıza ilk gələn zərərvercilərdən biri məhz “WannaCry” olacaqdır. Sözü gedən zərərərvericinin tarixi haqqında ətraflı məlumatı wikipedia üzərindən əldə edə bilərsiniz. Günümüzə qədər bu zərərverici-nin texniki analizləri bir çox mütəxəssislər tərəfindən aparılmışdır. Lakin wannacry-ın nə olduğu, nələr etdiyi və necə etdiyi suallarına cavabı birdə öz dilimizdə cavablandırmaq üçün zərərvericinin texniki analizini apardıq. Analiz prosesi zərərvericinin hədəf olaraq təyin etdiyimiz faylı “decoy” necə şifrləyəcəyi haqqında olacaqdır. Digər funksionallıqlar məqalədə yer almaqyacaq.
Analiz edəcəyimiz nüsxə “ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa” hash dəyərinə sahib “WannaCry” nüsxəsidir. 32 bitlik applikasiya C/C++ dilində hazırlanıb. Kompilasiya vaxt damğası bizə zərərvericinin 2010-ci ildə yaradıldığını (compile) göstərir (manipulasiya ediləbiləcək dəyərdir).
4 ədəd PE bölməsindən ibarət zərərverici import tablosunda eyni sayda dinamik kitabxana faylı istifadə edir.
Nüsxəyə aid resurs qovluğunda 3 ədəd qovluq mövcuddur. Bunlardan biri (XIA) “PK” başlığına malik arxiv faylı idi.
Resurs bölməsində saxlanılan ZIP arxiv faylı şifrə ilə mühafizə edilir. İlkin mərhələdə zərərverici ilk olaraq cari prosesin adını buferə kopyalayır.
Daha sonra kompüter adı uzunluğunda təsadüfi mətn generasiya edir.
Proses fayl yolundan proses adını ayırıb geri qalan qovluğu “SetCurrentDirectoryW” ilə cari qovluq edir.
Daha sonra cari istifadəçiyə məxsus “SOFTWARE\WanaCrypt0r” açarını yaradır və cari qovluğu “wd” dəyəri altında bura yazır.
Ardınca resurs bölməsində olan “XIA” resursunu ixrac edir. Arxivi ixrac etmək üçün “WNcry@2ol7” şifrəsindən istifadə edir.
Burada tor aləti, sistemdə kritik fayllar şifrələndikdən sonra istifadəçiyə göstəriləcək mesajlar, şifrəli halda saxlanılan əsas şifrələyici modul və s. kimi məlumatlar saxlanılır. Daha sonra “XIA” -ın ixrac edildiyi qovluq üzərində daha 2 əməliyyat icra edir. Bunlardan biri sözü gedən qovluğu gizlətmək digəri isə sözü gedən qovluğa hər kəs üçün tam səlahiyyət verməsidir.
Zərərverici statik analiz prosesini çətinləşdirmək üçün çağrılacaq sistem funksiyaları birbaşa import tablosundan çağırmır. Bunun üçün funksiya adreslərini dəyişənlərə kopyalayır və bu dəyişənlər üzərindən çağırır. Belə olan halda zərərverici analizləri zamanı funksiyalara müraciət edən funksiyaları aşkar etmək çətinləşir. Sözü gedən funksiyalar aşağıdakılardır:
kernel32.dll - [CreateFileW, WriteFile, ReadFile, MoveFileW, MoveFileExW, DeleteFileW, CloseHandle]
advapi32.dll - [CryptAcquireContextA, CryptImportKey, CryptDestroyKey, CryptEncrypt, CryptDecrypt, CryptGenKey]
Zərərverici biraz sonra görəcəyiniz bəzi de-şifrələmə əməliyyatları üçün öz daxilində daşıdığı RSA açarı (private key) kriptoqrafik xidmət təminatçısına (CSP) -yə köçürür. Ilk olaraq “CryptAcquireContextA” ilə konteyner yaradır.
Daha sözü gedən gizli açarı CSP-yə köçürür. Not: Burada "CryptImportKey" funksiyası birbaşa çağrılmır. Yuxarıda qeyd etdiyimiz kimi funksiya adreslərini köçürdüyü adreslər üzərindən edir.
Gizli açarın olduğu məlumat BLOBHEADER başlığı.
typedef struct _PUBLICKEYSTRUC {
BYTE bType;
BYTE bVersion;
WORD reserved;
ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;
Burada bType = 07 (PRIVATEKEYBLOB)
bVersion = 2 (KEYBLOB formatı)
aiKeyAlg = (CALG_RSA_KEYX)
Bundan sonra GlobalAlloc funksiyası ilə 2 ədəd 0x100000 (1048576) həcmində yaddaş ərazisi yaradır.
Əsas şifrələyici modulun (dll kitabxana) deşifrə edilməsi və işə salınması
Əsas şifrələyici modul XIA resurs bölməsində t.wnry faylınin içərisidə şifrələnmiş formada saxlanılır.
Zərərverici sözü gedən şifrəli məlumatı açmaq üçün decrypt_base_mod adını təyin etdiyimiz funksiyanı çağırır.
İlk olaraq sözü gedən fayl içərisindən ilk 8 baytlıq məlumatını (magic) oxuyur və “WANACRY!” ilə qarşılaşdırır.
Bundan sonra fayldan 4 baytlıq məlumat oxuyur. Buradan əldə etdiyi məlumat əsasında (0x100 – 256 bayt) yeniden fayldan 256 baytlıq məlumat daha oxuyur.
Növbəti əməliyyat olaraq "CryptDecrypt" funksiyası çağrılır və 256 baytlıq məlumatı yuxarıda əldə etdiyi RSA açar ilə deşifrə edir. 256 baytlıq məlumat daxil edilməsinə baxmayaraq deşifrə edilən məlumat uzunluğu 0x10 baytdır.
Burada deşifrə edilən məlumat eyni zamanda şifrəli halda “t.wnry” faylı içərisində saxlanılan əsas şifrələyici modulu deşifrə etmək üçün istifadə ediləcək AES-128 (CBC modu) açarıdır. Bundan sonra zərərverici şifrəli modulu məlumatını (65536 bayt) oxuyur əldə edilən AES açarı ilə modul deşifrə edilir.
Kitabxana 6 ədəd funksiyanı import edir. Bundan əlavə olaraq 1 ədəd “TaskStart” adından funksiya ixrac edir. Məhz bu sistemdə olan faylların şifrələməsini həyata keçirəcək olan funksiyadır.
WannaCrypt əsas şifrələyici modulu deşifrə etdikdən sonra modulu yaddaş yükləmək üçün LoadLibrary funksiyasından istifadə etmir. Bunun əvəzinə modulu bir başa yaddaşdan işə salır. Bu əməliyyat üçün ilk olaraq deşifrə edilən modulu yeni bir adresə köçürür.
Daha sonra xəritələmə əməliyyatı üçün bəzi sazlamaları etdikdən sonra ilkin başlanğıc üçün “DllMain” funksiyasını çağırır.
Sazlamalar tamamlandıqdan sonra yeni yaradılan və əsas zərərverici modulun olduğu yaddaş ərazisində yerləşən PE formatını təhlil edərək buradan kitabxana tərəfindən ixrac edilən “TaskStart" funksiyasının adresini əldə edir və sözü gedən funksiyanı (əsas şifrələyici) çağırır.
TaskStart
İxrac edilən funksiya ilk olaraq ƏS mutant obyektindən istifadə edərək sistemdə 2-ci dəfə işə salınmadığından əmin olur. Bunun üçün “MsWinZonesCacheCounterMutexA” adında mutant obyekt yaratmağa cəhd edir. Əgər sözü gedən obyekt öncədən yaradılıbsa bu zərərvericinin artıq sistemdə fəaliyyət göstərdiyinə işarədir və 2-ci dəfə işə düşmür (fəaliyyətini sonlandırır). Yoxdursa obyekt yaradılır.
Daha sonra əsas nüsxə-də olduğu kimi yenidən cari qovluğu əsas qovluq edir (SetCurrentDirectoryW). Növbəti əməliyyat olaraq “SYSTEM” istifadəçisi adından işə salınıb-salınmadığını yoxlayır. Bu əməliyyat zəərvericinin şəbəkə ilə yayılma mexanizmi üçün istifadə edilir və məqalədə buna yer ayrılmayıb. Ətraflı məlumat üçün istinadlar bölməsinə baxın.
Bundan sonra əsas nüsxədə olduğu kimi istifadə etdiyi əsas sistem funksiyalarını statik analizdən yayınmaq üçün başqa adreslərə köçürür.
Əməliyyat aşağıdakı kitabxana və funksiyalar üzərində aparılır.
kernel32: [CreateFileW, WriteFileW, ReadFile, MoveFileW, MovieFileExW, DeleteFileW, CloseHandle]
advapi32: [CryptAcquireContextA, CryptImportKey, CryptDestroyKey, CryptEncrypt, CryptDecrypt, CryptGenKey]
Açar cütlərinin yaradılması
Kritik məlumatların saxlanılacağı (publik, private key pair və s.) fayl adları generasiya edilir.
Fayl adları:
- res
- pky (Public açar)
- eky (Şifrələnmiş şəxsi açar (Private))
Zərərverici ilk olaraq cari qovluqda *.PKY faylının olub-olmadığını test edir.
Sözü gedən faylın mövcud olmadığını gördükdən sonra zərərverici ilə birlikdə gələn (embedded) gələn 276 baytlıq açar CryptImportKey funksiya ilə provayderə import edir.
Açar import edildikdən sonra zərərverici əsas məqsədlər üçün istifadə edəcəyi açar cütünü generasiya edir.
ALG_ID = (açar uzunlugu << 16) | CRYPT_EXPORTABLE
0x80000001 = (2048 << 16) | CRYPT_EXPORTABLE. Zərərverici 2048 bitlik açar yaradır. Bundan sonra ilk olaraq PUBLIC açarı CryptExportKey funksiyası ilə ixrac edir. İxrac edilən public açar 00000000.pky faylına olduğu şəkildə yazılır.
Daha sonra generasiya edilən açar cütündən private açar daxildən import edilən public açar ilə şifrələnir və 00000000.eky faylına yazılır.
Zərərverici generasiya edilən açar cütü ilə əməliyyatları bitirdikdən sonra bu dəfə yenidən problem olub-olmadığını yoxlamaq üçün 000000000.pky faylında olan public açarı CryptImportKey ilə import edir. Daha sonra provayder üzərində bütün əməliyyatlar buraxılır və şifrələmə əməliyyatlarına başlayır.
Hədəf faylın şifrələnməsi
Zərərvericinin məqalə üçün hazırlanmış USB sürücüdə olan dcy.txt faylını necə şifrələdiyinə baxaq. Zərərverici sistemə yeni daxil ediləcək disklərdə olan faylları şifrələmək üçün yeni axın yaradır. Əsas axın zamanı isə sistemdə olan fayllar şifrələnir. Şifrələmə əməliyyatı tamamlandıqdan sonra (əsas axın üçün) “cmd.exe /c vssadmin delete shadows /all /quiet” əmri ilə faylların geri qaytarılma imkanlarını yox edir.
Yeni yaradılan (daxil edilən yeni sürücülər üçün) diskləri aşkar etmək üçün yeni axın içərisində while loop içərisində GetLogicalDrives funksiyası-nı istifadə edir.
Əgər yeni disk daxil edilərsə bu zaman növbəti axını (sub_10005680) CreateThread əmri ilə işə salır.
sub_10005680
Funksiya içərisində zərərverici ilk olaraq 2 ədəd public açar üçün yeni provayder yaradır. Bunlardan biri 00000000.pky faylı içərisində saxlanılan public açar, digəri isə kitxabana daxilində olan basqa bir public açar (bu açar bir öncəki daxildə saxlanılan açar ilə fərqlidir).
Açarları import etdikdən sonra hədəf disk haqqında bəzi məlumatları əldə edir. İlk olaraq hədəf sürücüdə boş yer olduğudan əmin olur. Bundan sonra sürücü tipini 5 ilə qarşılaşdırır. Əgər sürücü tipi 5 (DRIVE_CDROM) olarsa şifrələmə əməliyyatı icra edilmir.
Bu testlərdən sonra sub_100027F0 funksiyası çağrılır. Disk içərisində “~SD” adında müvəqqəti fayl yaradır daha sonra bu faylı silir. Əmin olmamaqla birlikdə diskə (və ya hər hansı alt qovluğa) məlumat yazma imtiyazının olub olmadığını test etmək üçün etdiyni düşünürük. Əməliyyat uğurla icra edildikdən sonra disk içərisində və alt qovluqlarında olan faylların siyahısı götürür. Find*FileW. Burada daha bir test edrərək siyahı alınan qovluq adlarını aşağıdakı qovluq adları ilə qarşılaşdırır. Aşağıda göstərilən qovluqlara toxunmur!
Bu şəkilin yerinə table istifadə et
Əgər siyahıya alm zamanı fayl ilə qarşılaşarsa oxşar şəkildə fayl adını (“@Please_Read_Me@.txt”, “@WanaDecryptor@.exe.lnk”, “@WanaDecyptor@.bmp”) ilə qarşılaşdırır və əgər nəticə müsbətdirsə bu fayllar siyahəya alınmır.
Bundan əlavə olaraq fayl uzantısını (bizim halda *.txt), (*.exe, *.dll və *.WNCRY) ilə qarşılaşdırır nəticə müsbətdirsə toxunmur. Bundan sonra şifrələnməli olan fayl uzantıları ilə qarşılaşdırır. Əgər bu siyahıda uzantı mövcuddursa faylı şifrələcək faylların siyahısına göndərir. Bu uzantıılardan bəziləri:
Bundan sonra zərərverici “@Please_Read_Me@.txt” və” @WanaDecryptor@.exe” fayllarını diskə kopyalayır.
Bu əməliyyatlarıda bitidikdən sonra siyahıdan faylları götürür və şifrələməyə başlayır. İlk olaraq bizim hədəf diskə yerləşdirdiyimiz hədəf faylımız (decoy) dcy.txt üzərində. Öncədən şifrələnmiş fayl olub olmadığını yoxlmaaq üçün GetFileAttributes funksiyası ilə dcy.txt.WNCRY adında faylın olub olmadığını yoxlayır. Yoxdursa “sub_10001960” çağrılır və şifrələmə əməliyyatına başlayır. Hədəf fayla aid vaxt damğalarını kimi məlumatları götürür. Bunları yeni yaradılacaq şifrələnmiş faylda olduğu kimi saxlamaq üçün istifadə edir. Daha sonra hədəf fayldan 8 baytlıq məlumat oxuyur və “WANACRY!” (WannaCry imzası) ilə qarşılaşdırır. İmza olmadığı üçün SetFilePointer ilə faylın başına qayıdır və "dcy.txt.WNCRYT" faylını yaradır. Bu fayl içərisində şifrələnmiş məlumat saxlanılacaq. Orjinal fayl isə silinəcək. Yeni faylı yaratdıqdan sonra orijnal məlumatı (mrl.cert.gov.az) şifrələmək üçün "CryptGenRandom" funksiyasının köməyi ilə 0x10 (16) baytlıq yeni açar generasiya edir. Bu açar məlumatı şifrələyəcək AES-128 (IV – 0) üçün açardır. Şifrələcək hər bir fayl üçün yeni açar generasiya edilir.
Yeni yaradılan 16 baytlıq açar:
Generasiya edilən public açar (00000000.pky) ilə şifrələnir. Daha sonra yeni yaradılan fayla (dcy.txt.WNCRYT) kritik məlumatlar yazılır. Bu məlumatlar deşifrəlmə zamanı istifadə ediləcək strukturdur. Aşağıdakı məlumatlar yazılır:
- “WANACRY!” imzası
- Açar uzunluğu (0x100 – 256)
- Şifrələnmiş açar (0x100 həcmində)
- 4 baytlıq məlumat (0x4) naməlum
- 8 bayt həcmində (dcy.txt faylında saxlanılan açıq məlumatın (mrl.cert.gov.az) həcmi (0xF – 15 bayt)
Bundan sonra AES (128) ilə məlumat (“mrl.cert.gov.az”) 0x10006940 funksiyası ilə şifrələnir və fayla yazılır.
Son olaraq MoveFileW funksiya ilə şifrələnmiş fayl yeni ad ilə əvəzlənir.
dcy.txt.WNCRYT-> dcy.txt.WNCRY və orijinal fayla (dcy.txt) həcmi qədər random baytlar yazılaraq (silinən faylı geri qaytararkən açıq məlumatın qaytarılmasının qarşısını almaq üçün (wiping)) sistemdən silinir.
Şifrələnmiş fayl:
Burada hansı məlumatlar hansı ardıcıllıqla saxlanıldığı bildiyimiz üçün şifrəli məlumatı açmağa cəhd edək.
Şifrələnmiş məlumat: EA 34 80 3C 05 3C 9F 93 0F FD 24 F3 02 90 80
Açar: 5E B1 EB 14 AE 31 CF F2 9B 59 4A BE 9B 14 EC 46
İstinadlar
[1] https://cloud.google.com/blog/topics/threat-intelligence/wannacry-malware-profile/
[2] https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids
[3] https://en.wikipedia.org/wiki/WannaCry_ransomware_attack
[4] https://scis.gov.az/az/journal/show/8