Quantcast
Channel: Bilgi Güvenliği AKADEMİSİ
Viewing all articles
Browse latest Browse all 331

McRat Zararlı Yazılım Analizi

$
0
0
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

Viewing all articles
Browse latest Browse all 331

Latest Images