CPacketAttack::CPacketAttack(bool,CSubTask &,CConfig &) .text 080831FE 0000015B 0000002C 00000010 R . . . B . .
CAttackCompress::CAttackCompress(bool,CSubTask &,CConfig &) .text 0808335A 00000073 0000001C 00000010 R . . . B . .
CAttackSyn::CAttackSyn(bool,CSubTask &,CConfig &) .text 080833CE 0000002F 0000000C 00000010 R . . . B . .
CAttackUdp::CAttackUdp(bool,CSubTask &,CConfig &) .text 080833FE 0000002F 0000000C 00000010 R . . . B . .
CAttackDns::CAttackDns(bool,CSubTask &,CConfig &) .text 0808342E 0000008D 0000001C 00000010 R . . . B . .
CAttackAmp::CAttackAmp(bool,CSubTask &,CConfig &) .text 080834BC 00000056 0000000C 00000010 R . . . B . .
CAttackPrx::CAttackPrx(bool,CSubTask &,CConfig &) .text 08083512 0000008D 0000001C 00000010 R . . . B . .
CAttackIcmp::CAttackIcmp(bool,CSubTask &,CConfig &) .text 080835A0 0000002F 0000000C 00000010 R . . . B . .
CTcpAttack::CTcpAttack(CSubTask &) .text 080835D0 000001A1 0000001C 00000008 R . . . B . .
Bu fonksiyonların bir çoğunun az çok ne işe yaradığı adlarına bakılarak da anlaşılabilir. İleri seviye statik analizin etkili kullanım alanının, temel statik ve dinamik analizdeki ipuçlarının detaylarını araştırmak olduğu söylenebilir. Örneğin ilginç gözüken bir stringin geçtiği fonksiyonun veya strace çıktısında dikkat çeken bir fonksiyonun detaylı analizi için bir disassembler kullanmak mantıklı olabilir.
Örnek olarak zararlının başlangıç mekanizması analiz edilmiştir. Bunun için temel dinamik analizdeki strace çıktısında karşılaştığımız fork fonksiyonu (libc içerisindeki) başlangıç ipucu kabul edilmiştir. IDA Functions penceresinden fork bulunup çift tıklanarak fonksiyona gelinir ve başlangıcına tıklanıp “x” tuşuna basılarak kod içinde çağrıldığı yerler listelenir.
Direction Type Address Text
——— —- ——- —-
Up p CSysTool::RunLinuxShell(char const*)+9 call fork
Up p CThreadKernelAtkExcutor::ProcessMain(void)+6 call fork
Up p connectback(char const*,ushort)+EB call fork
Up p CThreadShell::ProcessMain(void)+1D call fork
Down p _IO_proc_open:loc_80ACB60 call fork
Down p daemon+7 call fork
Down p __unix_grantpt:loc_80BC865 call fork
Listede kalın font ile yazılı olan metodların hepsi incelemeye değer gibi dursa da başlangıç işleyişine odaklanmak adına ismi “ProcessMain” olan iki metottan analize başlanmıştır. CThreadShell::ProcessMain metodu, IP2String isimli başka bir metodu çağırdıktan sonra fork ile yeni bir süreç oluşturup burada da herşey yolunda giderse connectback fonksiyonunu çağırmaktadır.
.text:0808840F push eax
.text:08088410 push edx
.text:08088411 call _ZN8CUtility9IP2StringEj ; CUtility::IP2String(uint)
.text:08088416 add esp, 0Ch
.text:08088419 call fork
.text:0808841E mov [ebp+pid], eax
.text:08088421 cmp [ebp+pid], 0
.text:08088425 jns short loc_8088441
………
2 call _ZNKSs5c_strEv ; std::string::c_str(void)
.text:080884B7 add esp, 10h
.text:080884BA sub esp, 8
.text:080884BD push [ebp+var_18]
.text:080884C0 push eax
.text:080884C1 call _Z11connectbackPKct ; connectback(char const*,ushort)
.text:080884C6 add esp, 10h
.text:080884C9 jmp short loc_80884DD
Metod sonunda her halükarda CManager sınıfının recycleShell metodunu çağırmaktadır. connectback fonksiyonun da temel olarak verilen IP, port değerine bağlanıp socketten gelen veriyi /bin/sh’e, bunun çıktısını da geri socket’e yönlendirdiği söylenebilir. Kısa ismiyle bir “reverse shell” işlevi görmektedir ancak analiz hedefini dağıtmamak adına detaylı analizine yer verilmemiştir.
İlk iki metodun analizinde aranan bölüm bulunamadığı için üçüncü sırada CSysTool::RunLinuxShell metodu ile analize devam edilmiştir. Metod fork işleminden sonra CSysTool::CloseResources metodunu çağırarak açtığı tüm soketleri ve dosyaları kapatıyor ve fonksiyona parametre olarak gelen değeri sistemde komut olarak çalıştırıyor.
.text:0807630F call _ZN8CSysTool14CloseResourcesEv ; CSysTool::CloseResources(void)
.text:08076314 lea ecx, [ebp+var_108]
.text:0807631A mov edx, offset _ZZN8CSysTool13RunLinuxShellEPKcE6C_1223 ; CSysTool::RunLinuxShell(char const*)::C.1223
.text:0807631F mov eax, 100h
.text:08076324 sub esp, 4
.text:08076327 push eax
.text:08076328 push edx
.text:08076329 push ecx
.text:0807632A call memcpy
.text:0807632F add esp, 10h
.text:08076332 sub esp, 8
.text:08076335 push [ebp+arg_0]
.text:08076338 lea eax, [ebp+var_108]
.text:0807633E push eax
.text:0807633F call strcpy
.text:08076344 add esp, 10h
.text:08076347 sub esp, 0Ch
.text:0807634A lea eax, [ebp+var_108]
.text:08076350 push eax
.text:08076351 call system
.text:08076356 add esp, 10h
Metodun analizinden de açıkça görüldüğü üzere bu metodu çağıran metodların analizi bizi başlangıç işlevini çözmeye daha da yaklaştıracaktır. Çapraz referanslara bakıldığında ismi başlangıç metoduna en çok benzeyen CSysTool::ReleaseAndStartGates’in analizinden devam edilmiştir.
Direction Type Address Text
——— —- ——- —-
Up p CManager::UpdateProcess(CUpdateGates &)+2BC call _ZN8CSysTool13RunLinuxShellEPKc; CSysTool::RunLinuxShell(char const*)
Down p CSysTool::DoSystemCmd(char const*)+C call _ZN8CSysTool13RunLinuxShellEPKc; CSysTool::RunLinuxShell(char const*)
Down p CSysTool::ReleaseAndStartGates(char const*)+2F call _ZN8CSysTool13RunLinuxShellEPKc; CSysTool::RunLinuxShell(char const*)
Down p CSysTool::DoUpdate(int,char **)+4FA call _ZN8CSysTool13RunLinuxShellEPKc; CSysTool::RunLinuxShell(char const*)
Metod analiz edildiğinde sadece CSysTool::ReleaseGates ve CSysTool::RunLinuxShell metodlarını aldığı parametreyi kullanarak çağırdığı görülüyor. Yine çapraz referanslardan MainBeikong fonksiyonunun analizi ile devam edilmiştir.
Direction Type Address Text
——— —- ——- —-
Up p MainBeikong(void)+1C7 call _ZN8CSysTool20ReleaseAndStartGatesEPKc; CSysTool::ReleaseAndStartGates(char const*)
Up p MainBeikong(void)+250 call _ZN8CSysTool20ReleaseAndStartGatesEPKc; CSysTool::ReleaseAndStartGates(char const*)
Down p CThreadMonGates::ProcessMain(void)+51 call _ZN8CSysTool20ReleaseAndStartGatesEPKc; CSysTool::ReleaseAndStartGates(char const*)
MainBeikong fonksiyonunun analizi ile nihayet istenilen bölüme ulaşılabilmiştir. Burada çapraz referansı oluşturan bölüm basitçe arka kapı (backdoor) dosyasının sistemdeki yolu alınıp CSysTool::ReleaseAndStartGates fonksiyonuna parametre olarak veriliyor. (Dokümanda yukarı çıkıldıkça bu fonksiyonun bu parametre ile neler yaptığı görülebilir.)
.text:0806259D push edx
.text:0806259E call _ZN8CSysTool15GetBackDoorFileEPKc ; CSysTool::GetBackDoorFile(char const*)
.text:080625A3 add esp, 0Ch
.text:080625A6 sub esp, 0Ch
.text:080625A9 lea eax, [ebp+var_10]
.text:080625AC push eax
.text:080625AD call _ZNKSs5c_strEv ; std::string::c_str(void)
.text:080625B2 add esp, 10h
.text:080625B5 sub esp, 0Ch
.text:080625B8 push eax
.text:080625B9 call _ZN8CSysTool20ReleaseAndStartGatesEPKc ; CSysTool::ReleaseAndStartGates(char const*)
.text:080625BE add esp, 10h
.text:080625C1 jmp short loc_80625DD
Fonksiyonun geneli analiz edildiğinde de çalıştırdığı süreçleri senkronize etmek amaçlı oluşturduğu kilit dosyalarının varsa eskilerini silip yenilerini oluşturuyor, kendisini sistem başlangıcına yerleştirerek kalıcılık sağlıyor. Bunu da nasıl yaptığı CUtility::SetAutoStart metodu analiz edilerek görülebilir. Kabaca /etc/init.d/ altında kendisini çalıştıracak basit bir rc dosyası oluşturduğu söylenebilir.
.text:080904D1 lea eax, [ebp+var_11]
.text:080904D4 push eax
.text:080904D5 push offset aEtcInit_d ; “/etc/init.d/”
.text:080904DA lea eax, [ebp+var_18]
.text:080904DD push eax
.text:080904DE call _ZNSsC1EPKcRKSaIcE ; std::string::string(char const*,std::allocator<char> const&)
…..
.text:080905D4 push eax
.text:080905D5 push offset aBinBashS ; “#!/bin/bashn%sn”
.text:080905DA lea eax, [ebp+addr]
.text:080905E0 push eax
.text:080905E1 call sprintf
.text:080905E6 add esp, 10h
……
.text:0809067D push [ebp+arg_0]
.text:08090680 push [ebp+arg_4]
.text:08090683 push eax
.text:08090684 push offset aEtcRcD_dSDS ; “/etc/rc%d.d/S%d%s”
.text:08090689 lea eax, [ebp+pathname]
.text:0809068F push eax
.text:08090690 call sprintf
.text:08090695 add esp, 20h
.text:08090698 sub esp, 8
.text:0809069B push 0 ; mode
.text:0809069D lea eax, [ebp+pathname]
.text:080906A3 push eax ; pathname
.text:080906A4 call access
.text:080906A9 add esp, 10h
.text:080906AC test eax, eax
.text:080906AE setz al
.text:080906B1 test al, al
.text:080906B3 jnz short loc_80906E5
.text:080906B5 lea eax, [ebp+pathname]
.text:080906BB push eax
.text:080906BC push [ebp+arg_0]
.text:080906BF push offset aLnSEtcInit_dSS ; “ln -s /etc/init.d/%s %s”
.text:080906C4 lea eax, [ebp+var_220]
.text:080906CA push eax
.text:080906CB call sprintf
.text:080906D0 add esp, 10h
.text:080906D3 sub esp, 0Ch
.text:080906D6 lea eax, [ebp+var_220]
.text:080906DC push eax
.text:080906DD call system
Bonus olarak en son çapraz referanslarda görülen CThreadMonGates::ProcessMain metodunun analizi de faydalı bilgiler verecektir.
İleri seviye statik analizde ilgili kod bölümünün ürettiği sonuçtan çok ne iş yaptığına odaklanılır. Buradan edinilen bilgiler ışığında ileri seviye dinamik analize geçilerek zararlının istenilen kod bölümlerinde çalışma anındaki davranışı gözlenir. Bu sayede bellek ve işlemci registerları üzerindeki gerçek değerler kolayca elde edilebilir. Yazı boyunca program, bilinen bir noktasından geriye doğru analiz edilerek istenilen bölüme ulaşılmıştır. Bu açıdan işleme neden tersine mühendislik dendiğini de açıklayan bir örnek olduğunu düşünüyorum.