McRat Zararlı Yazılım Analizi

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