WWW2Exec - atexit()
Last updated
Last updated
AWS Hacking'i öğrenin ve uygulayın:HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE) GCP Hacking'i öğrenin ve uygulayın: HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)
Günümüzde bunu sömürmek çok garip!
atexit()
, diğer fonksiyonların parametre olarak geçirildiği bir fonksiyondur. Bu fonksiyonlar, bir exit()
veya main'in dönüşü sırasında çalıştırılacaklardır.
Eğer bu fonksiyonlardan herhangi birinin adresini değiştirebilirseniz ve örneğin bir shellcode'a işaret ederse, işlem kontrolünü ele geçireceksiniz, ancak bu şu anda daha karmaşıktır.
Şu anda çalıştırılacak fonksiyonların adresleri birkaç yapı arkasında gizlenmiştir ve sonunda işaret ettiği adresler fonksiyonların adresleri değil, XOR ile şifrelenmiş ve rastgele bir anahtarla kaydırılmıştır. Bu nedenle bu saldırı vektörü şu anda en azından x86 ve x64_86 üzerinde çok kullanışlı değildir.
Şifreleme fonksiyonu PTR_MANGLE
'dır. m68k, mips32, mips64, aarch64, arm, hppa gibi diğer mimariler, girdi olarak aldığı gibi şifrelemeyi uygulamaz. Bu nedenle bu mimariler bu vektör tarafından saldırıya uğrayabilir.
Bu nasıl çalıştığını ayrıntılı olarak https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html adresinde bulabilirsiniz.
Bu gönderide açıklandığı gibi, program return
veya exit()
kullanarak çıkarsa, __run_exit_handlers()
'ı çalıştıracak ve kayıtlı yıkıcıları çağıracaktır.
Program _exit()
fonksiyonu ile çıkarsa, exit
sistem çağrısını yapacak ve çıkış işleyicileri çalıştırılmayacaktır. Bu nedenle, __run_exit_handlers()
'ın çalıştırıldığını doğrulamak için bir kesme noktası ayarlayabilirsiniz.
Önemli kod (kaynak):
Not: map -> l_addr + fini_array -> d_un.d_ptr
'ın konumunu hesaplamak için nasıl kullanıldığına dikkat edin.
Birkaç seçenek bulunmaktadır:
map->l_addr
değerini üzerine yazarak, yürütülecek keyfi kod talimatları içeren sahte bir fini_array
'ya işaret etmesini sağlamak
Bellekte daha çok ardışık olan l_info[DT_FINI_ARRAY]
ve l_info[DT_FINI_ARRAYSZ]
girişlerini üzerine yazarak, yine array
'ın saldırganın kontrol ettiği bir bellek bölgesine işaret etmesini sağlayacak sahte bir Elf64_Dyn
yapısına işaret etmelerini sağlamak.
Bu yazıda l_info[DT_FINI_ARRAY]
'ı .bss
içindeki sahte bir fini_array
içeren kontrol edilen bellek adresiyle üzerine yazıyor. Bu sahte dizi önce yürütülecek bir one gadget adresini içerir ve ardından bu sahte dizinin adresi ile map->l_addr
'ın değeri arasındaki fark ve böylece *array
sahte diziye işaret eder.
Bu tekniğin ana yazısına ve bu yazıya göre ld.so, ld.so'da binary link_map
'e işaret eden bir işaretçi bırakır. Keyfi yazma ile üzerine yazarak, saldırganın kontrol ettiği sahte bir fini_array
'a işaret eden ve örneğin bir one gadget adresine işaret eden bu işaretçiyi yapabilirsiniz.
Önceki kodun devamında, ilginç bir bölüm daha bulabilirsiniz:
Bu durumda, map->l_info[DT_FINI]
değerinin üzerine yazılması mümkün olacaktır ve sahte bir ElfW(Dyn)
yapısına işaret edilecektir. Daha fazla bilgi için buraya bakabilirsiniz.
__run_exit_handlers
içindeEğer bir program return
veya exit()
ile çıkış yaparsa, __run_exit_handlers()
fonksiyonunu çalıştıracaktır ve kayıtlı olan herhangi bir yıkıcı fonksiyonu çağıracaktır.
_run_exit_handlers() fonksiyonundan gelen kod:
__call_tls_dtors()
fonksiyonundan kod:
Her bir kayıtlı fonksiyon için tls_dtor_list
içindeki işaretçiyi cur->func
'dan çözer ve cur->obj
argümanı ile çağırır.
Bu GEF'in bu çatalından tls
fonksiyonunu kullanarak, aslında dtor_list
'in stack canary ve PTR_MANGLE cookie'ye çok yakın olduğunu görmek mümkündür. Bu nedenle, üzerine taşma gerçekleştirilirse cookie ve stack canary'yi üzerine yazmak mümkün olacaktır.
PTR_MANGLE cookie üzerine yazıldığında, bunu 0x00 olarak ayarlayarak PTR_DEMANLE
fonksiyonunu atlayabilir ve gerçek adresi elde etmek için kullanılan xor
sadece yapılandırılmış adres olacaktır. Ardından, dtor_list
üzerine yazarak, fonksiyon adresi ve argümanı ile birkaç fonksiyonu zincirleme olasılığı vardır.
Son olarak, depolanan işaretçinin sadece cookie ile xor işlemine tabi tutulmayacağını, aynı zamanda 17 bit döndürüleceğini unutmayın:
Yeni bir adres eklemeden önce bunu dikkate almanız gerekmektedir.
Örnek bulun: orijinal gönderide.
__run_exit_handlers
içindeBu teknik burada açıklanmıştır ve yine programın return
veya exit()
çağrısı yaparak çıkması ve dolayısıyla __run_exit_handlers()
fonksiyonunun çağrılmasına bağlıdır.
Bu fonksiyonun daha fazla kodunu kontrol edelim:
Değişken f
, initial
yapısına işaret eder ve f->flavor
değerine bağlı olarak farklı fonksiyonlar çağrılacaktır.
Değerine bağlı olarak çağrılacak fonksiyonun adresi farklı bir yerde olacak, ancak her zaman demangled olacaktır.
Ayrıca, ef_on
ve ef_cxa
seçeneklerinde bir argümanı kontrol etmek de mümkündür.
Hata ayıklama oturumunda gef> p initial
komutunu çalıştırarak initial
yapısını kontrol etmek mümkündür.
Bunu kötüye kullanmak için ya PTR_MANGLE
cookie'yi sızdırmanız ya da silmeniz ve ardından initial
içindeki bir cxa
girdisini system('/bin/sh')
ile üzerine yazmanız gerekir.
Bu tekniğe ilişkin bir örneği orijinal teknik hakkındaki blog yazısında bulabilirsiniz.