Unsorted Bin Attack
Last updated
Last updated
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)
Unsorted bin'in ne olduğunu öğrenmek için bu sayfayı kontrol edin:
Bins & Memory AllocationsUnsorted listeler, bk
adresinde unsorted_chunks (av)
adresini yazma yeteneğine sahiptir. Bu nedenle, bir saldırgan unsorted bin içindeki bir chunk'taki bk
işaretçisinin adresini değiştirebilirse, bu adresi rastgele bir adrese yazabilir ki bu da Glibc adreslerini sızdırmak veya bazı savunmaları aşmak için faydalı olabilir.
Yani, temelde bu saldırı, rastgele bir adreste büyük bir sayı ayarlamaya olanak tanır. Bu büyük sayı, bir heap adresi veya bir Glibc adresi olabilecek bir adrestir. Tipik bir hedef, global_max_fast
'tır; bu, daha büyük boyutlarda hızlı binler oluşturulmasına izin verir (ve bir unsorted bin saldırısından hızlı bin saldırısına geçiş yapar).
https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle adresinde sağlanan örneğe bakarak ve chunk boyutları olarak 0x400 ve 0x500 yerine 0x4000 ve 0x5000 kullanarak (Tcache'den kaçınmak için) günümüzde malloc(): unsorted double linked list corrupted
hatasının tetiklendiğini görebilirsiniz.
Bu nedenle, bu unsorted bin saldırısı artık (diğer kontrollerin yanı sıra) çift bağlı listeyi düzeltme yeteneğine de ihtiyaç duyar, böylece victim->bk->fd == victim
veya victim->fd == av (arena)
atlanır; bu, yazmak istediğimiz adresin fd
konumunda sahte chunk'ın adresini içermesi ve sahte chunk'ın fd
'sinin arenaya işaret etmesi gerektiği anlamına gelir.
Bu saldırının unsorted bin'i (dolayısıyla küçük ve büyük olanları da) bozduğunu unutmayın. Bu nedenle, artık yalnızca hızlı binlerden tahsisat kullanabiliriz (daha karmaşık bir program başka tahsisatlar yapabilir ve çökebilir) ve bunu tetiklemek için aynı boyutta tahsisat yapmalıyız yoksa program çöker.
global_max_fast
'ı geçersiz kılmak, bu durumda yardımcı olabilir; hızlı binin, istismar tamamlanana kadar diğer tüm tahsisatlarla ilgilenebileceğine güvenerek.
guyinatuxedo tarafından sağlanan kod bunu çok iyi açıklıyor, ancak malloc'ları yeterince büyük bir bellek tahsis etmek için değiştirirseniz, böylece Tcache'de sona ermezseniz, daha önce bahsedilen hatanın bu tekniği engellediğini görebilirsiniz: malloc(): unsorted double linked list corrupted
Bu aslında çok temel bir kavramdır. Unsorted bin'deki chunk'lar işaretçilere sahip olacaktır. Unsorted bin'deki ilk chunk, aslında fd
ve bk
bağlantılarına ana arenanın (Glibc) bir kısmına işaret eder.
Bu nedenle, bir chunk'ı unsorted bin'e yerleştirip okuyabilirseniz (free'den sonra kullanma) veya en az 1 işaretçiyi geçersiz kılmadan tekrar tahsis edebilirseniz ve ardından okuyabilirseniz, bir Glibc bilgi sızıntısı elde edebilirsiniz.
Bu yazımda kullanılan benzer bir saldırı, 4 chunk yapısını (A, B, C ve D - D yalnızca üst chunk ile konsolidasyonu önlemek için) kötüye kullanmak için B'deki bir null byte taşmasını kullanarak C'nin B'nin kullanılmadığını belirtmesini sağladı. Ayrıca, B'deki prev_size
verisi değiştirilerek boyut, B'nin boyutu yerine A+B olarak ayarlandı.
Sonra C serbest bırakıldı ve A+B ile konsolide edildi (ancak B hala kullanılıyordu). A boyutunda yeni bir chunk tahsis edildi ve ardından libc sızdırılan adresler B'ye yazıldı ve buradan sızdırıldı.
Amaç, 4869'dan büyük bir değerle bir global değişkeni geçersiz kılmak, böylece bayrağı almak ve PIE'nin etkin olmamasını sağlamaktır.
Rastgele boyutlarda chunk'lar oluşturmak mümkündür ve istenen boyutta bir heap taşması vardır.
Saldırı, 3 chunk oluşturarak başlar: taşmayı kötüye kullanmak için chunk0, taşma yapılacak chunk1 ve üst chunk'un önceki chunk'larla konsolide olmaması için chunk2.
Sonra, chunk1 serbest bırakılır ve chunk0, chunk1'in bk
işaretçisinin işaret ettiği yere taşma yapar: bk = magic - 0x10
Ardından, chunk1 ile aynı boyutta chunk3 tahsis edilir, bu da unsorted bin saldırısını tetikleyecek ve global değişkenin değerini değiştirecektir, böylece bayrağı almak mümkün olacaktır.
Birleştirme işlevi, her iki geçirilen indeks aynı olduğunda onu yeniden tahsis edeceği ve ardından serbest bırakacağı için savunmasızdır, ancak serbest bırakılan bölgeye bir işaretçi döndürür.
Bu nedenle, 2 chunk oluşturulur: chunk0 kendisiyle birleştirilecek ve üst chunk ile konsolide olmasını önlemek için chunk1. Ardından, chunk0 ile birleştirme işlevi iki kez çağrılır, bu da free'den sonra kullanma durumuna neden olur.
Sonra, view
işlevi, free'den sonra kullanılan chunk'ın indeksi olan 2 ile çağrılır; bu, bir libc adresini sızdırır.
İkili, yalnızca global_max_fast
'dan daha büyük boyutları malloc etmeye izin verecek şekilde korumalara sahip olduğundan, hızlı bin kullanılmadığı için bir unsorted bin saldırısı kullanılacak ve global değişken global_max_fast
'ı geçersiz kılmak için kullanılacaktır.
Ardından, 2 indeksi (free'den sonra kullanılan işaretçi) ile edit işlevi çağrılabilir ve bk
işaretçisi p64(global_max_fast-0x10)
'a işaret edecek şekilde geçersiz kılınabilir. Ardından, yeni bir chunk oluşturmak, daha önce tehlikeye atılmış serbest adresi (0x20) kullanacak ve unsorted bin saldırısını tetikleyecektir; bu, global_max_fast
'ı çok büyük bir değerle geçersiz kılacaktır ve artık hızlı binlerde chunk'lar oluşturmak mümkün olacaktır.
Şimdi bir hızlı bin saldırısı gerçekleştirilir:
Öncelikle, __free_hook
konumunda hızlı 200 boyutunda chunk'larla çalışmanın mümkün olduğu keşfedilir:
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook> gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000 0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
Bu konumda 0x200 boyutunda hızlı bir chunk elde edebilirsek, çalıştırılacak bir işlev işaretçisini geçersiz kılmak mümkün olacaktır.
Bunun için, 0xfc
boyutunda yeni bir chunk oluşturulur ve birleştirilmiş işlev bu işaretçi ile iki kez çağrılır; bu şekilde, hızlı bin içinde 0xfc*2 = 0x1f8
boyutunda serbest bir chunk'a işaret eden bir işaretçi elde ederiz.
Ardından, bu chunk'ta edit işlevi çağrılarak bu hızlı binin fd
adresi önceki __free_hook
işlevine işaret edecek şekilde değiştirilir.
Ardından, hızlı bin'den önceki işe yaramaz chunk'ı almak için 0x1f8
boyutunda bir chunk oluşturulur; böylece __free_hook
içinde hızlı bir bin chunk'ı elde edilir ve bu, system
işlevinin adresi ile geçersiz kılınır.
Ve nihayet, /bin/sh\x00
dizesini içeren bir chunk, silme işlevini çağırarak serbest bırakılır; bu, __free_hook
işlevini tetikler ve /bin/sh\x00
parametre olarak sistem işlevine işaret eder.
Unsorted bin'de chunk'ları konsolide etmek ve bir libc bilgi sızıntısı elde etmek için 1B taşmasını kötüye kullanmanın başka bir örneği ve ardından malloc hook'u bir gadget adresi ile geçersiz kılmak için hızlı bin saldırısı.
Sadece 0x100
'den büyük boyutlarda chunk'lar tahsis edebiliriz.
Unsorted Bin saldırısı kullanarak global_max_fast
'ı geçersiz kılmak (ASLR nedeniyle 1/16 kez çalışır, çünkü 12 bit değiştirmemiz gerekir, ancak 16 bit değiştirmeliyiz).
Global chunk dizisini değiştirmek için hızlı bin saldırısı. Bu, GOT'u değiştirme ve bazı işlevleri system
'a işaret etme yeteneği veren rastgele okuma/yazma ilkesidir.
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)