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
SYSTEM\CurrentControlSet\Services\%s\Parameters
svchost.exe -k netsvcs
Brower
MyStubPath
\Parameters
SYSTEM\CurrentControlSet\Services\%s
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost
%%SystemRoot%%\System32\svchost.exe -k "%s"
…..
RTHDVCPL
RTHDVCPL.DLL
%USERPROFILE%\
SOFTWARE\Microsoft\Windows\CurrentVersion\Run
rundll32.exe "%s", Launch
Sadece stringlere bakılarak zararlının kendisini sistemde kalıcı kılmak için “SOFTWARE\Microsoft\Windows\CurrentVersion\Run” 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 pushedi
.text:00401906 callesi ; IsUserAnAdminfonksiyonu çağır
.text:00401908 testeax, eaxsonuç 0 ise zero flagı set edilir
.text:0040190A jz loc_401C39zero flagı 1’se dallan
.text:00401910 callsub_4018A0
.text:00401915 testeax, 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 pusheax ; lpString1
.text:00401960 callsub_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 testeax, 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 pushoffset String2 ; "Brower"
.text:00401217 pushedx ; lpString1
.text:00401218 callds:lstrcmpiW
.text:0040121E testeax, 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 calledi ; QueryServiceConfigW
.text:004012B8 mov edx, [ebx+0Ch]
.text:004012BB pushoffset aSvchost_exeKNe ; "svchost.exe -k netsvcs"
.text:004012C0 pushedx
.text:004012C1 callds:StrStrW
Böyle bir servis bulduğunda ise “HKLM\SYSTEM\CurrentControlSet\Services\%s\Parameters” kayıt defteri anahtarını açıp( %s yerine servis adını gelecek şekilde) ServiceDLL değerini sorguluyor.
.text:00401363 pushedx ; lpData
.text:00401364 pushedi ; lpType
.text:00401365 pushedi ; lpReserved
.text:00401366 pushoffset ValueName ; "ServiceDll"
.text:0040136B pusheax ; hKey
.text:0040136C callds:RegQueryValueExW
.text:00401372 testeax, 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%\System32\appmgmts.dll" yolunu buluyor. Bu yolu “HKLM\SYSTEM\CurrentControlSet001\Services\AppMgmt\Parameters” 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 Settings\mw2\AppMgmt.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 Settings\mw2\AppMgmt.dll" dosyası oluşturuluyor. (bilgisayar adı farklılık gösterecektir.)
- Elde edilen veri AppMgmt.dll dosyasına yazılıyor.
- “HKLM\SYSTEM\CurrentControlSet001\Services\AppMgmt\Parameters” anahtarı altındaki ServiceDll değerine "C:\Documents and Settings\mw2\AppMgmt.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 pushoffset aMystubpath ; "MyStubPath"
.text:1000190B pushesi ; hKey
.text:1000190C callsub_1000174
Fonksiyon incelendiğinde stub tarafından kayıt defterinde “HKLM\SYSTEM\CurrentControlSet001\Services\AppMgmt\Parameters” anahtarı altına girilen MyStubPath değerinden stub’ın dosya sisitemindeki yerini buluyor.
.text:100017B4 push3E8h ; dwMilliseconds
.text:100017B9 callds:Sleep
.text:100017BF lea eax, [ebp+FileName]
.text:100017C5 pusheax ; lpFileName
.text:100017C6 callds:DeleteFileW
.text:100017CC testeax, 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 callds: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 pusheax ; lpVersionInformation
.text:10001955 callds: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 pusheax
.text:100019AE lea eax, [ebp+CommandLine]
.text:100019B4 pushoffset aRundll32_exeSL ; "rundll32.exe \"%s\", Launch"
.text:100019B9 pusheax ; LPWSTR
.text:100019BA calledi ; 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_1000120Efonksiyonunu çağırdığı görülmektedir.
.text:100012FE pusheax ; lpFilename
.text:100012FF pushoffset String2 ; "McpRoXy.exe"
.text:10001304 mov [ebp+var_C], esi
.text:10001307 mov [ebp+var_4], esi
.text:1000130A callsub_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 push1 ; int
.text:10001234 pushoffset Name ; "SeDebugPrivilege"
.text:10001239 rep stosd
.text:1000123B callsub_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 push0 ; th32ProcessID
.text:10001244 push2 ; dwFlags
.text:10001246 callCreateToolhelp32Snapshot
.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 pushesi
.text:1000125E pushecx ; lppe
.text:1000125F pusheax ; hSnapshot
.text:10001260 callProcess32FirstW
.text:10001265 mov edi, ds:CloseHandle
.text:1000126B testeax, 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 pusheax ; lpString1
.text:1000127F
.text:1000127F loc_1000127F: ; CODE XREF: sub_1000120E+94j
.text:1000127F callesi ; lstrcmpiW
.text:10001281 testeax, eax
.text:10001283 jz short loc_100012A4
.text:10001285 lea eax, [ebp+pe]
.text:1000128B pusheax ; lppe
.text:1000128C push[ebp+hObject] ; hSnapshot
.text:1000128F callProcess32NextW
.text:10001294 testeax, eax
.text:10001296 jz short loc_100012DF
.text:10001298 push[ebp+lpString2]
.text:1000129B lea eax, [ebp+pe.szExeFile]
.text:100012A1 pusheax
.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
0014612F8030 6C XOR BYTE PTR DS:[EAX],6C
0014613240 INC EAX
0014613341 INC ECX
0014613481F9 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
001463A46A 40 PUSH 40
001463A668 00100000 PUSH 1000
001463ABFF77 04 PUSH DWORD PTR DS:[EDI+4]
001463AE6A 00 PUSH 0
001463B0FFD0 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
001463B757 PUSH EDI
001463B8E8 84FDFFFF CALL 00146141
001463BD58 POP EAX
001463BEFFE0 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
009BD00355 PUSH EBP
009BD0048BEC MOV EBP,ESP
009BD006E8 4793FFFF CALL 009B6352
009BD00B85C0 TEST EAX,EAX
009BD00D75 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~1\mw2\LOCALS~1\Temp\{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
0014634B5F POP EDI
0014634C64:A1 30000000 MOV EAX,DWORD PTR FS:[30]
001463528B40 0C MOV EAX,DWORD PTR DS:[EAX+0C]
001463558B70 1C MOV ESI,DWORD PTR DS:[EAX+1C]
00146358AD LODS DWORD PTR DS:[ESI]
001463598B68 08 MOV EBP,DWORD PTR DS:[EAX+8]
ile başlayıp
CPU Disasm
Address Hex dump Command Comments
001463B483C7 08 ADD EDI,8
001463B757 PUSH EDI
001463B8E8 84FDFFFF CALL 00146141
001463BD58 POP EAX
001463BEFFE0 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