Heap Overflow
Reading time: 6 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Temel Bilgiler
Heap overflow, stack overflow gibi ama heap'te gerçekleşir. Temelde, bazı verileri depolamak için heap'te ayrılmış bir alanın olduğu ve depolanan verinin ayrılan alandan daha büyük olduğu anlamına gelir.
Stack overflow'larda, talimat işaretçisi veya stack çerçevesi gibi bazı kayıtların stack'ten geri yükleneceğini biliyoruz ve bunu kötüye kullanmak mümkün olabilir. Heap overflow'larda ise, varsayılan olarak heap parçasında depolanan herhangi bir hassas bilgi yoktur. Ancak, hassas bilgiler veya işaretçiler olabilir, bu nedenle bu güvenlik açığının kritikliği hangi verilerin üzerine yazılabileceğine ve bir saldırganın bunu nasıl kötüye kullanabileceğine bağlıdır.
tip
Overflow offset'lerini bulmak için stack overflow'larda olduğu gibi aynı desenleri kullanabilirsiniz.
Stack Overflow'lar vs Heap Overflow'lar
Stack overflow'larda, güvenlik açığının tetiklenebileceği anda stack'te bulunacak düzen ve veri oldukça güvenilirdir. Bunun nedeni, stack'in lineer olması, her zaman çarpışan bellek içinde artması, programın çalışmasının belirli yerlerinde stack belleğinin genellikle benzer türde verileri depolamasıdır ve her fonksiyon tarafından kullanılan stack parçasının sonunda bazı işaretçilerle belirli bir yapıya sahip olmasıdır.
Ancak, heap overflow durumunda, kullanılan bellek lineer değildir, ayrılan parçalar genellikle bellek içinde ayrı konumlarda (birbirinin yanında değil) bulunur çünkü boyutlarına göre ayrılan alanları ayıran bins ve zonlar vardır ve önceki serbest bellek kullanılır yeni parçalar ayırmadan önce. Hedef nesnenin, heap overflow'a karşı savunmasız olan nesneyle çarpışacağını bilmek karmaşıktır. Bu nedenle, bir heap overflow bulunduğunda, istenen nesnenin, overflow edilebilecek nesneden sonra bellekte gelmesini sağlamak için güvenilir bir yol bulmak gereklidir.
Bunun için kullanılan tekniklerden biri Heap Grooming'dir, örneğin bu yazıda açıklanmaktadır. Yazıda, iOS çekirdeğinde bir alanın bellek parçalarını depolamak için bellek kalmadığında, bir çekirdek sayfası ile genişletildiği ve bu sayfanın beklenen boyutlardaki parçalara bölündüğü açıklanmaktadır (iOS sürüm 9.2'ye kadar, ardından bu parçalar bu saldırıların istismarını zorlaştırmak için rastgele bir şekilde kullanılır).
Bu nedenle, önceki yazıda bir heap overflow gerçekleştiğinde, overflow edilen nesneyi bir kurban nesnesiyle çarpışmaya zorlamak için, tüm serbest parçaların doldurulmasını sağlamak ve yeni bir sayfanın oluşturulmasını sağlamak için birkaç kalloc
birkaç iş parçacığı tarafından zorlanır.
Belirli bir boyuttaki nesnelerle bu doldurmayı zorlamak için, iOS mach portu ile ilişkili dışarıda ayrılan bellek ideal bir adaydır. Mesajın boyutunu şekillendirerek, kalloc
ayrımının boyutunu tam olarak belirlemek mümkündür ve ilgili mach portu yok edildiğinde, ilgili ayrım hemen kfree
'ye geri verilecektir.
Sonra, bu yer tutuculardan bazıları serbest bırakılabilir. kalloc.4096
serbest listesi, son giren ilk çıkar sırasına göre elemanları serbest bırakır, bu temelde, bazı yer tutucular serbest bırakıldığında ve istismar, overflow'a karşı savunmasız nesneyi ayırmaya çalışırken birkaç kurban nesnesi ayırmaya çalışırsa, bu nesnenin bir kurban nesnesinden sonra gelmesi olasıdır.
Örnek libc
Bu sayfada bir temel Heap overflow emülasyonu bulmak mümkündür; bu emülasyon, bir sonraki parçanın prev in use bitini ve prev boyutunun konumunu üzerine yazarak kullanılan bir parçayı konsolide etmenin (kullanılmamış gibi düşünmesini sağlayarak) ve sonra tekrar ayırmanın mümkün olduğunu göstermektedir.
Protostar heap 0 adlı başka bir örnek, bir heap overflow'un istismar edilebileceği çok temel bir CTF örneğini göstermektedir; bu örnekte bayrağı almak için kazanan fonksiyonu çağırmak mümkündür.
Protostar heap 1 örneğinde, bir buffer overflow istismar ederek, yakın bir parçaya bir adresi üzerine yazmanın mümkün olduğu gösterilmektedir; bu adrese kullanıcıdan rastgele veriler yazılacaktır.
Örnek ARM64
https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/ sayfasında, yürütülecek bir komutun overflow edilen parçanın sonraki parçasında depolandığı bir heap overflow örneği bulabilirsiniz. Bu nedenle, yürütülen komutu, kolay bir istismar ile üzerine yazarak değiştirmek mümkündür:
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
Diğer örnekler
- Auth-or-out. Hack The Box
- Bir Heap Overflow elde etmek için Integer Overflow zafiyetini kullanıyoruz.
- Bir
struct
içindeki bir işlevin işaretçilerini bozarız, taşan parçanın içinesystem
gibi bir işlev ayarlayıp kod yürütme elde ederiz.
Gerçek Dünya Örneği: CVE-2025-40597 – __sprintf_chk
'nin Yanlış Kullanımı
SonicWall SMA100 firmware 10.2.1.15'te ters proxy modülü mod_httprp.so
, 0x80-byte boyutunda bir heap parçası ayırır ve ardından içine birkaç dizeyi __sprintf_chk
ile birleştirir:
char *buf = calloc(0x80, 1);
/* … */
__sprintf_chk(buf, /* destination (0x80-byte chunk) */
-1, /* <-- size argument !!! */
0, /* flags */
"%s%s%s%s", /* format */
"/", "https://", path, host);
__sprintf_chk
, _FORTIFY_SOURCE'un bir parçasıdır. Pozitif bir size
parametresi aldığında, sonuçta oluşan string'in hedef tamponun içine sığdığını doğrular. -1
(0xFFFFFFFFFFFFFFFF) geçirerek, geliştiriciler etkili bir şekilde sınır kontrolünü devre dışı bıraktılar, güçlendirilmiş çağrıyı klasik, güvensiz sprintf
'ye geri döndürdüler.
Aşırı uzun bir Host:
başlığı sağlamak, bu nedenle bir saldırganın 0x80 baytlık parçayı taşmasına ve sonraki heap parçasının meta verilerini bozmasına olanak tanır (tcache / fast-bin / small-bin, ayırıcıya bağlı olarak). Bir çökme şu şekilde yeniden üretilebilir:
import requests, warnings
warnings.filterwarnings('ignore')
requests.get(
'https://TARGET/__api__/',
headers={'Host': 'A'*750},
verify=False
)
Pratik istismar, kontrol edilebilir bir nesneyi savunmasız parçanın hemen arkasına yerleştirmek için heap grooming gerektirecektir, ancak kök neden iki önemli çıkarımı vurgular:
- _FORTIFY_SOURCE gümüş bir mermi değildir – yanlış kullanım korumayı geçersiz kılabilir.
- Her zaman doğru tampon boyutunu
_chk
ailesine iletin (veya daha iyisi,snprintf
kullanın).
References
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.