Windows Heap Exploitation #6 | Heap Overflows 103.5

Qgenays

Katılımcı Üye
20 Haz 2020
254
3
Los Santos
Heap Overflows 103.5

Daha önce, bir yığın taşmasını kullanırken pencerelerde yığın korumalarını atlatmak için farklı teknikleri tartışmıştık.

Ancak bugün çok özel bir sürprizim var.

Bugün, başka bir yığın taşma saldırı tekniğini ele almayacağız, bunun yerine bir yığın taşması istismar tekniği kullanarak ‘çifte serbest’ bir güvenlik açığından nasıl yararlanılacağını öğreneceğiz.

Pek çok insan size çifte serbestliklerin sömürülmesinin çok zor olduğunu söylese de, sizi temin ederim ki bunların çoğu, tipik yığın taşmalarından çok daha kolay sömürülür.

Her zaman birinin bu güvenlik açıklarından nasıl yararlanılabileceğini merak ettim ve bu da beni kritik olarak değerlendirilen birkaç tavsiyeye işaret etti.

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 başlığımın bir kopyası
– 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)
– Biraz Assembly, C bilgisi ve bir hata ayıklayıcıda nasıl kazılacağı hakkında bilgi – Windows yığın yönetimi iç bileşenleri hakkında bazı bilgiler
– ZMaalesef analizim sırasında, Bağışıklık Hata Ayıklayıcı her zaman çalışmadı ve aslında birkaç kez üzerime düştü ama bizi durduramaz;)

Double free nedir?

Pek popüler olmayan owasp wiki’den alınmıştır:

“free () bir bağımsız değişken olarak aynı bellek adresiyle birden fazla çağrıldığında çift serbest hata oluşur.”

Tanımlarına ilişkin son tartışmada, güvenlik açığının aslında bir arabellek taşması olmadığı sonucuna vardım (owasp aksini söylemesine rağmen).

Bir saldırgana aynı belleği iki kez serbest bırakma yeteneği verilirse, bu durumdan öbekte sarkan bir işaretçi yığınını değiştirmek ve belirli saldırılar gerçekleştirmek için **** verilerini bozmak için bunu kullanabilir.

0x24 boyutunda olmayan bir parçanız olduğunu varsayalım.

Ayrıca, lookaside [4] için son girişi double free’den biriyle doldurduğunuzu varsayalım, o zaman ikinci free listeniz FreeList [4] ‘e düşecektir.

Bu nedenle, farklı yığın ayırıcılarda depolanan aynı işaretçilerden ikisine sahip olacaksınız.

Bir saldırganın * biraz * (aslında oldukça düşük) determinizm seviyelerine sahip olması durumunda, bu daha önce gördüğümüz çok çeşitli saldırılar sağlayabilir:

Aynı hafızayı bakış tarafına [n] iki kez serbest bırakarak bakış tarafındaki bir parçanın üzerine yazın ve bunlardan birini tahsis edin.

Sonra sarkan işaretçinin liste başlığının üzerine yazın ve bir işlev işaretçisinin üzerine yazmak için kötü amaçlı flink.

Görünüşe ve diğerine FreeList’e bir parça ayırın, böylece serbest listeye girişte flink / blink üzerine yazarsınız. Bunu yaparak şunları yapabilirsiniz:

> Flink’i kötü niyetli bir sahte yığın olarak ayarlayın ve ardından FreeList [0] ‘e yeniden eklenmesini sağlayın bölünmüş ve bir yeniden bağlantıdan sonra geri dönmüşse, kalan yığın daha önce eklenecektir sahte flink yığını ve daha sonra sahte parçaları dolduracak, malicous’u işaret etmek için yanıp sönecek flink (Brett Moore – FreeList [0] Yeniden bağlama saldırısı).

> Flink’i sahte bir parçaya ayarlayın, böylece sahte parçayı iade edersiniz (Brett Moore – FreeList [0] Arama saldırısı).

> Yanıp sönmeyi bir Bakış listesi girişine veya işlev tablosuna ayarlayın ve yanıp sönmeyi başka bir işlev işaretçisi, böylece ekleme parçasının işaret ettiği adresi kontrol eder.

Bu Lookaside [n] ‘de sahte yığınlar oluşturmanıza ve kötü amaçlı flink elde edilir (Brett Moore – FreeList [0] Saldırı ekle).

> Boyutu farklı olacak şekilde ayarlayın ve girişten ayırın (Görünüm kenarını boşalttıktan sonra) ve üzerine yazılan boyut için bit eşlemi çevirin. (Nicolas Waisman 2008).

Adresi Yığın tabanının kendisinden bir ofset olan bir öbeği doğrudan iade edin, böylece size yönetim yapılarının üzerine yazmak ve kontrolü ele almak için (Nicolas Waisman 2008) FreeList [n] üzerindeki iki parçayı serbest bırakın ve boyutun üzerine yazmak için bunlardan birini ayırın ve flink / blink değerleri (FreeList [n] girişinde yalnız bir yığın olmadığını varsayarak) ve her ikisini de ayarlayın liste giriş adresi olarak flink / yanıp söner.

Boyutu ayırın ve biti çevirecek (FreeListInUse) karşılık gelen boyut için ve bir saldırganın adres, yığın tabanının ofsetidir (Nicolas Waisman 2008

Çifte serbest güvenlik açığından yararlanma örneği

Kodu alıp dev c ++ ‘da derleyerek başlayın (not: vtable araması ve işlev çağrısı için satır içi derleme (AT&T) kullanıyorum):

Yakından bakarsanız, uygulamaya özgü işlev işaretçileri kullandığımızı ve aslında vtable’daki bir işlevin üzerine yazacağımızı fark edeceksiniz.

Yürütülebilir dosyayı bir hata ayıklayıcıda açın ve HeapCreate () (0x00401364) çağrısından hemen sonra adres üzerinde bir kesme noktası ayarlayın.

Şu komutu çalıştırmanız gerekecek:

Kod:
char *b1,*b2,*b3,*b4,*c1,*c2,*c3,*c4,*d1,*d2,*d3;
char *trigger;
long *pHeap;
int i;
DWORD function[20];
DWORD ptr1, ptr2;
 
**** callback1(){
        printf("(+) Executed application callback 1...\n");
}
 
**** callback2(){
        printf("(+) Executed application callback 2...\n");
}
 
**** callback3(){
        printf("(+) Executed application callback 3...\n");
}
 
**** callback4(){
        printf("(+) Executed application callback 4...\n");
}
 
**** create_vtable(){
        int x;
        printf("(+) Creating vtable...\n");
 
        (DWORD) function[0] = (DWORD) &callback1;
        (DWORD) function[1] = (DWORD) &callback2;
        (DWORD) function[3] = (DWORD) &callback3;
        (DWORD) function[4] = (DWORD) &callback4;
 
        for(x=5;x<20;x++){
                (DWORD) function[x] = (DWORD) &callback1;
        }
}
 
int main(int argc,char *argv[])
{
 
       pHeap = HeapCreate(0x00040000,0,0);
 
       printf("[ -------- double free -------- ]\n");
       create_vtable();
       printf("\n(+) Created vtable @ 0x%08x\n", &function);
       printf("(+) Performing vtable lookup @ 0x%08x and set to call 0x%08x\n", &function, &function[4]);
 
       ptr1 = (int)function;
 
       // vtable lookup and callback4
       __asm__("movl %0, %%ecx":"=m"(ptr1) );
       __asm__("mov 0x10(%ecx),%eax\n");
       __asm__("call *%eax");
 
      b1=HeapAlloc(pHeap, 0, 24);
      b2=HeapAlloc(pHeap, 0, 24);
      b3=HeapAlloc(pHeap, 0, 24);
      b4=HeapAlloc(pHeap, 0, 24);
 
      HeapFree(pHeap, 0, b1);
      HeapFree(pHeap, 0, b2);
      HeapFree(pHeap, 0, b3);
      HeapFree(pHeap, 0, b4); // 1st free
      HeapFree(pHeap, 0, b4); // 2nd free (double free)
 
      c1=HeapAlloc(pHeap, 0, 24);
      c2=HeapAlloc(pHeap, 0, 24);
      c3=HeapAlloc(pHeap, 0, 24);
      c4=HeapAlloc(pHeap, 0, 24);
 
      printf("(+) Chunk b4 (0x%08x) is now freed twice and is dangling..\n",&b4);
      printf("(+) Overwrite the dangling chunk pointer's flink with a function pointer..\n");
      gets(c4);
 
      d1=HeapAlloc(pHeap, 0, 24);
      d2=HeapAlloc(pHeap, 0, 24);
      d3=HeapAlloc(pHeap, 0, 24); // return our controlled lookaside chunk
 
      printf("(+) Overwrite the returned function pointer...\n");
      gets(d3); // overwrite application specific pointer and gain code execution
 
      printf("(+) Performing vtable lookup @ 0x%08x and set to call 0x%08x\n", &function, &function[3]);
 
      ptr2 = (int)function;
 
      // vtable lookup at callback3
      __asm__("movl %0, %%ecx":"=m"(ptr1) );
      __asm__("mov 0xc(%ecx),%eax\n");
      __asm__("call *%eax");
 
      HeapDestroy( pHeap );
 
      exit(1);
}


Kod:
!hidedebug ZwQueryInformationProcess

Şimdi uygulamayı çalıştırın, böylece ilk molanıza ulaşırsınız ve yığınınızın içine ayırma ve ücretsiz kullanım için bazı kancalar yerleştirebilirsiniz.

Kod:
!heaper hook <heap> -h alloc !heaper hook <heap> -h free

Tahsisleri ve bedava olanları izleyeceğiz ve ilerledikçe mantıklı olup olmadıklarını göreceğiz.

I2XRYI.jpg


Örnekte bazı kodların vurgulandığına dikkat edin. Sanal işlev arama ve çağrıdır.

Temel olarak, c ++ uygulamaları genellikle her nesne için bir vtable’a sahiptir (nesnenin bellekteki konumunda ilk dword olarak saklanır) ve bu nesnenin üye işlevlerini içerir.

Yapılan örnekte, belirli bir sürecin kontrolünü ele geçirmek için hedefleyebileceğimiz uygulamaya özel işlev işaretçileri içeren bir vtable gibi bir nesne yoktur.

Vtable’ın 0x00404080 adresinde bulunduğunu ve bazı sökme işlemlerinde bulunabileceğini unutmayın. Bu değerin ECX’e yazıldığını görebiliriz ve ardından fonksiyon çağrısı için offset + 0x10’a bir referans kullanılır.

Son olarak kod çalıştırma bu fonksiyon çağrısına aktarılır. İlerledikçe bu daha önemli hale gelecektir.

Yapılması gereken bir sonraki şey, uygulamadaki son iki HeapFree () ‘ye bir kesme noktası koymak ve 0x00404080 (vtable) ofsetini dökmektir.

Belirli bir ofsette belirli bir işlevi çağırmak için kullanılan bir dizi dword adresi göreceksiniz.

30TsaE.jpg


Bu noktada uygulamanın HeapAlloc () ve HeapFree () ‘leri çalıştırmasına ve izlemesine izin verin:

onW1WI.jpg


Bu aşamada, bakarsak [4] girişine bakarsak, 3 parça göreceğimizi ve FreeList [4] girişinin herhangi bir parça içermeyeceğini unutmayın (bu noktada hala iki HeapFree () var ).

w7YMQI.jpg


Bir HeapFree () ‘nin üzerinden geçelim, aslında yanlış bir adres olan 0x00491e88 yığınıyla doldurulmuş görünüm [4]’ ü görebiliriz.

Görünüşe yerleştirilmesi gereken şey 0x00491ef0 idi.

Şu anda, bağışıklık hata ayıklayıcısında bunun neden olduğundan emin değilim, ancak uygulamaların eylemlerini doğrulamak için başka yollarımız var ve bu engelin bizi engellemesine izin vermemeliyiz.

BwXmIT.jpg


BwXmIT.jpg



Artık 2nd HeapFree () için kırılma noktamıza ulaştığımıza göre (çifte serbestliğe neden olur) aşağıdaki argümanları görebiliriz:

sjc5Pt.jpg


Kancalar için günlük girişlerimizi görüntüleyerek neler olduğunu biraz daha doğrulayalım:

hlCCbQ.jpg


Tek yapmamız gereken, tahsis edilen yığın olarak ikiye katlanmamıza neden olan yığınımızı alana kadar, bakış tarafındaki [4] yığınları kaldırmaktır.

Lookaside [4] ‘den 4’üncü ardışık tahsisatımıza rağmen, yığın hala Lookaside [4] listesinde yer alıyor ve yığınlara sadece 0x4 bayt yazarak görünüm kenarındaki flink’i bozabiliriz, böylece dolaylı olarak bakış tarafında sahte bir yığın oluşturabiliriz .

HijyJT.jpg


Riskli bakış [4] girişine bakın:

Anv0GX.jpg


Şimdi sahip olduğumuz vtable’ı hatırlıyor musunuz?

Eğer derlemeye aşağı kaydırırsanız, çifte serbest bırakmamızdan sonra [vtable + 0xc] çağrısı göreceksiniz.

İşlev işaretçilerinin dwords (4 bayt) olduğunu biliyoruz, bu yüzden tek yapmamız gereken 3. Girişin üzerine vtable’a yazmak.

kUNke5.jpg


Burada, görünüm [4] giriş adresindeki ilk 4 baytı basitçe değiştirebiliriz (ilk öbeğe göstericiyi içerdiğinden bakın) ve EAX’i 0x00404080 + 0xc’de işlev işaretçimizi içerecek şekilde değiştirebiliriz.

EZYP3I.jpg


Buradan yürütmeye devam edersek, kod mutlu bir şekilde 0040408c’yi geçerli bir yığın adresi olarak döndürecektir.

qtM9kn.jpg


Daha sonra onu ‘shellcode’ ile doldurmamıza izin verecektir.

İlk 0x4 baytın üzerine yazarsak, işlev çağrısı yapıldığında, kontrollü işlev işaretçimizi tetikleyecek ve kod yürütmeyi kötü amaçlı tamponumuza aktaracaktır.

Ayrıca, vtable’ımızın ECX’te depolandığına dikkat edin, yığını bu konuma döndürmeyi deneyebiliriz, böylece bir dep bypass gerçekleştirebiliriz. Örneğin: mov esp, ecx; pop r32; pop r32; pop r32; pop r32; retn.

ko2599.jpg


Son Düşünceler

Açılış paragraflarında belirtildiği gibi, çift serbestlikten (determinizm düzeyine bağlı olarak) kod yürütme elde etmek için yığın taşması istismar vektörlerinden hemen hemen herhangi birini kullanabilirsiniz.

İşaretçinin hala sarkıyor olması gerçeği, bir saldırganın, sarkan parçanın tahsisi yoluyla 0x4-0x8 baytlık flink / göz kırpmanın üzerine yazmasına izin verir (daha çok, eğer bakış tarafındaki bir yığın üzerine yazıyorsa).

Bu, Windows XP sp3’ün korumalarını atlatabilecek pek çok uygulama saldırısına izin verir.

Kod yürütmeye giden en basit yolu basitçe sundum.

Bununla birlikte, bu, şüphesiz, basit bir çift serbest doğrudan bakış açısına ve sadece iki kez tahsis edilmesiyle başarılabilirdi.

Ne yazık ki, bir süre önce irc’de olduğumda, belirli bir kişinin trol yapmaya, tehdit etmeye ve sonunda birinin bir çifte özgürlüğü nasıl kullanabileceğimi bilmediğimi gün ışığına çıkarmaya çalıştığını hatırlıyorum.

Bu gönderi, bu yakıcı soruyu her zaman akıllarında soran herkes için o ****ye ithaf edilmiştir, biri nedir ve nasıl olabilir, bir çifte özgürlüğü sömürmek.

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