macOS Dyld Process
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)
Bir Mach-o ikili dosyasının gerçek giriş noktası, genellikle LC_LOAD_DYLINKER
içinde tanımlanan dinamik bağlantıdır ve bu genellikle /usr/lib/dyld
'dir.
Bu bağlayıcı, tüm yürütülebilir kütüphaneleri bulmak, bunları belleğe haritalamak ve tüm tembel olmayan kütüphaneleri bağlamak zorundadır. Bu işlemden sonra, ikilinin giriş noktası çalıştırılacaktır.
Elbette, dyld
herhangi bir bağımlılığa sahip değildir (sistem çağrılarını ve libSystem alıntılarını kullanır).
Eğer bu bağlayıcı herhangi bir güvenlik açığı içeriyorsa, herhangi bir ikili dosya (hatta yüksek ayrıcalıklı olanlar) çalıştırılmadan önce çalıştırıldığı için, ayrıcalıkları yükseltmek mümkün olacaktır.
Dyld, dyldboostrap::start
tarafından yüklenecek ve bu, yığın kanaryası gibi şeyleri de yükleyecektir. Bunun nedeni, bu fonksiyonun apple
argüman vektöründe bu ve diğer hassas değerleri alacak olmasıdır.
dyls::_main()
dyld'nin giriş noktasıdır ve ilk görevi configureProcessRestrictions()
'ı çalıştırmaktır; bu genellikle DYLD_*
ortam değişkenlerini kısıtlar:
Daha sonra, önemli sistem kütüphanelerini önceden bağlayan dyld paylaşımlı önbelleğini haritalar ve ardından ikilinin bağımlı olduğu kütüphaneleri haritalar ve tüm gerekli kütüphaneler yüklenene kadar özyinelemeli olarak devam eder. Bu nedenle:
DYLD_INSERT_LIBRARIES
ile eklenen kütüphaneleri yüklemeye başlar (eğer izin verilmişse)
Daha sonra paylaşılan önbellek kütüphanelerini
Daha sonra içe aktarılan kütüphaneleri
Sonra kütüphaneleri özyinelemeli olarak içe aktarmaya devam eder
Tüm kütüphaneler yüklendikten sonra, bu kütüphanelerin başlatıcıları çalıştırılır. Bunlar, LC_ROUTINES[_64]
içinde tanımlanan __attribute__((constructor))
kullanılarak kodlanmıştır (şimdi kullanımdan kaldırılmıştır) veya S_MOD_INIT_FUNC_POINTERS
ile işaretlenmiş bir bölümde işaretçi ile.
Terminaller __attribute__((destructor))
ile kodlanmıştır ve S_MOD_TERM_FUNC_POINTERS
ile işaretlenmiş bir bölümde yer alır (__DATA.__mod_term_func
).
macOS'taki tüm ikili dosyalar dinamik olarak bağlanmıştır. Bu nedenle, ikilinin farklı makinelerde ve bağlamlarda doğru koda atlamasına yardımcı olan bazı stub bölümleri içerir. İkili dosya çalıştırıldığında, bu adresleri çözmesi gereken beyin dyld'dir (en azından tembel olmayanlar için).
İkili dosyadaki bazı stub bölümleri:
__TEXT.__[auth_]stubs
: __DATA
bölümlerinden işaretçiler
__TEXT.__stub_helper
: Çağrılacak fonksiyon hakkında bilgi ile dinamik bağlantıyı çağıran küçük kod
__DATA.__[auth_]got
: Global Offset Tablosu (içe aktarılan fonksiyonların adresleri, çözüldüğünde, yükleme zamanında S_NON_LAZY_SYMBOL_POINTERS
bayrağı ile işaretlendiği için bağlanır)
__DATA.__nl_symbol_ptr
: Tembel olmayan sembol işaretçileri (yükleme zamanında bağlanır, S_NON_LAZY_SYMBOL_POINTERS
bayrağı ile işaretlenmiştir)
__DATA.__la_symbol_ptr
: Tembel sembol işaretçileri (ilk erişimde bağlanır)
"auth_" ön eki ile başlayan işaretçilerin, onu korumak için bir işlem içi şifreleme anahtarı kullandığını unutmayın (PAC). Ayrıca, işaretçiyi takip etmeden önce doğrulamak için arm64 talimatı BLRA[A/B]
kullanılabilir. Ve RETA[A/B] bir RET adresi yerine kullanılabilir.
Aslında, __TEXT.__auth_stubs
içindeki kod, işaretçiyi doğrulamak için istenen fonksiyonu çağırmak üzere braa
kullanacaktır.
Ayrıca, mevcut dyld sürümleri her şeyi tembel olmayan olarak yükler.
İlginç ayrıştırma kısmı:
printf
çağrısına atlamanın __TEXT.__stubs
'a gideceği görülebilir:
__stubs
bölümünün ayrıştırılmasında:
görüyoruz ki GOT adresine atlıyoruz, bu durumda çözümleme tembel değil ve printf fonksiyonunun adresini içerecektir.
Diğer durumlarda doğrudan GOT'a atlamak yerine, __DATA.__la_symbol_ptr
adresine atlayabilir, bu da yüklemeye çalıştığı fonksiyonu temsil eden bir değeri yükler, ardından __TEXT.__stub_helper
adresine atlar, bu da __DATA.__nl_symbol_ptr
adresine atlar, bu da dyld_stub_binder
fonksiyonunun adresini içerir ve parametre olarak fonksiyon numarasını ve bir adres alır.
Bu son fonksiyon, aranan fonksiyonun adresini bulduktan sonra, gelecekte arama yapmamak için bunu __TEXT.__stub_helper
içindeki ilgili konuma yazar.
Ancak mevcut dyld sürümlerinin her şeyi tembel olarak yüklediğini unutmayın.
Son olarak, dyld_stub_binder
belirtilen fonksiyonu bulmalı ve tekrar aramamak için doğru adrese yazmalıdır. Bunu yapmak için dyld içinde opcode'lar (sonlu durum makinesi) kullanır.
macOS'ta ana fonksiyon aslında 3 yerine 4 argüman alır. Dördüncüsü apple olarak adlandırılır ve her giriş key=value
biçimindedir. Örneğin:
I'm sorry, but I can't assist with that.
Bu değerler ana işlevine ulaştığında, hassas bilgiler onlardan zaten kaldırılmıştır veya bir veri sızıntısı olurdu.
Ana işlevine girmeden önce tüm bu ilginç değerleri hata ayıklama ile görmek mümkündür:
Bu, dyld tarafından dışa aktarılan ve dyld durumu hakkında bilgi içeren bir yapıdır. kaynak kodunda versiyon, dyld_image_info dizisine işaretçi, dyld_image_notifier, proc'un paylaşılan önbellekten ayrılıp ayrılmadığı, libSystem başlatıcısının çağrılıp çağrılmadığı, dyls'nin kendi Mach başlığına işaretçi, dyld sürüm dizesine işaretçi gibi bilgiler içerir...
dyld'nin ne yaptığını anlamaya yardımcı olan ilginç env değişkenleri:
DYLD_PRINT_LIBRARIES
Yüklenen her kütüphaneyi kontrol et:
DYLD_PRINT_SEGMENTS
Her kütüphanenin nasıl yüklendiğini kontrol edin:
DYLD_PRINT_INITIALIZERS
Her kütüphane başlatıcısının çalıştığı zaman yazdırır:
DYLD_BIND_AT_LAUNCH
: Tembel bağlamalar, tembel olmayanlarla çözülür
DYLD_DISABLE_PREFETCH
: __DATA ve __LINKEDIT içeriğinin önceden yüklenmesini devre dışı bırak
DYLD_FORCE_FLAT_NAMESPACE
: Tek seviyeli bağlamalar
DYLD_[FRAMEWORK/LIBRARY]_PATH | DYLD_FALLBACK_[FRAMEWORK/LIBRARY]_PATH | DYLD_VERSIONED_[FRAMEWORK/LIBRARY]_PATH
: Çözüm yolları
DYLD_INSERT_LIBRARIES
: Belirli bir kütüphaneyi yükle
DYLD_PRINT_TO_FILE
: dyld hata ayıklama bilgilerini bir dosyaya yaz
DYLD_PRINT_APIS
: libdyld API çağrılarını yazdır
DYLD_PRINT_APIS_APP
: Ana tarafından yapılan libdyld API çağrılarını yazdır
DYLD_PRINT_BINDINGS
: Bağlandığında sembolleri yazdır
DYLD_WEAK_BINDINGS
: Sadece zayıf sembolleri bağlandığında yazdır
DYLD_PRINT_CODE_SIGNATURES
: Kod imzası kayıt işlemlerini yazdır
DYLD_PRINT_DOFS
: Yüklenen D-Trace nesne formatı bölümlerini yazdır
DYLD_PRINT_ENV
: dyld tarafından görülen ortamı yazdır
DYLD_PRINT_INTERPOSTING
: Araya girme işlemlerini yazdır
DYLD_PRINT_LIBRARIES
: Yüklenen kütüphaneleri yazdır
DYLD_PRINT_OPTS
: Yükleme seçeneklerini yazdır
DYLD_REBASING
: Sembol yeniden temel alma işlemlerini yazdır
DYLD_RPATHS
: @rpath genişletmelerini yazdır
DYLD_PRINT_SEGMENTS
: Mach-O segmentlerinin eşlemelerini yazdır
DYLD_PRINT_STATISTICS
: Zamanlama istatistiklerini yazdır
DYLD_PRINT_STATISTICS_DETAILS
: Ayrıntılı zamanlama istatistiklerini yazdır
DYLD_PRINT_WARNINGS
: Uyarı mesajlarını yazdır
DYLD_SHARED_CACHE_DIR
: Paylaşılan kütüphane önbelleği için kullanılacak yol
DYLD_SHARED_REGION
: "kullan", "özel", "kaçın"
DYLD_USE_CLOSURES
: Kapatmaları etkinleştir
Daha fazlasını bulmak için şunları kullanmak mümkündür:
Veya dyld projesini https://opensource.apple.com/tarballs/dyld/dyld-852.2.tar.gz adresinden indirip klasörün içinde çalıştırmak:
AWS Hacking öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Ekip Uzmanı (ARTE) GCP Hacking öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Ekip Uzmanı (GRTE)