Paketlenmiş dosyayı tanımak
- Paketleyici asıl kodu sıkıştırıp gizler; sen de paketlemeyi entropi, bölüm tablosu ve kısa içe aktarma listesinden tanımayı öğrenirsin.
- Statik analiz paketli dosyada yalnız açıcıyı görür, asıl kodu göremez.
- Bu derste belirtileri birlikte okumayı ve standart paketlemeyi upx -d ile açmayı öğrenirsin.
Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +50 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.
Paketleme basit bir fikirdir. Asıl kod sıkıştırılır ya da şifrelenir ve bir veri bloğuna konur. Dosyanın başına küçük bir açıcı yerleştirilir.
Program çalışınca açıcı kodu belleğe açar ve akışı ona devreder. Sonuç şudur: statik analiz yalnız açıcıyı görür, asıl kodu göremez.
Amaç her zaman kötü değildir; boyut küçültmek, kodun kopyalanmasını zorlaştırmak ve lisans denetimini gizlemek meşru nedenlerdir. Yine de paketleme analizi zorlaştırdığı için zararlı yazılımda çok sık görünür. Bu derste paketlemeyi üç belirtiden tanırsın.
Paketlemenin bir amacı da tespitten kaçmaktır. Modülün ilk dersinde gördüğün gibi bir dosyanın kimliği SHA-256 özetiyle sabitlenir ve engelleme listeleri bu özetlere dayanır.
Aynı zararlı kodu farklı bir anahtarla yeniden paketlemek, dosyanın her baytını değiştirir ve özeti tümden başkalaştırır. Böylece eski özete göre engellenen bir örnek, yeni paketiyle listelerde hiç görünmez; içerik aynı kalır ama imza kaçar. Bu yüzden savunma yalnız özet eşleşmesine değil, davranışa ve paketleme belirtilerine de bakar, çünkü yüzlerce yeni özet üretmek saldırgan için kolaydır.
Birinci belirti: entropi
İlk belirti entropidir. Entropi bayt dağılımının düzensizliğini ölçer ve sıfır ile sekiz arasında bir değer alır. Düzenli, tekrar eden veri düşük entropi verir. Sıkıştırılmış ya da şifreli veri ise neredeyse rastgele görünür ve yüksek entropi verir.
Sıradan derlenmiş kod beş ile altı bandında gezer. Sıkıştırılmış bir bölüm yedi buçuğun üstüne çıkar. Bu yüzden yüksek entropi, bakılacak yeri gösteren ilk işarettir.
Entropiyi dosyanın tamamına değil, bölüm bölüm ölçersin. Paketli kod genelde tek bir bölümde toplanır; geri kalan bölümler düz kalır. Dosyanın ortalamasına bakarsan bu tek yüksek bölüm kaybolur.
Araçlar her bölüm için ayrı bir değer üretir; sen de o listeye bakar, hangi bölümün sıçradığını görürsün. Yüksek entropi tek başına suç değildir: gömülü bir resim ya da sıkıştırılmış bir kaynak da aynı değeri verebilir. Bu yüzden entropiyi diğer belirtilerle birlikte okursun.
En sık karşılaşacağın paketleyici UPX'tir. Adı Ultimate Packer for eXecutables ifadesinden gelir ve açık kaynaktır. Asıl işi dosyayı küçültmektir, bu yüzden meşru yazılımda da bolca görünür. Zararlı yazılım yazarları da onu sever, çünkü bedava, hızlı ve çok platformludur.
UPX'in bir kolaylığı var: paketlediği dosyayı aynı araçla geri açabilirsin. İşte bu yüzden saldırganlar çoğu zaman UPX çıktısını olduğu gibi bırakmaz; başlığı elle bozar ya da üstüne ikinci bir katman ekler, böylece kolay açmayı engeller. Bir dosyada UPX izi görmek seni rahatlatmamalı; yalnız hangi aileyle uğraştığını söyler.
$ r2 -q -c 'iS entropy' ornek.exe .text vsize 0xe000 perm r-x entropy 6.39 .rdata vsize 0x5000 perm r-- entropy 5.51 .data vsize 0x1000 perm rw- entropy 0.29 ; aynı dosya paketlendikten sonra: UPX1 vsize 0x9000 perm rwx entropy 7.90
Bu iki tabloyu karşılaştır. Üstteki normal dosyada .text bölümü 6.39, .rdata 5.51, .data ise 0.29 entropi taşıyor; hepsi beklenen bandda.
Alttaki paketli sürümde kod artık UPX1 adlı tek bir bölümde ve entropisi 7.90, yani neredeyse en yüksek değer. Bu sıçrama tek başına kanıt değil ama çok güçlü bir işaret: o bölümün içi sıkıştırılmış ya da şifreli. Bakacağın yer bellidir.
Etkinlik 1 / 6
Sıkıştırılmış ya da şifreli bölümlerde entropi değeri kabaca kaça yaklaşır? (0 ile 8 arası)
Tahminini kaydır, sonra gönder.
İkinci belirti: bölüm tablosu
İkinci belirti bölüm tablosudur. Her bölümün bir sanal boyutu, bir ham boyutu ve bir izin kümesi vardır. Sanal boyut, bölümün bellekte kaplayacağı yeri; ham boyut, diskte kapladığı yeri gösterir.
Normal bir bölümde bu iki değer birbirine yakındır. Paketli dosyada ise sanal boyutu büyük, ham boyutu sıfıra yakın bir bölüm görürsün: o alan diskte boştur, çalışma anında açıcı onu doldurur. Hem yazılabilir hem yürütülebilir izin de aynı yöne işaret eder.
$ r2 -q -c 'iS' paketli.exe UPX0 vsize 0x11000 raw 0x0 perm rwx UPX1 vsize 0x9000 raw 0x8c00 perm rwx UPX2 vsize 0x1000 raw 0x400 perm rw-
Bu tabloyu oku. UPX0 bölümünün sanal boyutu 0x11000 ama ham boyutu sıfır; yani diskte hiç yer kaplamıyor, bellekte ise büyük bir alan ayrılıyor. Bu alan açılma anında dolacak.
İzin kümesi hem yazma hem yürütme veriyor; sağlıklı derleyici çıktısında bu birleşim pek görülmez, çünkü kod normalde yazılamaz. UPX0 ile UPX1 adları da açık ipucu: bu dosya UPX ile paketlenmiş. Üç işaret, boş ham boyut, yazma artı yürütme izni ve paketleyici adı, kararı neredeyse tek başına verdirir.
Giriş noktasının konumu dördüncü bir ipucu verir. Giriş noktası, yükleyicinin dosyayı belleğe aldıktan sonra ilk atladığı adrestir. Normal bir derleyici çıktısında bu adres kod bölümünün, yani .text içinin bir yerini gösterir. Paketli dosyada ise giriş noktası açıcının bulunduğu bölümü, çoğu zaman sonlara eklenmiş bir bölümü gösterir; çünkü ilk çalışması gereken şey açıcıdır, asıl kod değil.
Giriş noktasının hangi bölümün adres aralığına düştüğüne bakarsın: aralığı bulmak için bölümün başlangıç adresinden başlar, sanal boyutu kadar ilerlersin. Giriş noktası kod bölümünün dışına düşüyorsa, bu paketlemenin güçlü bir işaretidir.
Etkinlik 2 / 6
Bölüm tablosunda paketlemeye işaret eden satırı bul.
Açmak: upx -d
Üçüncü belirti içe aktarma listesidir. Paketli dosyada bu liste birkaç satıra iner; çoğu zaman yalnız LoadLibraryA, GetProcAddress ve bellek ayıran bir çağrı kalır. Açıcı asıl tabloyu bellekte kendisi kurar, bu yüzden diskteki tablo neredeyse boştur.
Standart UPX ile paketlenmiş bir dosyayı açmak kolaydır: aracın kendi açma bayrağı orijinal ikiliyi geri verir. Açma yalnızca standart UPX için çalışır; değiştirilmiş başlıkta araç hata verir.
$ cp paketli.exe acilmis.exe
$ upx -d acilmis.exe
74240 <- 37376 50.34% win64/pe acilmis.exe
Unpacked 1 file.
$ rabin2 -i paketli.exe | wc -l # paketliyken: 4 çağrı
$ rabin2 -i acilmis.exe | wc -l # açıldıktan sonra: 40+ çağrıBu çıktıyı oku. Önce paketli dosyanın bir kopyasını aldın, sonra kopyayı açtın; dosya 37376 bayttan eski 74240 baytına döndü ve araç tek dosyanın açıldığını bildirdi.
Alttaki iki komut açmanın işe yaradığını doğrular: paketliyken içe aktarma listesinde yalnız dört çağrı vardı, açıldıktan sonra kırktan fazla çağrı göründü. Aynı doğrulamayı dizelerle de yaparsın: paketli dosyada bir avuç dize varken açılmış dosyada yüzlerce anlamlı dize belirir. Üç soruya evet diyorsan açma doğrudur: içe aktarma zenginleşti mi, dizeler anlamlandı mı, entropi düştü mü.
Etkinlik 3 / 6
UPX ile paketlenmiş ornek.exe dosyasını aç.
Belirtileri birlikte okumak
Hiçbir belirti tek başına karar verdirmez. Yüksek entropi gömülü bir resimden gelebilir. Kısa içe aktarma listesi küçük ve sade bir araçta da görülebilir.
Yazma artı yürütme izni bazı meşru çalışma zamanlarında da olur. Karar, belirtilerin bir araya gelmesiyle verilir: yüksek entropili bir bölüm, sanal boyutu büyük ham boyutu sıfır bir bölüm ve birkaç satıra inmiş bir içe aktarma listesi bir aradaysa dosya paketlidir. Tek işarete bakan analist hem yanlış alarm üretir hem gerçek paketlemeyi kaçırır.
Bölüm adları da imza veritabanıyla okunur. UPX0 ve UPX1 açık ad verir ama birçok paketleyici rastgele adlar kullanır. Detect It Easy gibi araçlar dosyayı bilinen imzalarla karşılaştırır ve hangi derleyici ya da paketleyici ile üretildiğini tahmin eder.
Araç paketi kendisi açmaz; yalnız adını söyler ve bu bir ipucudur, kesin hüküm değil. Kaynak bölümüne de bakarsın: paketli dosyaların ikonu ve sürüm bilgisi çoğu zaman olduğu gibi kalır. Sürümdeki şirket adı ile dosyanın davranışı çelişirse bu tek başına bir bulgudur.
Etkinlik 4 / 6
Her belirtiyi paketli ya da paketsiz kovasına koy.
Önce bir seçeneğe, sonra aşağıdaki uygun kutuya bas. İstersen seçeneği kutuya sürükleyip bırak. Yerini değiştirmek için aynı işlemi tekrarla.
0/5 seçenek yerleşti.
Zorlu durumlar: elle açma
Standart yol kapalıysa elle açma gerekir. Yazarlar çoğu zaman başlıkları bozar ve aracın kısa yolunu kapatır. Yöntem şudur: dosyayı bir hata ayıklayıcıda başlatırsın ve açıcının işini bitirmesini beklersin.
Açıcı asıl kodu belleğe yazar ve akışı ona devreder; akış orijinal giriş noktasına atladığı an, kod artık bellekte açık demektir. O anda süreç belleğinin dökümünü alırsın. İş burada bitmez: bellekten alınan döküm çoğu zaman bozuk bir içe aktarma tablosu taşır ve tabloyu yeniden kurmadan araçlar dosyayı düzgün çözemez.
İçe aktarma tablosunu onarmak için ayrı araçlar vardır. Scylla ve ImpREC gibi araçlar, çalışan süreci tarar, hangi adresin hangi kütüphane yordamına denk geldiğini bulur ve döküme sağlam bir tablo yeniden yazar. Bu adımdan sonra dosyayı Ghidra ya da radare2 düzgün açar: içe aktarma listesi anlamlı adlarla dolar, dizeler okunur hale gelir ve giriş noktası artık asıl kodu gösterir.
Elle açmanın sırası bu yüzden hep aynıdır: doğru anı bekle, dökümü al, giriş noktasını düzelt, tabloyu yeniden kur. Dördü tamamlanınca elinde paketsiz, okunabilir bir ikili olur.
Koruyucular paketleyicilerden daha serttir. Sanal makine tabanlı koruyucular kodu kendi ürettikleri bir komut kümesine çevirir; o zaman iş, önce o komut kümesini çözmeye döner ve analiz günler sürebilir. Bütün bu işler yalıtılmış laboratuvarda yapılır, çünkü elle açma örneği gerçekten çalıştırmayı gerektirir. Yine de kod sonunda bellekte açılmak zorundadır; sabırla doğru anı beklemek ve o anda döküm almak, en karmaşık paketleyiciyi bile aşar.
Derinleş:Entropi neden tek başına yanıltır
Entropi hızlı ve ucuz bir ölçüdür, bu yüzden otomatik tarayıcılar ona çok güvenir. Ama yüksek entropi yalnız paketlemeden gelmez. Bir yürütülebilirin içine gömülü bir JPEG ya da PNG resmi, bir ZIP arşivi, bir TLS sertifikası ya da sıkıştırılmış bir yapılandırma bloğu da bölüm entropisini yedi buçuğun üstüne çıkarır. Bunların hiçbiri paketleme değildir.
Ters yönden de yanılır: zayıf bir XOR ile şifrelenmiş kod, anahtar kısa ve tekrarlıysa entropiyi fazla yükseltmez ve ölçü bu gizlemeyi kaçırır. Doğru yaklaşım entropiyi bir tetikleyici saymaktır: yüksek değer gördüğün yere yakından bakarsın, ama kararı bölüm tablosu, giriş noktasının konumu ve içe aktarma listesiyle birlikte verirsin.
Etkinlik 5 / 6
Detect It Easy (DIE) aracı ne yapar?
Etkinlik 6 / 6
Doğru mu, yanlış mı?
Paketleme tek başına dosyanın zararlı olduğunu kanıtlar.
Okumayı istediğin sırayla sürdürebilirsin. Ders, bütün etkinlikleri cevapladığında tamamlanır.