Yazının amacı muhtemel bir zararlı analiz sürecinde statik ve dinamik analiz yöntemlerinin nasıl kullanılabileceğini McRat zararlısını analiz etme örneği üzerinde göstermektir. Analiz aşamasında kullanılabilecek farklı yaklaşımlar ve kısayollar mevcut olsa da yazı temel yöntemlere bağlı kalınarak hazırlanmıştır. Konuya yeni okuyucuların lab ortamı hazırlama(http://blog.bga.com.tr/2013/08/zararl-yazlm-analizi-icin-lab-ortam.html) ve debugger kullanımıyla(http://blog.bga.com.tr/2013/09/malware-analiz-calsmalarnda-temel.html) ilgili yazıları incelemesi faydalı olabilir.
Kullanılan Araçlar:
-
PEID v0.95
-
IDA 6.1
-
OllyDbg v2.01 (v1.1 veya Immunity Debugger da kullanılabilir.)
-
Strings v2.52 (SysInternals)
Analiz edilen örneğin md5 özeti: 4d519bf53a8217adc4c15d15f0815993
1. Adım
Örnek zararlıyı test için hazırlanmış bir windows platforma aktardıktan sonra(winxp sp3 x86 kullanılmıştır) ilk olarak PEID ile zararlının bir sıkıştırma veya paketleme işlemine tabi tutulup tutulmadığı kontrol edilir.
PEID zararlının yazıldığı dil ve hatta kullandığı derleyici hakkında tahminde bulunuyor. Herhangi bir packer, protecter yazılımı kullanılmış olsaydı PEID, imzasını tanırsa packerın adını yoksa “unknown” gibi bir uyarı çıkarıyor olurdu. Alternatif olarak RGB Packer Detector aracı da aynı amaçla kullanılabilir.
Edinilen bilgiler ışığında herhangi bir unpacking işlemine gerek kalmadan(şimdilik) zararlının statik analizine başlanabilir. SysInternals’ın Strings aracı kullanılarak zararlının okunabilir durumdaki stringleri listelenir. Komut satırından “strings mcrat.exe | more” komutu ile işlem gerçekleştirilebilir. Listelenen stringler zararlı hakkında oldukça fazla fikir verebileceği gibi yanıltıcı da olabilir bu yüzden doğrulanması gerekir. Göze çarpan bazı ilginç stringler şöyledir.
ServiceDll
SYSTEMCurrentControlSetServices%sParameters
svchost.exe -k netsvcs
Brower
MyStubPath
Parameters
SYSTEMCurrentControlSetServices%s
SOFTWAREMicrosoftWindows NTCurrentVersionSvchost
%%SystemRoot%%System32svchost.exe -k “%s”
…..
RTHDVCPL
RTHDVCPL.DLL
%USERPROFILE%
SOFTWAREMicrosoftWindowsCurrentVersionRun
rundll32.exe “%s”, Launch
Sadece stringlere bakılarak zararlının kendisini sistemde kalıcı kılmak için “SOFTWAREMicrosoftWindowsCurrentVersionRun” kayıt defteri anahtarını kullandığı veya kendisini servis olarak eklediği tahminleri yapılabilir. Ayrıca “!This program cannot be run in DOS mode.” stringinin iki kere geçmesi zararlının içinde başka bir çalıştırılabilir dosya barındırıyor olması ihtimalini de akıllara getirir.
2. Adım
Zararlı IDA ile açılır. İlk olarak Imports sekmesine göz atılması zararlının kullanmış olabileceği fonkisyonlar hakkında fikir verebilir. Alternatif olarak Dependency Walker uygulaması da bu amaçla kullanılabilir. Imports sekmesine bakıldığında dosya işlemleri, kayıt defteri işlemleri, servis işlemleri, süreç işlemleri ve hatta sistemde komut çalıştırmayı sağlayacak birçok fonksiyonun içe aktarıldığı görülmektedir. İlginç olan nokta fonksiyonlar arasında ağ aktivitesi sağlayacak bir fonksiyon bulunmamasıdır. WinAPI fonksiyonlarının işlevleri ve detayları msdn.microsoft.com adresinden öğrenilebilir.
Functions penceresinden start(main) fonksiyonu seçilerek analize başlanır. IDA graph görünümüne bakıldığında beklenmeyen bir şekilde main fonksiyonunun kayda değer hiçbir şey yapmadan koşulsuz bir dallanmayla programın çalışmasını sonlandırdığı görülmektedir. Assembly kodlarına bakıldığında dallanmadan hemen önce “int3” komutuyla bir istisna(exception) fırlatıldığı görülür.
.text:00401DB6 mov [ebp+var_4], 0
.text:00401DBD int 3 ; Trap to Debugger
.text:00401DBE jmp short loc_401DCE
Bu istisna zararlı tarafından 0x00401DC6 adresindeki handler tarafından yakalanır. Handlerın tek işlevi de zararlının esas main fonksiyonu denilebilecek sub_4018F0(IDA’nın 0x4018F0 adresindeki fonksiyona verdiği isim) fonksiyonunu çağırmak olduğu görülür. Zararlının buradaki esas amacı muhtemelen debuggerları şaşırtmaktır.
sub_4018F0 incelendiğinde ilk olarak IsUserAdmin winapi fonksiyonunu çağırıp zararlıyı çalıştıran kullanıcının yönetici yetkilerine sahip olup olmadığını kontrol ettiği görülür. İlgili kod incelendiğinde
.text:00401905 push edi
.text:00401906 call esi ; IsUserAnAdmin fonksiyonu çağır
.text:00401908 test eax, eax sonuç 0 ise zero flagı set edilir
.text:0040190A jz loc_401C39 zero flagı 1’se dallan
.text:00401910 call sub_4018A0
.text:00401915 test eax, eax
.text:00401917 jnz loc_401C39
yönetici grubundan bir kullanıcıysa sub_4018A0 fonksiyonundan çalışmaya devam edeceği görülür. Bu fonksiyon analiz edildiğinde işlevinin IsWow64Process winapi fonksiyonunu kullanarak sürecin WOW64 altında çalıştığını sorguladığı görülür. WOW64 32 bit windows uygulamalarının 64 bit sistemlerde sorunsuz çalışmasını sağlayan bir çeşit emulatördür denebilir. (http://msdn.microsoft.com/en-us/library/windows/desktop/aa384249%28v=vs.85%29.aspx) Dolayısıyla zararlı çalıştığı sistemin mimarisini(32 bit mi 64 bit mi) öğrenmiş olur. sub_4018A0 fonksiyonun C++ koduna http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx adresinden ulaşılabilir, dolayısıyla detaylı assembly analizi eklenmemiştir. (Zararlı yazılımlarda msdn gibi kaynaklardaki kodların neredeyse birebir kullanıldığını görmek doğaldır.)
Zararlının 32bit sistemde çalıştığını varsayarak analize devam edildiğinde tekrar kullanıcının yönetici olup olmadığını kontrol edip(ilginç) eğer yönetici ise şu kod bloğundan çalışmaya devam ediyor.
.text:00401927 xor esi, esi
.text:00401929 mov ecx, 7Fh
.text:0040192E xor eax, eax
.text:00401930 lea edi, [ebp+var_25A]
.text:00401936 mov [ebp+ValueName], si
.text:0040193D mov [ebp+Data], si
.text:00401944 rep stosd
.text:00401946 stosw
Buraya kadar olan satırlar ebp + 25A dan itibaren 128 byte sıfırlar.
.text:00401948 mov ecx, 1FFh
.text:0040194D xor eax, eax
.text:0040194F lea edi, [ebp+var_107A]
.text:00401955 rep stosd
.text:00401957 stosw
Buraya kadar olan satırlar ebp + 107A dan itibaren 512 byte sıfırlar.
.text:00401959 lea eax, [ebp+ValueName]
.text:0040195F push eax ; lpString1
.text:00401960 call sub_401160
Üstteki 3 satır ise 128’lik bufferı parametre olarak vererek 0x401160 daki fonksiyonu çağırır.
.text:00401965 add esp, 4
.text:00401968 test eax, eax
.text:0040196A jz loc_401ACE
sub_401160 fonksiyonu OpenSCManager ve EnumServicesStatus winapi fonksiyonlarını kullanarak sistemdeki servislerin listesini alıyor. Daha sonra bu listede “Brower” isimli servisi arıyor.
.text:00401210 mov edx, [esi]
.text:00401212 push offset String2 ; “Brower”
.text:00401217 push edx ; lpString1
.text:00401218 call ds:lstrcmpiW
.text:0040121E test eax, eax
Bu servisin bulamadığı durumda zararlı, QueryServiceConfig winapi fonksiyonunu kullanarak servis ayarlarında “svchost.exe -k netsvcs” geçen bir servis arıyor.
.text:004012B6 call edi ; QueryServiceConfigW
.text:004012B8 mov edx, [ebx+0Ch]
.text:004012BB push offset aSvchost_exeKNe ; “svchost.exe -k netsvcs”
.text:004012C0 push edx
.text:004012C1 call ds:StrStrW
Böyle bir servis bulduğunda ise “HKLMSYSTEMCurrentControlSetServices%sParameters” kayıt defteri anahtarını açıp( %s yerine servis adını gelecek şekilde) ServiceDLL değerini sorguluyor.
.text:00401363 push edx ; lpData
.text:00401364 push edi ; lpType
.text:00401365 push edi ; lpReserved
.text:00401366 push offset ValueName ; “ServiceDll”
.text:0040136B push eax ; hKey
.text:0040136C call ds:RegQueryValueExW
.text:00401372 test eax, eax
Zararlının amacının kendisini yetkili bir başka servisin altına gizlemek veya yerine geçmek olduğu tahmininde bulunabilir. (svchost.exe -k netsvc nin anlamı için http://www.softwaretipsandtricks.com/necessary_files/105-SVCHOSTEXE%20-K%20NETSVCS.html)
Devamında ise bu ServiceDLL değerini değiştirdiği, service konfigürasyonunu değiştirdiği ve hatta yeni konfigürasyonda servise SeTcbPrivilege yetkisi verdiği görülüyor. Bu servisin işletim sisteminin bir parçası olarak görüleceği anlamına gelir. Bir başka değişle bir windows sistemdeki en üst yetki olarak da tanımlanabilir. (http://technet.microsoft.com/en-us/library/bb457125.aspx)
Bu aşamadan sonra zarlının hangi servisi seçtiği, ne gibi değişiklikler yaptığı ve devamında nasıl bir yol izlediğini dinamik yöntemlerle analiz etmek daha verimli olacaktır.
3. Adım
McRat Ollydbg ile açılır. Statik analizde görülen anti-debugging hilesini atlatmak için int3 kesmesini çalıştırmadan 0x00401DC6 adresindeki exception handlerın ilk satırına sağ tık -> new origin here denilerek EIP’in değeri değiştirilir.
CPU Disasm
Address Hex dump Command Comments
00401DBD |. CC INT3
00401DBE . EB 0E JMP SHORT 00401DCE
00401DC0 /. B8 01000000 MOV EAX,1
00401DC5 . C3 RETN
00401DC6 /. 8B65 E8 MOV ESP,DWORD PTR SS:[EBP-18]
00401DC9 |. E8 22FBFFFF CALL 004018F0
Diğer bir seçenek de OllyDbg’ın “options” menüsünden “debugging->exceptions” bölümünden “INT3 breaks” kutusunu işaretlemektir. Bu sayede ollydbg int3 ile fırlatılan istisnayı görmezden gelip programın handle etmesini sağlayacaktır. İkinci seçenek programın defalarca çalıştırılması gerektiği durumlarda daha verimli olabilir.
Ardından CTRL+G kısa yoluyla açılan ekrana analiz edilmek istenen fonksiyonun başlangıcı olan 0x401160 adresi yazılıp bu adrese ulaşılır ve F2 ile bir duraknoktası konulur. Program F9 ile çalıştırıldığında bu adreste duracaktır. Test ortamında bu fonksiyon adım adım çalıştırılıp analiz edildiğinde ikinci adımda konuşulan Brower servisi bulunamıyor. Aradığı “svchost.exe -k netsvcs” çalıştırılan servislerden de ilk eşleşen “AppMgmt” servisini seçiyor. AppMgmt için kayıt defterinden ServiceDll değerini sorguladığında “%SystemRoot%System32appmgmts.dll” yolunu buluyor. Bu yolu “HKLMSYSTEMCurrentControlSet001ServicesAppMgmtParameters” anahtarı altındaki ServiceDll değerine yazıyor ve servise statik analizde bahsedilen “System” yetkisini veriyor.
Adım adım analize devam ederken 0X40145F adresindeki call çalıştırıldığında tekrar bir istisna fırlatıldığı görülür. İstisnanın kodu da ekranın sol altından görülebilir. Call incelendiğinde yine bir anti-debugging tekniği olduğu görülecektir. Detaylara girmeden bu istisnayı da görmezden gelmek için “options” penceresinden “debugging->exceptions” bölümünden Add Current butonu ile o anki istisna görmezden gelinecekler listesine eklenir. 0X40145F adresine duraknoktası konulup Ctrl+F2 ile zararlı Ollydbg’a tekrar yüklenir ve F9 ile duraknoktasına kadar gelinir.
Analize devam edip bu fonksiyondan çıkıldıktan hemen sonra “%%USERPROFILE%%AppMgmt.dll” stringi oluşturuluyor.
CPU Disasm
Address Hex dump Command Comments
0040198C |. 8D95 84F7FFFF LEA EDX,[LOCAL.543]
00401992 |. 51 PUSH ECX ; /<%s> => OFFSET LOCAL.151
00401993 |. 68 28344000 PUSH OFFSET 00403428 ; |Format = “%%USERPROFILE%%%s.dll”
00401998 |. 52 PUSH EDX ; |Buf => OFFSET LOCAL.543
00401999 |. 66:AB STOS WORD PTR ES:[EDI] ; |
0040199B |. FF15 DC204000 CALL DWORD PTR DS:[<&USER32.wsprintfW>] ; USER32.wsprintfW
ExpandEnvironmentStrings winapi fonksiyonu ile userprofile’ın adresi alınıp 0x004010C0 adresindeki fonksiyon aşağıdaki parametrelerle çağırılıyor.
CPU Disasm
Address Hex dump Command Comments
004019C4 |. 52 PUSH EDX ; |Arg4 = UNICODE “C:Documents and Settingsmw2AppMgmt.dll”
004019C5 |. 68 20344000 PUSH OFFSET 00403420 ; |Arg3 = UNICODE “BIN”
004019CA |. 6A 65 PUSH 65 ; |Arg2 = 65
004019CC |. 56 PUSH ESI ; |Arg1
004019CD |. E8 EEF6FFFF CALL 004010C0 ; 4d519bf53a8217adc4c15d15f081599.004010C0
F7 ile fonksiyonun içine girildiğinde sırasıyla şu işlemleri yaptığı görülmektedir.
-
FindResource ve LoadResource fonksiyonları ile zararlının resource olarak taşıdığı BIN tipinde bir veriye erişiliyor.
-
CreateFile ile “C:Documents and Settingsmw2AppMgmt.dll” dosyası oluşturuluyor. (bilgisayar adı farklılık gösterecektir.)
-
Elde edilen veri AppMgmt.dll dosyasına yazılıyor.
-
“HKLMSYSTEMCurrentControlSet001ServicesAppMgmtParameters” anahtarı altındaki ServiceDll değerine “C:Documents and Settingsmw2AppMgmt.dll” yolu yazılıyor.
-
Aynı şekilde MyStubPath değerine de çalıştırılan mcrat.exe’nin yolu yazılıyor.
Bu işlemlerden sonra da program sonlanıyor. Buraya kadar zararlının kendisini nasıl sistem servisi olarak eklediği daha doğrusu başka bir servisin yerine geçtiği detaylıca ele alınmıştır. Analize zararlının servis olarak çalışacak bölümü yani AppMgmt.dll dosyası üzerinden devam ederek zararlının aktiviteleri açığa çıkarılabilir.
4. Adım:
Zararlının oluşturduğu AppMgmt.dll dosyası IDA ile açılır. DllEntryPoint (dll dosyaları için main fonksiyonu) fonksiyonundan analize başlamak doğru gözükse de aslında bu dll sisteme bir servis olarak eklendiğinden ilk çalışacak fonksiyonu ServiceMain’dir. IDA’nın Exports sekmesinden veya Functions penceresinden ServiceMain seçilerek analize başlanır.
Servis başlangıç işlemlerinden sonra ilk olarak “MyStubPath” stringini parametre alan bir fonksiyon(sub_10001748) çağırmaktadır.
.text:10001906 push offset aMystubpath ; “MyStubPath”
.text:1000190B push esi ; hKey
.text:1000190C call sub_1000174
Fonksiyon incelendiğinde stub tarafından kayıt defterinde “HKLMSYSTEMCurrentControlSet001ServicesAppMgmtParameters” anahtarı altına girilen MyStubPath değerinden stub’ın dosya sisitemindeki yerini buluyor.
.text:100017B4 push 3E8h ; dwMilliseconds
.text:100017B9 call ds:Sleep
.text:100017BF lea eax, [ebp+FileName]
.text:100017C5 push eax ; lpFileName
.text:100017C6 call ds:DeleteFileW
.text:100017CC test eax, eax
1000 ms bekledikten sonra dosyayı(stub’ı) siliyor. Eğer dosya silme işlemi başarılıysa MyStubPath anahtarını da siliyor.
text:100017D6 loc_100017D6: ; CODE XREF: sub_10001748+86j
.text:100017D6 push [ebp+lpValueName] ; lpValueName
.text:100017D9 push [ebp+hKey] ; hKey
.text:100017DC call ds:RegDeleteValueW
Temizlik işleminden sonra GetVersionEx winapi fonksiyonu ile işletim sistemi versiyonunu alıp versiyon 6’dan büyükse Launch fonksiyonunu çağıran kod bloğuna dallanıyor.
.text:10001954 push eax ; lpVersionInformation
.text:10001955 call ds:GetVersionExW
.text:1000195B cmp [ebp+VersionInformation.dwMajorVersion], 6
.text:10001962 jb loc_10001A8F
Versiyon 6 dan büyük olması sistemin en az Windows 7 veya Server 2008 R2 olması anlamına gelir(http://en.wikipedia.org/wiki/Comparison_of_Microsoft_Windows_versions). Daha eski sistemlerde ise “rundll32.exe “%s”, Launch”(%s yerine GetModuleFileName ile alınan isim gelecek şekilde) komutu ile zararlı dllin export ettiği Launch fonksiyonunu çalıştıracak string hazırlanıyor.
text:100019A7 lea eax, [ebp+FileName]
.text:100019AD push eax
.text:100019AE lea eax, [ebp+CommandLine]
.text:100019B4 push offset aRundll32_exeSL ; “rundll32.exe “%s”, Launch”
.text:100019B9 push eax ; LPWSTR
.text:100019BA call edi ; wsprintfW
.text:100019BC add esp, 18h
Daha sonra da işlemin tamamlanmasını beklenip sonlanıyor. İki durumda da analiz Launch fonksiyonuna yönleniyor. Launch fonksiyonu incelendiğinde doğrudan sub_100012EB fonksiyonunu çağırdığı görülür. Bu fonksiyonun da ilk iş olarak “McpProXy.exe” string parametresi ile sub_1000120E fonksiyonunu çağırdığı görülmektedir.
.text:100012FE push eax ; lpFilename
.text:100012FF push offset String2 ; “McpRoXy.exe”
.text:10001304 mov [ebp+var_C], esi
.text:10001307 mov [ebp+var_4], esi
.text:1000130A call sub_1000120E
.text:1000130F pop ecx
Son çağırılan sub_1000120E fonksiyonu da “SeDebugPrivilege” stringini parametre olarak vererek sub_10001053 fonksiyonunu çağırıyor.
.text:10001232 push 1 ; int
.text:10001234 push offset Name ; “SeDebugPrivilege”
.text:10001239 rep stosd
.text:1000123B call sub_10001053
.text:10001240 pop ecx
Bu fonksiyon oldukça basit bir yapıya sahip. İncelendiğinde sürece SE_DEBUG_NAME(SeDebugPrivilege) yetkisi verdiği görülür. Bu işlem sürece diğer süreçleri debug etme ve bellek alanlarına müdahale etme hakkı verir. (http://msdn.microsoft.com/en-us/library/windows/desktop/bb530716%28v=vs.85%29.aspx)
.text:10001241 pop ecx
.text:10001242 push 0 ; th32ProcessID
.text:10001244 push 2 ; dwFlags
.text:10001246 call CreateToolhelp32Snapshot
.text:1000124B cmp eax, 0FFFFFFFFh
Hemen ardından CreateToolhelp32Snapshot fonksiyonunun dwFlags parametresine 2(TH32CS_SNAPPROCESS) değeri verilerek çağırılıyor. Yani sistemde çalışan tüm süreçlerin listesi alınıyor. Daha sonra Process32First ve Process32Next winapi fonksiyonları kullanılarak süreç listesinde gezinip ismi daha önce bu fonksiyona parametre olarak geçirilen “McpRoXy.exe” olan süreç aranıyor.
.text:10001257 lea ecx, [ebp+pe]
.text:1000125D push esi
.text:1000125E push ecx ; lppe
.text:1000125F push eax ; hSnapshot
.text:10001260 call Process32FirstW
.text:10001265 mov edi, ds:CloseHandle
.text:1000126B test eax, eax
.text:1000126D jz short loc_100012DF
.text:1000126F push [ebp+lpString2] ; lpString2
.text:10001272 mov esi, ds:lstrcmpiW
.text:10001278 lea eax, [ebp+pe.szExeFile]
.text:1000127E push eax ; lpString1
.text:1000127F
.text:1000127F loc_1000127F: ; CODE XREF: sub_1000120E+94j
.text:1000127F call esi ; lstrcmpiW
.text:10001281 test eax, eax
.text:10001283 jz short loc_100012A4
.text:10001285 lea eax, [ebp+pe]
.text:1000128B push eax ; lppe
.text:1000128C push [ebp+hObject] ; hSnapshot
.text:1000128F call Process32NextW
.text:10001294 test eax, eax
.text:10001296 jz short loc_100012DF
.text:10001298 push [ebp+lpString2]
.text:1000129B lea eax, [ebp+pe.szExeFile]
.text:100012A1 push eax
.text:100012A2 jmp short loc_1000127F
Eğer bu süreç bulunup OpenProcess ile bu sürece bir handle elde edilebilirse IDA’nın ebp+var_4 olarak tanımladığı 4. local değişken anlamındaki değeri 1 olarak atıyor.
.text:100012D5 mov [ebp+var_4], 1
Fonksiyon sonlanırken de geriye bu değişkenin değerini döndürüyor. Kısacası sub_1000120E fonksiyonu, ismi parametre olarak geçirilen sürecin sistemde çalışıp çalışmadığını kontrol ediyor. Burada bu bir cümle yerine detaylı anlatılışının sebebi, birçok zararlı tarafından kullanılan benzer kodların assembly seviyesinde nasıl okunup yorumlanabileceğini göstermektir. Alt fonksiyonlar ve genel yapı hakkında bilgi sahibi olduktan zararlının çalışma anında nasıl bir yol izlediği analiz edilerek daha çok bilgi toplanabilir.
5. Adım
AppMgmt.dll OllyDbg ile açılır. Alt+F6 kısayolu ile “Call Dll Export” penceresi açılıp Export bölümünden Launch(4. adımdaki bilgilere dayanarak) fonksiyonu seçilir. “Follow in CPU” butonu ile Launch fonksiyonunun başlangıcına gidildikten sonra “sağ tuş-> new origin here” ile EIP fonksiyonun başına set edilip debug işlemine başlanabilir.
CPU Disasm
Address Hex dump Command Comments
1000161D /$ 51 PUSH ECX
1000161E |. 8D4424 00 LEA EAX,[LOCAL.0]
10001622 |. 50 PUSH EAX ; /Arg1 => OFFSET LOCAL.0
10001623 |. E8 C3FCFFFF CALL 100012EB ; AppMgmt.100012EB
10001628 |. 85C0 TEST EAX,EAX
0x100012EB adresindeki ilk çağırılan fonksiyon analiz edildiğinde 4. adımda incelenen McpRoXy.exe sürecini arayan fonksiyon’un 0 döndürdüğü, yani sistemde bu sürecin bulunmadığı görülür, bu yüzden JNZ dallanmaz ve 0x1000142A adresindeki fonksiyon çağırılır.
CPU Disasm
Address Hex dump Command Comments
1000162A |. 59 POP ECX
1000162B |. 75 05 JNZ SHORT 10001632
1000162D |. E8 F8FDFFFF CALL 1000142A
10001632 |> 68 E8030000 /PUSH 3E8 ; /Time = 1000. ms
Bu fonksiyon da ilk iş olarak 0x10003000 adresindeki 30904 bytelık veriyi 0x75 ile xor işleminden geçirip stack’e yazıyor.
CPU Disasm
Address Hex dump Command Comments
1000143E |. BE B8780000 MOV ESI,78B8
10001443 |> 8A88 00300010 /MOV CL,BYTE PTR DS:[EAX+10003000]
10001449 |. 80F1 75 |XOR CL,75
1000144C |. 888C05 E013FF |MOV BYTE PTR SS:[EAX+EBP+FFFF13E0],CL
10001453 |. 40 |INC EAX
10001454 |. 3BC6 |CMP EAX,ESI
10001456 |.^ 7C EB JL SHORT 10001443
Çalışmaya heap’te 30904 bytelık yer ayırarak devam ediyor ayırdığı bu alana VirtualProtect fonksiyonu ile PAGE_EXECUTE_READ_WRITE yetkisi veriyor. Daha sonra da bu alandaki kodu çalıtırmak için CreateThread winapi fonksiyonunu kullanıyor.
CPU Disasm
Address Hex dump Command Comments
100014A8 |. 8D45 F8 LEA EAX,[LOCAL.2]
100014AB |. 50 PUSH EAX ; /pThreadId => OFFSET LOCAL.2
100014AC |. 53 PUSH EBX ; |CreationFlags
100014AD |. 53 PUSH EBX ; |Parameter
100014AE |. FF75 FC PUSH DWORD PTR SS:[LOCAL.1] ; |StartAddress => [LOCAL.1]
100014B1 |. 53 PUSH EBX ; |StackSize
100014B2 |. 53 PUSH EBX ; |pSecurity
100014B3 |. FF15 68200010 CALL DWORD PTR DS:[<&KERNEL32.CreateThread>] ; KERNEL32.CreateThread
CreateThread’e parametre olarak geçirilen başlangıç adresinden analize devam edildiğinde (“new origin here” özelliği veya “on execution” olayına bir donanımsal duraknoktası(hardware bp) koymak bu durumda işe yarayacaktır.) İlk olarak kendi kendini xorla çözen bir kod bloğu görülüyor. Test ortamında yeni threadin adresi 0x00146120 olarak bulunmuştur ama dinamik olarak verildiği için farklılık gösterecektir.
CPU Disasm
Address Hex dump Command Comments
0014612F 8030 6C XOR BYTE PTR DS:[EAX],6C
00146132 40 INC EAX
00146133 41 INC ECX
00146134 81F9 9C780000 CMP ECX,789C
0014613A ^ 75 F3 JNE SHORT 0014612F
Zararlı 30876 byte xorladıktan sonra çalışamaya 0x0014634B adresindeki fonksiyondan devam ediyor. Bu fonksiyon VirtualAlloc winapi fonksiyonun adresini hesaplayıp çağırarak 4096 byte(4KB) yer ayırıyor ve hemen devamındaki fonksiyon da bu alana bir takım kodlar yazıyor. Olayın akışını izlemek için şu yol izlenebilir.
VirtualAlloc’u çağıran kod bloğu(EAX ta onun adres olduğu için)
CPU Disasm
Address Hex dump Command Comments
001463A4 6A 40 PUSH 40
001463A6 68 00100000 PUSH 1000
001463AB FF77 04 PUSH DWORD PTR DS:[EDI+4]
001463AE 6A 00 PUSH 0
001463B0 FFD0 CALL EAX
“call eax” çalıştırıldıktan hemen sonra fonksiyon başarıyla çalışmışsa, EAX’ta yeni ayrılan alanın adresini içerecektir. Register bölümünden EAX’ın üzerine “sağ tuş-> follow in dump” ile hafızanın o bölümü dump ekranında görülebilir.
CPU Disasm
Address Hex dump Command Comments
001463B7 57 PUSH EDI
001463B8 E8 84FDFFFF CALL 00146141
001463BD 58 POP EAX
001463BE FFE0 JMP EAX
0x00146141’daki fonksiyon çağırıldıktan sonra da aynı ekranda boş olan alana kodların yazıldığı ve daha sonra o adrese jmp ile dallanıldığı görülür. Analize buradaki 0x008B0015 (değişkendir) fonksiyonundan devam edildiğinde içinde ws2_32 ve wininet’i de barındıran 9 adet sistem kütüphanesini(dll) yükleyen bir fonksiyonla karşılaşılmıştır.
CPU Disasm
Address Hex dump Command Comments
009BD003 55 PUSH EBP
009BD004 8BEC MOV EBP,ESP
009BD006 E8 4793FFFF CALL 009B6352
009BD00B 85C0 TEST EAX,EAX
009BD00D 75 05 JNE SHORT 009BD014
Fonksiyonda belirtilen yerlere duraknoktası koyup döngünün her adımında hangi kütüphanenin yüklendiği görülebilir.
CPU Disasm
Address Hex dump Command Comments
009B6386 /0F83 D8000000 JAE 009B6464
009B638C |837D FC 00 CMP DWORD PTR SS:[EBP-4],0
009B6390 |74 4A JE SHORT 009B63DC
009B6392 |8B4D FC MOV ECX,DWORD PTR SS:[EBP-4]
009B6395 |C1E1 04 SHL ECX,4
009B6398 |8B91 20189B00 MOV EDX,DWORD PTR DS:[ECX+9B1820]
Devamında LoadLibrary winapi fonksiyonu ile çalışma anında yüklenen kütüphaneleri kullanarak çalışma zararlı işlevlerini sürdürmektedir. Bu da zararlının işlevlerini gizlemek için kullandığı yöntemlerden birisidir.
Zararlı bu aşamadan sonra CreateThread fonksiyonunu kullanarak 4 thread daha oluşturuyor ama bunlardan bazıları aynı fonksiyonu göstermektedir. Zararlının doğrudan hafızaya decode ettiği(xor veya substraction gibi yöntemlerle) kod bloklarının tek tek analizi şu ana kadarki yöntemlerle yapılabileceğinden dolayı bunların detaylı analizine yer verilmemiştir, ipucu olabilecek
genel veriler şu şekildedir.
Test ortamında adı “C:DOCUME~1mw2LOCALS~1Temp{2D93B73E-36B9-40C4-9FD8-93C067157A8F}” olan dosyayı okumak için açıyor. (CreateFile fonksiyonunun farklı kullanımları için: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx) Daha sonra ReadFile ile içeriğini okuyup okunan veri 948 byte değilse fonksiyon sonlanıyor.
Bu dosyanın içine 110.173.55.187 adresi yazılıyor ve daha sonra bu adresin 80 portuna gönderilen HTTP POST istekleri aracılığıyla iletişim kuruluyor. Bu bölüm
CPU Disasm
Address Hex dump Command Comments
0014634B 5F POP EDI
0014634C 64:A1 30000000 MOV EAX,DWORD PTR FS:[30]
00146352 8B40 0C MOV EAX,DWORD PTR DS:[EAX+0C]
00146355 8B70 1C MOV ESI,DWORD PTR DS:[EAX+1C]
00146358 AD LODS DWORD PTR DS:[ESI]
00146359 8B68 08 MOV EBP,DWORD PTR DS:[EAX+8]
ile başlayıp
CPU Disasm
Address Hex dump Command Comments
001463B4 83C7 08 ADD EDI,8
001463B7 57 PUSH EDI
001463B8 E8 84FDFFFF CALL 00146141
001463BD 58 POP EAX
001463BE FFE0 JMP EAX
ile biten 2. decode bölümünde hafızaya yazılıyor.
Analize başlamadan önce strings, imports gibi çıktılara bakılarak veya Procmon, Process Explorer gibi araçlarla yapılan iyi tahminler çoğu zaman analiz sırasında doğru yolda ilerlemeyi kolaylaştırır fakat sağlıklı bir analiz sadece tahminlerden ibaret olmamalıdır.
Onur ALANBEL