WWW2Exec - atexit()
Last updated
Last updated
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)
Günümüzde bunu istismar etmek çok garip!
atexit()
bir 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ılacaktır.
Eğer bu fonksiyonlardan herhangi birinin adresini örneğin bir shellcode'a işaret edecek şekilde değiştirebilirseniz, sürecin kontrolünü ele geçireceksiniz, ancak bu şu anda daha karmaşık.
Şu anda çalıştırılacak fonksiyonların adresleri birkaç yapı arkasında gizlidir ve nihayetinde işaret ettikleri adresler, fonksiyonların adresleri değil, XOR ile şifrelenmiş ve rastgele bir anahtar ile kaydırılmıştır. Bu nedenle, şu anda bu saldırı vektörü en azından x86 ve x64_86 üzerinde çok kullanışlı değildir.
Şifreleme fonksiyonu PTR_MANGLE
'dir. Diğer mimariler m68k, mips32, mips64, aarch64, arm, hppa... şifreleme fonksiyonunu uygulamaz çünkü bu fonksiyon girdi olarak aldığı ile aynı çıktıyı döner. Bu nedenle bu mimariler bu vektörle saldırıya uğrayabilir.
Bunun nasıl çalıştığına dair derinlemesine bir açıklamayı https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html adresinde bulabilirsiniz.
Açıklandığı gibi bu yazıda, Program return
veya exit()
kullanarak çıkarsa, __run_exit_handlers()
çalıştırılacak ve kayıtlı yıkıcıları çağıracaktır.
Eğer program _exit()
fonksiyonu aracılığıyla çıkarsa, exit
syscall'ini çağıracak ve çıkış işleyicileri çalıştırılmayacaktır. Bu nedenle, __run_exit_handlers()
'ın çalıştırıldığını doğrulamak için üzerine bir kesme noktası koyabilirsiniz.
Önemli kod (kaynak):
map -> l_addr + fini_array -> d_un.d_ptr
ifadesinin çağrılacak fonksiyonlar dizisinin konumunu hesaplamak için kullanıldığına dikkat edin.
Bir kaç seçenek var:
map->l_addr
değerini, rastgele kod çalıştıracak talimatlarla sahte bir fini_array
gösterecek şekilde üzerine yazın.
l_info[DT_FINI_ARRAY]
ve l_info[DT_FINI_ARRAYSZ]
girişlerini (bellekte daha az ya da çok ardışık olan) üzerine yazarak, bunları sahte bir Elf64_Dyn
yapısına işaret edecek şekilde değiştirin, böylece array
tekrar saldırganın kontrol ettiği bir bellek bölgesine işaret eder.
Bu yazım l_info[DT_FINI_ARRAY]
'ı .bss
içinde kontrol edilen bir belleğin adresi ile değiştirir ve bu bellek sahte bir fini_array
içerir. Bu sahte dizi öncelikle bir one gadget adresini içerir, bu adres çalıştırılacak ve ardından bu sahte dizi ile map->l_addr
değerinin adresi arasındaki fark içerir, böylece *array
sahte diziye işaret eder.
Bu tekniğin ana gönderisine ve bu yazıma göre ld.so, ld.so'daki ikili link_map
'e işaret eden bir işaretçi bırakır. Rastgele bir yazma ile bunu üzerine yazmak ve saldırgan tarafından kontrol edilen sahte bir fini_array
'e işaret etmesini sağlamak mümkündür; örneğin bir one gadget adresi ile.
Önceki kodun ardından, kodla birlikte başka ilginç bir bölüm bulabilirsiniz:
Bu durumda, sahte bir ElfW(Dyn)
yapısına işaret eden map->l_info[DT_FINI]
değerini geçersiz kılmak mümkün olacaktır. daha fazla bilgi burada bulun.
__run_exit_handlers
içindeburada açıklandığı gibi, bir program return
veya exit()
ile çıkarsa, kayıtlı olan herhangi bir yıkıcı işlevi çağıracak olan __run_exit_handlers()
işlevini çalıştıracaktır.
_run_exit_handlers()
kodu:
__call_tls_dtors()
kodu:
Her kayıtlı fonksiyon için tls_dtor_list
, cur->func
'dan işaretçiyi çözerek cur->obj
argümanıyla çağıracaktır.
Bu GEF çatallamasındaki tls
fonksiyonunu kullanarak, aslında dtor_list
'in stack canary ve PTR_MANGLE cookie'ye çok yakın olduğunu görebiliriz. Bu nedenle, üzerinde bir taşma ile cookie ve stack canary'yi üst üste yazmak mümkün olacaktır.
PTR_MANGLE cookie'sini üst üste yazarak, PTR_DEMANLE
fonksiyonunu atlamak için 0x00 olarak ayarlamak, gerçek adresi elde etmek için kullanılan xor
'un sadece yapılandırılan adres olduğunu gösterecektir. Ardından, dtor_list
üzerinde yazarak, fonksiyon adresi ve argümanı ile birkaç fonksiyonu zincirlemek mümkündür.
Son olarak, saklanan işaretçinin sadece cookie ile xoredilmekle kalmayıp, aynı zamanda 17 bit döndürüleceğini unutmayın:
Bu nedenle, yeni bir adres eklemeden önce bunu dikkate almanız gerekir.
orijinal gönderide bir örnek bulun.
__run_exit_handlers
içindeBu teknik burada açıklanmıştır ve yine programın return
veya exit()
çağrısı ile çıkmasına bağlıdır, böylece __run_exit_handlers()
çağrılı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ğere bağlı olarak, çağrılacak fonksiyonun adresi farklı bir yerde olacaktır, 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.
initial
yapısını GEF ile bir hata ayıklama oturumunda gef> p initial
komutunu kullanarak kontrol edebilirsiniz.
Bunu kötüye kullanmak için ya leak yapmanız ya da PTR_MANGLE
çerezini silmeniz ve ardından system('/bin/sh')
ile initial
içindeki bir cxa
girişini yazmanız gerekir.
Bunun bir örneğini teknik hakkında orijinal blog yazısında bulabilirsiniz.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)