WWW2Exec - .dtors & .fini_array
.dtors
Günümüzde bir binary dosyasında .dtors bölümü bulmak çok garip!
Yıkıcılar, programın sona ermeden önce (ana main
fonksiyonu geri döndükten sonra) çalıştırılan fonksiyonlardır.
Bu fonksiyonların adresleri, binary dosyasının .dtors
bölümünde saklanır ve bu nedenle, __DTOR_END__
içine bir shellcode adresi yazmayı başarırsanız, bu programın sona ermeden önce çalıştırılacaktır.
Bu bölümün adresini şu şekilde alın:
Genellikle DTOR işaretçilerini ffffffff
ve 00000000
değerleri arasında bulacaksınız. Yani eğer sadece bu değerleri görüyorsanız, bu herhangi bir fonksiyonun kaydedilmediği anlamına gelir. Bu yüzden 00000000
değerini shellcode'ın adresiyle üzerine yazın ve onu çalıştırın.
Tabii ki, daha sonra onu çağırmak için shellcode'ı saklamak için bir yer bulmanız gerekiyor.
.fini_array
Temelde bu, programın sona ermeden önce çağrılacak fonksiyonların bulunduğu bir yapıdır, .dtors
gibi. Bu, shellcode'unuzu bir adrese atlayarak çağırabildiğinizde veya zafiyeti ikinci kez sömürmek için main
'e geri gitmeniz gereken durumlarda ilginçtir.
Not edin ki .fini_array
'den bir işlev çalıştırıldığında bir sonrakine geçer, bu yüzden birkaç kez çalıştırılmaz (sonsuz döngüleri önler), ancak yalnızca buraya yerleştirilen bir işlevin çalıştırılmasını sağlar.
.fini_array
içindeki girişlerin ters sırayla çağrıldığını unutmayın, bu yüzden muhtemelen en sondan yazmaya başlamak istersiniz.
Sonsuz döngü
.fini_array
'yi kötüye kullanmak için sonsuz bir döngü elde etmek için burada ne yapıldığını kontrol edebilirsiniz: En az 2 girişiniz varsa .fini_array
içinde, şunları yapabilirsiniz:
İlk yazmanızı zafiyetli keyfi yazma işlevini çağırmak için kullanın
Ardından,
__libc_csu_fini
tarafından depolanan yığında dönüş adresini hesaplayın ve oraya__libc_csu_fini
'nin adresini koyunBu,
__libc_csu_fini
'nin kendisini tekrar çağırarak.fini_array
işlevlerini tekrar çalıştırmasını sağlayacak ve zafiyetli WWW işlevini 2 kez çağıracaktır: biri için keyfi yazma ve diğeri yığında kendi kendini tekrar çağırmak için__libc_csu_fini
'nin dönüş adresini tekrar üzerine yazmak.
Tam RELRO** ile,** bölüm .fini_array
salt okunur hale getirilir.
link_map
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()
işlevi ile çıkarsa, exit
sistem çağrısını çağırır ve çıkış işleyicileri çalıştırılmaz. 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
kullanılarak dizinin çağrılacak fonksiyonların konumunu hesaplamak için.
Birkaç seçenek bulunmaktadır:
map->l_addr
değerini üzerine yazarak, talimatları yürütmek için sahte birfini_array
'e işaret edecek şekilde yapay birfini_array
oluşturmakBellekte daha çok ardışık olan
l_info[DT_FINI_ARRAY]
vel_info[DT_FINI_ARRAYSZ]
girişlerini üzerine yazarak, tekrararray
'ın saldırganın kontrol ettiği bir bellek bölgesine işaret etmesini sağlayacak sahte birElf64_Dyn
yapısına işaret etmelerini sağlamak.Bu yazıda
l_info[DT_FINI_ARRAY]
üzerine.bss
içindeki kontrol edilen bir bellekteki adresle üzerine yazarak sahte birfini_array
'nın adresini üzerine yazıyor. Bu sahte dizi önce yürütülecek olan bir one gadget adresini içerir ve ardından bu sahte dizi adresi ilemap->l_addr
değeri arasındaki farkı içerir, 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. Bir keyfi yazma işlemiyle üzerine yazarak, saldırganın kontrol ettiği sahte birfini_array
'e işaret eden bir adresle ld.so'nun bu işaretçiye işaret etmesini sağlamak mümkündür, örneğin bir one gadget adresine.
Bu durumda, map->l_info[DT_FINI]
değerinin üzerine yazılabilir ve sahte bir ElfW(Dyn)
yapısına işaret edilebilir. Daha fazla bilgi için buraya bakabilirsiniz.
TLS-Depolama dtor_list üzerine yazma işlemi __run_exit_handlers
içinde
__run_exit_handlers
içindeBurada açıklandığı gibi, 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 kod:
Kod __call_tls_dtors()
fonksiyonundan:
Her bir kayıtlı fonksiyon için tls_dtor_list
içindeki işaretçiyi cur->func
'tan çözer ve cur->obj
argümanı ile çağırır.
Bu GEF'in bu fork'u kullanılarak tls
fonksiyonu ile, aslında dtor_list
'in stack canary ve PTR_MANGLE cookie'ye çok yakın olduğu görülebilir. Bu nedenle, üzerine taşma olursa cookie ve stack canary'yi üzerine yazmak mümkün olacaktır.
PTR_MANGLE cookie üzerine yazıldığında, PTR_DEMANLE
fonksiyonunu atlayabilir çünkü 0x00 olarak ayarlanması, gerçek adresi elde etmek için kullanılan xor
'un sadece yapılandırılmış adres olduğu anlamına gelir. Ardından, dtor_list
üzerine yazarak, fonksiyon adresi ve argümanı ile birkaç fonksiyonu zincirleme mümkün olacaktır.
Son olarak, depolanan işaretçinin sadece cookie ile xor işlemine tabi tutulmayacağı, aynı zamanda 17 bit döndürüleceğine dikkat edin:
Yeni bir adres eklemeden önce bunu dikkate almanız gerekmektedir.
Örnek bir örneği orijinal gönderide bulun.
__run_exit_handlers
içindeki diğer karışık işaretçiler
__run_exit_handlers
içindeki diğer karışık işaretçilerBu 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 ile çalışırken gef> p initial
komutu kullanılarak initial
yapısı kontrol edilebilir.
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
girişini 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.
Last updated