Tango Scramble 3: Sality Analizi Bölüm 1 - Loader ve Kernel Driver Mimarisi
Scramble Terminolojisi Hakkında: Bu yazı serisinin isimlendirme mantığı (Alpha, Tango vb. Scramble kodları) hakkında detaylı bilgi almak için Scramble Konsepti yazımı okuyabilirsiniz.
Yönetici Özeti (Executive Summary)
İncelenen örnek seti, Sality ailesine ait gelişmiş bir polimorfik virüs ve botnet mimarisinin farklı katmanlarını gösteriyor. Bu ilk bölümde; ilk triage bulguları, loader davranışı, kernel driver başlatma akışı, periyodik kernel thread yapısı ve \Device\IPFILTERDRIVER üzerinden kurulan dispatcher/IOCTL ilişkisi ele alınmaktadır. User-mode ana bileşen, dosya enfeksiyonu, servis manipülasyonu, C2/P2P iletişimi ve IOC seti ikinci bölümde incelenecektir.
Analize başlamadan önce zararlı dosya arşivden çıkartılmıştır.
Binary dosyasının UPX ile paketlendiği (packed) görülmüştür.
Dosya, UPX kullanılarak kendi ortamımızda paketleyiciden çıkarılabilir; ancak içerdiği diğer arka plan süreçlerine ve bileşenlere daha hızlı/temiz erişebilmek adına unpac.me servisi kullanılmıştır.
CFF Explorer ile dosya incelendiğinde, Borland Delphi 4.0 ile derlendiğine dair izler bulunmuştur.
Dosya hakkında ek bilgi toplamak amacıyla ANY.RUN ve Hybrid Analysis raporları incelenmiştir.
analiz raporu doğrultusunda Sality ailesine ait izler tespit edilmiştir.
Sality, çalıştırılabilir dosyaları enfekte etmesi ve ağlar arasında hızla yayılmasıyla bilinen son derece gelişmiş bir kötü amaçlı yazılımdır. Başlıca amacı, spam gönderme, veri hırsızlığı ve ek kötü amaçlı yazılım indirme gibi zararlı faaliyetler için kullanılan eşler arası bir botnet oluşturmaktır. Sality, güvenlik yazılımlarını devre dışı bırakmak da dahil olmak üzere güçlü kalıcılık mekanizmalarına sahiptir ve bu da kaldırılmasını zorlaştırır. Hızlı ve sessiz yayılma yeteneği ve polimorfik yapısı, geleneksel antivirüs çözümleri tarafından tespit edilmekten kaçınmasını sağlar.
Dosya İşlemleri (File I/O)
- CreateFileW, WriteFile, ReadFile, SetFilePointer, MoveFileExW, CreateDirectoryW
Bu API seti, dosya oluşturma, kopyalama ve taşıma işlemlerinin mevcut olduğuna işaret eder. Tek başına değerlendirildiğinde bu çağrılar zararlı davranışı kanıtlamaz; ancak sonraki analiz adımlarında görülen dosya enfeksiyonu, kopyalama ve silme rutinleriyle birlikte okunduğunda anlam kazanır.
Bellek Yönetimi (Memory Operations)
- VirtualAlloc, VirtualFree, GlobalAlloc
Bu çağrılar, çalışma zamanında dinamik bellek tahsisine işaret eder. Bu bilgi tek başına shellcode yürütümü veya enjeksiyon anlamına gelmez; ancak sonraki fonksiyon analizlerinde bellek üzerinde payload hazırlama davranışıyla birlikte değerlendirildiğinde önem kazanır.
Dinamik API Çözümleme (Dynamic API Loading)
LoadLibraryA/W,GetProcAddress
Bu tespitin önemi şunlardır:
- Zararlı, IAT (Import Address Table) tablosunu gizleyerek API çağrılarını örtbas etmeyi (API hiding) amaçlamaktadır.
- Obfuscation (kod karmaşıklaştırma) uygulandığının temel göstergesidir.
Süreç Enjeksiyon Göstergeleri (Process/Injection Signals)
ReadProcessMemory,VirtualFreeEx,UnmapViewOfFile
Bu API’ler, süreç belleğiyle etkileşim kurulabildiğini düşündüren ön göstergelerdir. Ancak yalnızca import veya yüzeysel API varlığından hareketle süreç enjeksiyonu hükmüne varılmamalıdır. Bu makalede enjeksiyon değerlendirmesi, daha sonraki bölümlerde incelenen VirtualAllocEx, WriteProcessMemory ve CreateRemoteThread çağrı zincirine dayandırılmaktadır.
Süreçler Arası İletişim (IPC / Named Pipe)
CreateNamedPipeW,ConnectNamedPipe,WaitNamedPipeW,SetNamedPipeHandleState,DisconnectNamedPipe
Davranışsal Anlamı: Adlandırılmış boru (Named Pipe) desteği, süreçler arası iletişim kurulabildiğini gösterir. Ancak ek kullanım bağlamı olmadan bunun C2, yerel IPC ya da meşru uygulama mantığı için kullanıldığı netleştirilemez.
Anti-Analiz ve Stabilite (Anti-Analysis / Stability)
SetUnhandledExceptionFilter
Bu yapı, klasik bir istisna yönetimi (exception handling) tekniğidir. Bir çökme (crash) anında kontrolün işletim sistemine bırakılmasını engellemekte ve reverse engineering / hata ayıklama (debugging) sürecini zorlaştırmayı hedeflemektedir.
Kaynak Yönetimi (Resource Utilization)
FindResourceW,LoadResource,LockResource
Bu API kullanımı, örneğin gömülü veri veya kod parçalarının kaynak bölümünden çalışma anında çıkarıldığına işaret eder. Kaynak bölümündeki verinin tam niteliği ise bu çağrılar tek başına değil, ilgili çözme ve yürütme fonksiyonlarıyla birlikte değerlendirildiğinde anlaşılır.
Zamanlama ve İş Parçacığı Kontrolü (Thread / Timing)
- Sleep, GetTickCount
Bu çağrılar zamanlama kontrolü ve bekleme mekanizması sağlar. Anti-analysis amacı olasıdır; ancak tek başına Sleep veya GetTickCount kullanımından sandbox kaçınma sonucu çıkarılmamalıdır.
unpac.me servisine yüklenen örnek başarıyla paketleyici katmanından arındırılmıştır.
Ortaya çıkan bileşenler sırasıyla statik ve dinamik analize tabi tutulacaktır.
2cdacb5d742167599b826f899807cee2745c86d38a294c76cc4323b3ac0faeec kodlu dosya IDA ortamında analiz edildiğinde, içerikte hata ayıklayıcı (debugger) engelleme mekanizmalarının mevcut olduğu tespit edilmiştir:
incelenen örnek, 32-bit bir PE32 GUI binary’sidir. Sınırlı fakat dikkat çekici KERNEL32.dll import seti; dinamik API çözümleme (GetProcAddress, LoadLibraryA), bellek ayırma (VirtualAlloc) ve anti-debug/exception yönetimi (IsDebuggerPresent, SetUnhandledExceptionFilter) gibi özellikler içerir. Buna karşın ağ, süreç enjeksiyonu veya kalıcılık kurulumuna yönelik zengin bir işlev kümesi barındırmamaktadır. Bu nedenle örnek, ana payload’dan ziyade küçük bir stage/stub/loader benzeri bileşen olarak değerlendirilir.
Decompiler (IDA/Ghidra) üzerinden programın başlangıç (Entry) noktasına gidildiğinde, yürütmenin ___tmainCRTStartup üzerinden başladığı görülmektedir.
CRT Başlangıç (Startup) Süreci
Bu süreçte gerçekleştirilen temel işlemler şunlardır:
- Çalışma zamanı (runtime) ortamının kurulması.
- Komut satırı argümanları ve ortam değişkenlerinin (environment variables) hazırlanması.
- Pencere başlangıç durumunun alınması.
- Tüm hazırlıkların ardından asıl yürütme noktası olan
FUN_00401000(uVar2)fonksiyonuna dallanılması. - Yürütme tamamlandıktan sonra dönen değerin süreç (process) çıkış kodu olarak atanması.
C Runtime (CRT) Nedir?
CRT (C Runtime), derlenmiş bir programın yürütülebilmesi için arka planda çalışan altyapıdır.
Temel İşlevleri:
- İşletim sisteminden döner dönmez programı başlatır.
- Asıl main fonksiyonu çağrılmadan önce ortamı uygun hale getirir.
- Heap alanını, argv listesini ve ortam değişkenlerini (environment variables) kurar.
- İşlem sonlandırma (exit) prosedürlerini yürütür.
Analiz Perspektifinden Değerlendirilirse:
Yazılımın ana operasyonel noktası veya zararlı işlevi değil; derleyici tarafından eklenen “tetikleyici başlangıç motoru” (startup wrapper) rolündedir.
Analiz Akışının Temeli
İlgili bileşenin incelenme amacı:
Uygulama kontrol akışının (execution flow), bu başlangıç motorundan doğrudan gerçek zararlı yazılım koduna geçtiği aktarım noktası olmasıdır.
Yürütme Akışı (Execution Flow):
1
Entry Point -> CRT (`tmainCRTStartup`) -> Main Payload Logic (`FUN_00401000`)
Sıradaki aşamada FUN_00401000 fonksiyonu incelenmiştir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
undefined4 __fastcall FUN_00401000(int param_1)
{
uint uVar1;
char cVar2;
uint uVar3;
int iVar4;
int extraout_ECX;
undefined4 uStack_103b4;
byte abStack_103b0 [4464];
undefined1 auStack_f240 [62004];
if (DAT_0041ac51 != '\0') {
iVar4 = 0x103a3;
uStack_103b4 = abStack_103b0;
uVar3 = (uint)CONCAT11(DAT_0041ac53,(char)(~DAT_0041ac52 + DAT_0041ac53) >> 1);
do {
cVar2 = (char)uVar3;
uVar1 = uVar3 >> 8;
uVar3 = CONCAT31((int3)(uVar3 >> 8),cVar2 + '\x01');
abStack_103b0[iVar4 + -1] = *(char *)((int)&UNK_0040105d + iVar4 + 2) + cVar2 ^ (byte)uVar1;
iVar4 = iVar4 + -1;
} while (iVar4 != 0);
(*(code *)(abStack_103b0 + 0x1170))();
param_1 = extraout_ECX;
}
FUN_004021d0(param_1);
return 0;
}
Fonksiyonun Amacı ve Davranışı
Özünde bu fonksiyon:
Yığın (stack) bölgesinde şifreli durumdaki (obfuscated) zararlı yükü çalışma zamanında çözerek (decode) yürütmektedir.
Teknik İnceleme ve Akış
Yürütme Koşulları (Execution Gates)
1
if (DAT_0041ac51!='\0')
Kontrol Bayrağı (Control Byte)
Payload yalnızca
DAT_0041ac51 != '\0'koşulu sağlandığında çözümlenip yürütülmektedir.
Yığın (Stack) Tampon Bölgesi
1
byte abStack_103b0[4464];
Bu alan:
Çözümlenmiş zararlı yükün belleğe yazıldığı hedef bölgedir.
Şifre Çözme Döngüsü (Decode Loop)
1
2
3
4
do {
...
abStack_103b0[...]=*(...)+cVar2^ (byte)uVar1;
}while (...)
Bu mekanizma:
Özel bir XOR tabanlı ve aritmetik şaşırtma (obfuscation) tekniği kullanmaktadır.
Kaynak Veri Konumu
1
UNK_0040105d
İlgili hedef:
İkili dosya içerisine gömülmüş şifreli zararlı yüktür.
Önemli Yürütme Çağrısı
1
(*(code*)(abStack_103b0+0x1170))();
Çıkarım:
Stack üzerinde çözümlenen veri, belirli bir ofsette fonksiyon işaretçisi olarak çağrılmaktadır.
Çıkarım:
Çözümleme (Decode) -> Yürütme (Execute)
Değerlendirme
Bu fonksiyon:
Bellek üzerinde (in-memory) kabuk kodu yürüten bir yükleyici (loader) mekanizmasıdır.
Akış Şeması
1
Encoded Data -> Decode Loop -> Stack Buffer -> Execution Call (abStack + offset)
Analiz edilen örnek, gömülü ve obfuscation uygulanmış bir payload’ı çalışma anında çözen ve stack üzerinde oluşturduğu buffer üzerinden doğrudan fonksiyon pointer çağrısı ile çalıştıran bir in-memory loader’dır. Payload statik olarak disk üzerinde açık biçimde bulunmamakta, çalışma sırasında dinamik olarak çözülmektedir.
Yardımcı bileşenin analizi tamamlandıktan sonra, asıl zararlı modülün incelenmesine geçilmiştir.
d34b4e7472d1df3603be48d10c4a267281bc3d39ea64c424de408f0876a3035a
d34b4e7472d1df3603be48d10c4a267281bc3d39ea64c424de408f0876a3035a dosyası
Entry noktası işlevi (function) analiz edildiğinde:
Decompiler üzerinde yapılan incelemedeki bulgular:
1
2
PsCreateSystemThread(...)
ObReferenceObjectByHandle(...)
Sürücü, çekirdek modunda (kernel-mode) yeni bir iş parçacığı oluşturmaktadır.
Sürücü Başlatma İşlemleri
1
2
IoCreateDevice
IoCreateSymbolicLink
Bu bulgular klasik sürücü başlatma rutinlerine işaret eder. Esas tespit edilen yapı şöyledir:
1
2
(param_1+0x48)
(param_1+0x40)
IRP Yönlendirme
Bu:
1
DriverObject->MajorFunction[]
Bu durum, IRP (I/O Request Packet) istek yöneticisinin yapılandırıldığını gösterir.
Öne Çıkan Davranış
Şu satır:
1
for (ivar1=0; ivar1 < ... )
Bir döngü aracılığıyla MajorFunction parametre dizisi tamamen güncellenmektedir.
Davranışın Anlamı
Gelen tüm IRP çağrıları tek ve aynı IRP yöneticisine (handler) yönlendirilmektedir.
Çekirdek İş Parçacığı (Kernel Thread) Yönetimi
PsCreateSystemThread(&local_18, ...)
Sistem üzerinde yeni bir çekirdek iş parçacığı yaratılmaktadır.
Davranış Analizi
Sürücü:
Kendi zararlı süreçlerini arka planda otonom olarak (kernel dahilinde) sürdürmektedir.
Güvenlik Tespiti Perspektifi
Temel sebep:
Çekirdek modunda çalışan iş parçacıklarının Anti-Virüs / EDR çözümleri tarafından müdahalesi daha zordur.
Bileşen içerisindeki önemli fonksiyonlar incelendiğinde, öncelikle periyodik görevleri planlayan FUN_00010440 fonksiyonu öne çıkar.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void FUN_00010440(void)
{
uint local_8;
KeInitializeTimer(&DAT_00010e00);
while (DAT_00010dbc == 0) {
if ((9 < local_8) || (local_8 == 0)) {
local_8 = 0;
}
KeSetTimer(&DAT_00010e00,0xf4143e00,0xffffffff,0);
KeWaitForSingleObject(&DAT_00010e00,0,0,0,0);
if (DAT_00010dbc != 0) break;
local_8 = local_8 + 1;
}
KeCancelTimer(&DAT_00010e00);
PsTerminateSystemThread(0);
return;
}
İncelenen bu fonksiyon zararlının çekirdek mantığıyla doğrudan ilişkilidir. Tespitlere göre:
Sürücü tarafından başlatılan periyodik işçi/gözetmen iş parçacığıdır.
Bu işlem yapısı, yalnızca bir kereliğine yürütülen bir görev yerine, hedeflenen aralıklarla arka planda çalışan ve eylemleri periyodik olarak tetikleyen bir çekirdek döngüsüne (kernel loop) işaret eder.
Fonksiyonel Analiz
Yürütme (Execution) akışı doğrultusunda şu bulgulara ulaşılmıştır:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
KeInitializeTimer(&DAT_00010e00);
while (DAT_00010dbc == 0) {
if ((9 < local_8) || (local_8 == 0)) {
FUN_00010a3e(0);
FUN_00010a3e(FUN_000108f0);
local_8 = 0;
}
KeSetTimer(...);
KeWaitForSingleObject(...);
if (DAT_00010dbc != 0) {
break;
}
local_8 = local_8 + 1;
}
KeCancelTimer(...);
PsTerminateSystemThread(0);
Bunun anlamı:
1. Zamanlayıcı (Timer) Hazırlığı
KeInitializeTimer
Çekirdek (Kernel) zamanlayıcı nesnesi oluşturulmakta ve hazırlanmaktadır.
2. Sonlandırma Bayrağı (Stop Flag) Kontrolü
DAT_00010dbc == 0 değeri sağlandığı sürece döngü devam etmektedir.
Bu değişken, döngünün sürdürülüp sürdürülmeyeceğini belirleyen bir kontrol bayrağı gibi davranır. Koda bakılarak bu bayrağın tam semantiği netleştirilemese de iş parçacığının sonlandırılmasıyla ilişkili olduğu görülür.
3. Periyodik Görev Çağrıları
Döngü başlangıcında veya belirli bir sınırı aştığında:
FUN_00010a3e(0)FUN_00010a3e(FUN_000108f0)
çağrılıyor.
Bu mimari, iş parçacığının periyodik görev çağrılarını planlayan bir dispatcher/scheduler rolü üstlendiğini gösterir.
4. Bekleme/Zaman Aşımı
KeSetTimer + KeWaitForSingleObject
İşleyiş:
- Belirlenmiş süre kısıtında iş parçacığı askıya alınır (sleep).
- Süre dolduğunda döngü devam ettirilir.
5. Döngü Çıkış Prosedürü
Sonunda timer iptal edilip:
PsTerminateSystemThread(0)
çağrısı ile iş parçacığı güvenli şekilde (graceful degradation) sonlandırılmaktadır.
İş Parçacığının Sistemdeki Rolü
Bu fonksiyon:
Periyodik Baştıcı (Periodic Dispatcher) / Zamanlayıcı
Gözlemlenen işlevi:
- belirli aralıklarla yardımcı rutini çağırmak
- döngüsel çalışma mantığını sürdürmek
- kontrol bayrağı değiştiğinde iş parçacığını sonlandırmak
Analiz Çıkarımı
Analizlerin bundan sonraki ana odağı şu fonksiyon olmalıdır:
FUN_00010a3e
Zira çekirdek iş parçacığının tüm görev sevkini bu fonksiyon üzerinden gerçekleştirdiği doğrulanmıştır.
Ayrıca fonksiyon, iki farklı parametre ile (0 ve 000108f0 değerleri) çağrılmaktadır:
FUN_00010a3e(0)FUN_00010a3e(FUN_000108f0)
Bu durum, aynı rutinin en az iki farklı parametre değeriyle çağrıldığını gösterir. Ancak bu parametrelerin semantiği, yalnızca bu kod kesiti üzerinden net biçimde belirlenememektedir.
FUN_000108f0 Parametresine İlişkin Gözlem
FUN_000108f0 değeri, FUN_00010a3e fonksiyonuna iletilen alternatif parametrelerden biridir. Bu değerin alıcı bileşen tarafından fonksiyon işaretçisi, durum kodu veya başka bir veri alanı olarak kullanılıp kullanılmadığı yalnızca gönderici taraftaki kod üzerinden doğrulanamamaktadır.
Driver, PsCreateSystemThread aracılığıyla ayrı bir kernel iş parçacığı başlatmaktadır. Bu thread, bir kernel timer kullanarak döngüsel biçimde çalışmakta ve belirli aralıklarla aynı yardımcı rutini farklı parametrelerle çağırmaktadır. Bu yapı, sürücünün periyodik görev icra eden bir dispatcher mantığı taşıdığını gösterir.
Zararlının dispatcher fonksiyonu olan FUN_00010a3e adresi incelendiğinde:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int FUN_00010a3e(undefined4 param_1)
{
int iVar1;
undefined4 local_24;
int local_20;
undefined4 local_1c;
undefined1 local_18 [8];
undefined1 local_10 [8];
undefined4 local_8;
local_24 = 0;
local_20 = 0;
local_1c = 0;
local_8 = 0;
RtlInitUnicodeString(local_10,L"\\Device\\IPFILTERDRIVER",0);
iVar1 = IoGetDeviceObjectPointer(local_10,0x1f01ff,&local_20,&local_24);
if (iVar1 == 0) {
local_1c = param_1;
local_8 = IoBuildDeviceIoControlRequest(0x128058,local_24,&local_1c,4,0,0,0,0,local_18);
IofCallDriver();
if (local_20 != 0) {
}
}
return iVar1;
Bu fonksiyon:
başka bir kernel driver’a IOCTL gönderiyor
İşlem Analizi
Hedef Sürücü Bağlantısı
1
RtlInitUnicodeString(local_10,L"\\Device\\IPFILTERDRIVER");
Hedef sürücü yolu:
\Device\IPFILTERDRIVER
Cihaz Referansı Alma
1
IoGetDeviceObjectPointer(...)
Bu API çağrısı:
İşletim sistemi vasıtasıyla farklı bir kernel sürücüsüyle birleşim kurmak anlamına gelir.
IOCTL İsteği Oluşturma
1
IoBuildDeviceIoControlRequest(0x128058, ...)
IOCTL kodu:
1
0x128058
Parametre Aktarımı
1
local_1c = param_1;
Pratikte aktarılan değer:
- ya 0
- ya
FUN_000108f0
Çekirdek İletişimi
1
IofCallDriver();
İşletim (IOCTL) talebinin hedef birime iletildiğini doğrulamaktadır.
Sistem Düzeyi İletişim
Gösterilen kod, analiz edilen sürücünün \Device\IPFILTERDRIVER nesnesine bağlanıp 0x128058 kodlu bir IOCTL isteği gönderdiğini gösterir. Bu nedenle güvenle söylenebilecek husus, örneğin başka bir kernel bileşeniyle doğrudan etkileşim kurduğudur.
Bu noktada dikkat edilmesi gereken sınır şudur:
- hedef sürücünün meşru veya zararlı olduğuna bu kod kesiti tek başına karar verdirmez
- gönderilen
param_1değerinin alıcı tarafta nasıl işlendiği henüz görülmemektedir - bu nedenle alıcı sürücünün payload yürüttüğü, hook kurduğu veya rootkit işlevi gördüğü sonucuna bu aşamada varılamaz
Bu bölüm için savunulabilir özet:
- kernel thread başlatır
- periyodik çalışır
- başka bir sürücü nesnesine
IOCTLgönderir
param_1 Değerinin Rolü
İlgili analizde önem taşıyan bir diğer veri kurgusu aşağıdaki gibidir:
1
2
FUN_00010a3e(0)
FUN_00010a3e(FUN_000108f0)
Çıkarım
Bu kod kesiti üzerinden doğrulanabilen husus, param_1 alanına iki farklı değerin yazılıp IOCTL isteği içinde iletildiğidir. Ancak alıcı bileşen analiz edilmeden bu değerin fonksiyon işaretçisi, durum kodu veya başka bir kontrol verisi olduğu net biçimde söylenemez.
Dosya Karakteristiği
Bu dosya:
Windows kernel-mode driver (.sys)
Detaylandırmak gerekirse:
Doğrudan gözlenen davranış, periyodik çalışan bir kernel thread üzerinden başka bir sürücü nesnesine
IOCTLgönderen bir dispatcher/scheduler mantığıdır.
Faaliyet Analizi
Bu driver:
- Yüklenince kernel thread oluşturur (
PsCreateSystemThread) - Timer ile sürekli döngüde çalışır
- Belirli aralıklarla:
1
\Device\IPFILTERDRIVER
adresinden çağrılabilen diğer yapı hedefi ile
1
IOCTL: 0x128058
gönderir
Özetle:
Bu bileşen, gözlenen kod akışı itibarıyla periyodik
IOCTLiletimi yapan bir kernel dispatcher rolü sergilemektedir. Alıcı tarafta hangi işlevin yürütüldüğü ise bu kesitten tek başına doğrulanamamaktadır.
Mimari Rol
İlgili Sürücü (Dispatcher):
- Görev Düzenleyici (Scheduler)
- Tetikleyici / Atak İletken (Trigger)
- Süreç arası iletişim köprüsü (IPC Layer)
Analiz edilen örnek, kullanıcı modunda çalıştırılabilir bir binary değil, Windows kernel seviyesinde çalışan bir sürücüdür (.sys). Bu nedenle doğrudan çalıştırılamamaktadır. Driver’lar yalnızca işletim sistemi tarafından yüklenebilir ve başlatılabilir.
Analiz kapsamında incelenen iki yardımcı bileşenin, ana zararlı yükü doğrudan içermek yerine çok aşamalı bir saldırı zincirinin parçası olarak görev yaptığı tespit edilmiştir.
İlk bileşen, Windows kernel seviyesinde çalışan bir sürücü (.sys) olup, sistemde yüklendikten sonra
PsCreateSystemThreadaracılığıyla ayrı bir kernel thread başlatmaktadır. Bu thread, bir kernel timer kullanarak periyodik biçimde çalışmakta ve her döngüde\Device\IPFILTERDRIVERisimli başka bir sürücüye belirli bir IOCTL isteği (0x128058) göndermektedir. Bu davranış, incelenen sürücünün doğrudan zararlı işlevleri gerçekleştirmekten ziyade, başka bir kernel bileşenini tetikleyen bir scheduler/dispatcher rolü üstlendiğini gösterir.İkinci bileşen ise kullanıcı modunda çalışan bir PE32 binary olup, statik analizde sınırlı import setine rağmen dinamik API çözümleme ve bellek yönetimi fonksiyonları içermektedir. Detaylı incelemede, gömülü ve obfuscation uygulanmış bir veri bloğunu çalışma anında çözen bir döngü bulunduğu ve bu verinin stack üzerinde oluşturulan bir buffer içerisine yazıldığı görülmüştür. Ardından bu buffer içerisindeki belirli bir offset’ten fonksiyon pointer çağrısı yapılarak payload doğrudan bellek üzerinden çalıştırılmaktadır. Bu yapı, dosyanın disk üzerinde açık bir payload barındırmadığını, bunun yerine in-memory loader olarak görev yaptığını gösterir.
Her iki bileşen birlikte değerlendirildiğinde, analiz edilen örneklerin doğrudan zararlı aktivite gerçekleştiren ana payload’dan ziyade, daha karmaşık ve çok katmanlı bir saldırı mimarisinin ara bileşenleri olduğu anlaşılır. Bu mimari, payload’ın statik analizle tespit edilmesini zorlaştırmak amacıyla işlevlerin farklı katmanlara bölündüğüne işaret eder.
Ardından incelenecek diğer bileşen:
8ec28b718336a05245f2138cbcc4fea8e45f698a40bfc6fd79162adf67333e8b
Dosya dizesi (string) analizinde kalıcılık (persistence) veya veri çalma (log stealer) faaliyetlerine işaret edebilecek ifadelere rastlanmıştır.
AV bypass ya da detection için stringler:
Komuta ve kontrol (C2) bağlantısına yönelik olarak çeşitli göstergelerin (IoC) metin düzeyinde bulunduğu da tespit edilmiştir.
Bu göstergeler ikinci bölümde IOC seti içinde toplu olarak ele alınacaktır.
Bu noktadan sonraki user-mode bileşen analizi Ghidra üzerinden ilerlemekte ve ikinci bölümde ele alınmaktadır.
Detection Notu
Bu bölümde incelenen bileşenler loader, in-memory decode akışı ve kernel dispatcher/IOCTL davranışıyla sınırlıdır. IOC, MITRE ATT&CK ve YARA kuralları; user-mode ana bileşen, P2P iletişim, persistence ve AV süreç sonlandırma davranışlarıyla birlikte daha anlamlı hale geldiği için ikinci bölümde merkezi olarak verilmiştir.
Savunma ekipleri bu ilk bölümü özellikle şu triage sinyalleri için kullanmalıdır:
- UPX sonrası ortaya çıkan ara loader bileşenleri
- stack üzerinde decode edilip fonksiyon pointer ile yürütülen payload akışı
PsCreateSystemThread,KeInitializeTimer,KeWaitForSingleObjectile çalışan kernel dispatcher yapısı\Device\IPFILTERDRIVERhedefine gönderilen0x128058IOCTL isteği
Bu sinyalleri kapsayan YARA/MITRE çıktıları için devam yazısındaki Detection bölümüne bakılmalıdır: Tango Scramble 3: Sality Analizi Bölüm 2 - Enfeksiyon, C2/P2P ve Persistence.
Bölüm 2’ye Geçiş
Bu bölümde loader, kernel driver ve dispatcher mimarisi ele alındı. User-mode ana bileşen, dosya enfeksiyonu, servis manipülasyonu, UDP/P2P iletişimi ve IOC seti için devam yazısı: Tango Scramble 3: Sality Analizi Bölüm 2 - Enfeksiyon, C2/P2P ve Persistence.


















