Windows Hacking Serisi #4 | Poweshell PE Enjeksiyonu

PuaL

Forum Üyesi
Katılım
19 Nisan 2020
Mesajlar
616
Tepkime puanı
0
<div><div align="center"><blockquote>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) -
Taşınabilir Yürütülebilir (Corkami) -


Araç:
Subvert-PE.ps1 -



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 Header’ları 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:
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 ¸...... @
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).


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 binary’den binary’e 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 'da Daniel Pistelli’nin analizini okuyabilirsiniz.


Kod:
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".



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:
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.

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:
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 @ Yq......
0120h: 00 B0 0D 00 00 00 40 00 00 10 00 00 00 10 00 00 .°... @ .
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 ........€.. @
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.


Görebildiğiniz üzere, birçok bölüm vurgulanmamıştır. İsteğe bağlı header’a daha kapsamlı bir genel bakış için lütfen 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 header’ları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:
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) |


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:
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 ....@..@



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:
# 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


Ç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:

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)



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:
# 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
Kod:



PE'yi Immunity’de 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.


<div style="margin:20px; margin-top:5px"> Kod:
<font color="plum"> __________________________________________
| |
| PE Header |
| |
| |
| Entry Point Offset | ---->----
| | |
|__________________________________________| |
| | |
| .......... | |
|__________________________________________| |
| | |
| First Executable Section | |
| (Probably .text) | |
| | |
| Legitimate Entry Point |
 

Nutella

Harbi Üye
Bayan Üye
Özel Üye
Katılım
2 Ocak 2021
Mesajlar
9,432
Tepkime puanı
8
Cinsiyet
  1. Bayan
Takım
Galatasaray
Paylaşım için teşekkürler.
 
İçerik sağlayıcı "paylaşım" sitelerinden biri olan Harbimekan.Com Forum, Eğlence ve Güncel Paylaşım Platformu Adresimizde 5651 Sayılı Kanun’un 8. Maddesine ve T.C.K’nın 125. Maddesine göre TÜM ÜYELERİMİZ yaptıkları paylaşımlardan sorumludur. Harbimekan.Com sitesindeki konular yada mesajlar hakkında yapılacak tüm hukuksal Şikayetler için info@harbimekan.com yada iletişim sayfası üzerinden iletişime geçilmesi halinde ilgili kanunlar ve yönetmelikler çerçevesinde en geç 3 Gün (72 Saat) içerisinde Forum yönetimi olarak tarafımızdan gereken işlemler yapılacaktır.

Bu Site, Bilim ve Sağlık Haber Ajansı Üyesidir.

Yığıntı - 8kez - kaynak mağazam - Uğur Ağdaş