Stack Canaries
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)
StackGuard, EIP (Genişletilmiş Talimat İşaretçisi)'nden önce, özellikle 0x000aff0d
(null, yeni satır, EOF, taşıma dönüşü temsil eder) olarak bilinen özel bir değeri canary olarak ekler ve bu, tampon taşmalarına karşı koruma sağlar. Ancak, recv()
, memcpy()
, read()
ve bcopy()
gibi fonksiyonlar hala savunmasızdır ve EBP (Temel İşaretçi)'yi korumaz.
StackShield, Global Return Stack'i koruyarak daha sofistike bir yaklaşım benimser; bu, tüm dönüş adreslerini (EIP'ler) saklar. Bu yapı, herhangi bir taşmanın zarar vermemesini sağlar, çünkü saklanan ve gerçek dönüş adresleri arasında bir karşılaştırma yapılmasına olanak tanır. Ayrıca, StackShield, dönüş adresini bir sınır değeri ile kontrol ederek EIP'nin beklenen veri alanının dışına işaret edip etmediğini tespit edebilir. Ancak, bu koruma, Return-to-libc, ROP (Return-Oriented Programming) veya ret2ret gibi tekniklerle aşılabilir; bu da StackShield'in yerel değişkenleri korumadığı anlamına gelir.
-fstack-protector
:Bu mekanizma, EBP'den önce bir canary yerleştirir ve yerel değişkenleri, tamponları daha yüksek bellek adreslerinde konumlandıracak şekilde yeniden düzenler, böylece diğer değişkenleri ezmelerini engeller. Ayrıca, yerel değişkenlerin üstündeki yığın üzerinde geçirilen argümanları güvenli bir şekilde kopyalar ve bu kopyaları argüman olarak kullanır. Ancak, 8'den az eleman içeren dizileri veya bir kullanıcının yapısı içindeki tamponları korumaz.
Canary, /dev/urandom
'dan türetilen rastgele bir sayıdır veya varsayılan değeri 0xff0a0000
'dir. TLS (Thread Local Storage)'de saklanır ve bu, iş parçacıkları arasında paylaşılan bellek alanlarının iş parçacığına özgü küresel veya statik değişkenlere sahip olmasına olanak tanır. Bu değişkenler başlangıçta ana süreçten kopyalanır ve çocuk süreçler, ana veya kardeşleri etkilemeden verilerini değiştirebilir. Ancak, eğer bir fork()
yeni bir canary oluşturmadan kullanılırsa, tüm süreçler (ana ve çocuklar) aynı canary'yi paylaşır, bu da onu savunmasız hale getirir. i386 mimarisinde, canary gs:0x14
'te, x86_64'te ise fs:0x28
'de saklanır.
Bu yerel koruma, saldırılara karşı savunmasız tamponlara sahip fonksiyonları tanımlar ve bu fonksiyonların başına canary yerleştirmek için kod enjekte eder ve sonunda bütünlüğünü doğrulamak için kod ekler.
Bir web sunucusu fork()
kullandığında, canary'yi byte byte tahmin etmek için bir kaba kuvvet saldırısını etkinleştirir. Ancak, fork()
'tan sonra execve()
kullanmak bellek alanını ezdiğinden, saldırıyı geçersiz kılar. vfork()
, çocuk sürecin yazma girişiminde bulunana kadar kopyalamadan çalışmasına izin verir; bu noktada bir kopya oluşturulur ve bu, süreç oluşturma ve bellek yönetimi için farklı bir yaklaşım sunar.
x64
ikili dosyalarında, canary çerezi 0x8
byte qword'dur. İlk yedi byte rastgeledir ve son byte bir null byte'dır.
x86
ikili dosyalarında, canary çerezi 0x4
byte dword'dur. İlk üç byte rastgeledir ve son byte bir null byte'dır.
Her iki canary'nin en az anlamlı byte'ı bir null byte'dır çünkü bu, daha düşük adreslerden gelen yığın içinde ilk olacak ve bu nedenle string okuyan fonksiyonlar onu okumadan önce duracaktır.
Canary'yi sızdırmak ve ardından kendi değeriyle (örneğin, tampon taşması) ezmek.
Eğer canary çocuk süreçlerde fork edilirse, bir byte bir seferde brute-force yapmak mümkün olabilir:
Eğer ikili dosyada ilginç bir sızıntı veya keyfi okuma açığı varsa, onu sızdırmak mümkün olabilir:
Yığın üzerinde saklanan işaretçileri ezmek
Yığın, bir yığın taşmasına karşı savunmasızsa, string'lere veya fonksiyonlara işaret eden adresleri içerebilir ve bu adresler, canary'ye ulaşmadan açığı istismar etmek için ezilebilir. Kontrol edin:
Pointer RedirectingHem ana hem de iş parçacığı canary'sini değiştirmek
Canary ile korunan bir iş parçacıklı fonksiyonda bir tampon taşması, iş parçacığının ana canary'sini değiştirmek için kullanılabilir. Sonuç olarak, bu önlem işe yaramaz çünkü kontrol, aynı (değiştirilmiş) iki canary ile kullanılır.
Ayrıca, canary ile korunan bir iş parçacıklı fonksiyonda bir tampon taşması, TLS'de saklanan ana canary'yi değiştirmek için kullanılabilir. Bunun nedeni, bir iş parçacığının yığınında bir bof aracılığıyla TLS'nin saklandığı bellek konumuna ulaşmanın mümkün olabilmesidir. Sonuç olarak, bu önlem işe yaramaz çünkü kontrol, aynı (değiştirilmiş) iki canary ile kullanılır. Bu saldırı, yazıda gerçekleştirilmiştir: http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads
Ayrıca, https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015 sunumunu kontrol edin; bu sunumda genellikle TLS'nin mmap
ile saklandığı ve bir iş parçacığı yığını oluşturulduğunda bunun da mmap
ile oluşturulduğu belirtilmektedir; bu da önceki yazıda gösterildiği gibi taşmaya izin verebilir.
__stack_chk_fail
GOT girişini değiştirmek
Eğer ikili dosya Kısmi RELRO'ya sahipse, o zaman __stack_chk_fail
'in GOT girişini, canary değiştiğinde programı engellemeyen sahte bir fonksiyon olacak şekilde değiştirmek için keyfi bir yazma işlemi kullanabilirsiniz.
Bu saldırı, yazıda gerçekleştirilmiştir: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/
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)