macOS Apps - Inspecting, debugging and Fuzzing
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)
Buradan disarm'ı indirin.
You can jtool2'yi buradan indirin veya brew
ile kurabilirsiniz.
jtool, disarm lehine kullanımdan kaldırılmıştır
Codesign
macOS'de bulunabilirken, ldid
iOS'de bulunabilir
SuspiciousPackage , .pkg dosyalarını (kurulum dosyaları) incelemek ve yüklemeden önce içeriğini görmek için yararlı bir araçtır.
Bu kurulum dosyaları, kötü amaçlı yazılım yazarlarının genellikle kötü amaçlı yazılımı sürdürmek için kötüye kullandığı preinstall
ve postinstall
bash betikleri içerir.
Bu araç, herhangi bir şeyi çalıştırmadan önce Apple disk görüntülerini (.dmg) incelemek için monte etmeye olanak tanır:
It will be mounted in /Volumes
Yüksek entropi kontrolü
String'leri kontrol et (anlaşılır string yoksa, packed)
MacOS için UPX packer, "__XHDR" adlı bir bölüm oluşturur
Objective-C ile yazılmış programların derlendiğinde Mach-O ikili dosyalarına sınıf bildirimlerini koruduğunu unutmayın. Bu tür sınıf bildirimleri şunları içerir:
Tanımlanan arayüzler
Arayüz yöntemleri
Arayüz örnek değişkenleri
Tanımlanan protokoller
Bu isimlerin, ikilinin tersine çevrilmesini zorlaştırmak için obfuscate edilebileceğini unutmayın.
Bir ikili dosyada Objective-C kullanan bir fonksiyon çağrıldığında, derlenmiş kod o fonksiyonu çağırmak yerine objc_msgSend
çağrısını yapar. Bu, nihai fonksiyonu çağıracaktır:
Bu fonksiyonun beklediği parametreler şunlardır:
İlk parametre (self) "mesajı alacak sınıfın örneğine işaret eden bir işaretçi"dir. Daha basit bir ifadeyle, bu, metodun çağrıldığı nesnedir. Eğer metod bir sınıf metoduysa, bu sınıf nesnesinin (bütün olarak) bir örneği olacaktır, oysa bir örnek metodu için self, sınıfın bir örneğine işaret edecektir.
İkinci parametre (op), "mesajı işleyen metodun seçicisidir". Yine, daha basit bir ifadeyle, bu sadece metodun adıdır.
Kalan parametreler, metodun gerektirdiği herhangi bir değerdir (op).
Bu bilgiyi lldb
ile ARM64'te nasıl kolayca alacağınızı bu sayfada görün:
x64:
Dynadump, Objective-C ikili dosyalarını sınıf dökümü yapmak için bir araçtır. Github, dylib'leri belirtmektedir ancak bu, çalıştırılabilir dosyalarla da çalışır.
Yazım zamanı itibarıyla, bu şu anda en iyi çalışanıdır.
class-dump , ObjetiveC formatında koddaki sınıflar, kategoriler ve protokoller için bildirimler üreten orijinal araçtır.
Eski ve bakımsızdır, bu yüzden muhtemelen düzgün çalışmayacaktır.
iCDump modern ve çok platformlu bir Objective-C sınıf dökümüdür. Mevcut araçlarla karşılaştırıldığında, iCDump Apple ekosisteminden bağımsız olarak çalışabilir ve Python bağlamalarını açığa çıkarır.
Swift ikili dosyaları ile, Objective-C uyumluluğu olduğundan, bazen class-dump kullanarak bildirimleri çıkartabilirsiniz ama her zaman değil.
jtool -l
veya otool -l
komut satırları ile __swift5
ön eki ile başlayan birkaç bölüm bulmak mümkündür:
Bu bölümde saklanan bilgiler hakkında daha fazla bilgiye bu blog yazısından ulaşabilirsiniz.
Ayrıca, Swift ikili dosyaları sembollere sahip olabilir (örneğin, kütüphanelerin fonksiyonlarının çağrılabilmesi için sembolleri saklaması gerekir). Semboller genellikle fonksiyon adı ve attr hakkında çirkin bir şekilde bilgi içerir, bu nedenle çok faydalıdırlar ve orijinal adı alabilen "demanglers" vardır:
Not edin ki, ikili dosyaları hata ayıklamak için, SIP devre dışı bırakılmalıdır (csrutil disable
veya csrutil enable --without debug
) veya ikili dosyaları geçici bir klasöre kopyalamak ve imzayı kaldırmak için codesign --remove-signature <binary-path>
komutunu kullanmak ya da ikili dosyanın hata ayıklanmasına izin vermek gerekir (bunu bu script ile kullanabilirsiniz).
Not edin ki, macOS'ta sistem ikililerini enstrümante etmek (örneğin cloudconfigurationd
gibi) için, SIP devre dışı bırakılmalıdır (sadece imzayı kaldırmak işe yaramaz).
macOS, süreçler hakkında bilgi veren bazı ilginç API'ler sunar:
proc_info
: Her süreç hakkında çok fazla bilgi veren ana API'dir. Diğer süreçlerin bilgilerini almak için root olmanız gerekir, ancak özel yetkilere veya mach portlarına ihtiyacınız yoktur.
libsysmon.dylib
: XPC tarafından sunulan işlevler aracılığıyla süreçler hakkında bilgi almayı sağlar, ancak com.apple.sysmond.client
yetkisine sahip olmak gerekir.
Stackshotting, süreçlerin durumunu, tüm çalışan iş parçacıklarının çağrı yığınlarını içerecek şekilde yakalamak için kullanılan bir tekniktir. Bu, hata ayıklama, performans analizi ve sistemin belirli bir zamanda davranışını anlamak için özellikle yararlıdır. iOS ve macOS'ta, stackshotting, sample
ve spindump
gibi çeşitli araçlar ve yöntemler kullanılarak gerçekleştirilebilir.
Bu araç (/usr/bini/ysdiagnose
), bilgisayarınızdan ps
, zprint
gibi onlarca farklı komut çalıştırarak çok fazla bilgi toplar...
root olarak çalıştırılmalıdır ve daemon /usr/libexec/sysdiagnosed
çok ilginç yetkilere sahiptir, bunlar arasında com.apple.system-task-ports
ve get-task-allow
bulunmaktadır.
Plist'i /System/Library/LaunchDaemons/com.apple.sysdiagnose.plist
konumunda bulunur ve 3 MachServices tanımlar:
com.apple.sysdiagnose.CacheDelete
: /var/rmp içindeki eski arşivleri siler
com.apple.sysdiagnose.kernel.ipc
: Özel port 23 (kernel)
com.apple.sysdiagnose.service.xpc
: Libsysdiagnose
Obj-C sınıfı aracılığıyla kullanıcı modu arayüzü. Bir sözlükte üç argüman geçirilebilir (compress
, display
, run
)
MacOS, bir uygulama çalıştırırken ne yaptığını anlamaya yardımcı olabilecek çok sayıda günlük üretir.
Ayrıca, bazı günlükler, bazı kullanıcı veya bilgisayar tanımlanabilir bilgileri gizlemek için <private>
etiketini içerecektir. Ancak, bu bilgileri açığa çıkarmak için bir sertifika yüklemek mümkündür. buradan açıklamaları takip edin.
Hopper'ın sol panelinde, ikilinin sembollerini (Etiketler), prosedürler ve işlevler listesini (Proc) ve dizeleri (Str) görebilirsiniz. Bunlar tüm dizeler değildir, ancak Mac-O dosyasının çeşitli bölümlerinde tanımlananlardır (örneğin cstring veya objc_methname
).
Orta panelde dağıtılmış kodu görebilirsiniz. Ve bunu ham dağıtım, graf olarak, decompile edilmiş ve ikili olarak ilgili simgeye tıklayarak görebilirsiniz:
Bir kod nesnesine sağ tıklayarak, o nesneye referansları/giden referansları görebilir veya adını değiştirebilirsiniz (bu, decompile edilmiş psödo kodda çalışmaz):
Ayrıca, orta alanda python komutları yazabilirsiniz.
Sağ panelde, navigasyon geçmişi (bu sayede mevcut duruma nasıl geldiğinizi bilirsiniz), bu işlevi çağıran tüm işlevleri ve bu işlevin çağırdığı tüm işlevleri görebileceğiniz çağrı grafiği ve yerel değişkenler bilgileri gibi ilginç bilgiler görebilirsiniz.
Kullanıcılara uygulamalara son derece düşük seviyede erişim sağlar ve kullanıcılara programları izleme ve hatta yürütme akışlarını değiştirme imkanı sunar. Dtrace, kernel boyunca yerleştirilen prob'lar kullanır ve sistem çağrılarının başlangıç ve bitiş noktaları gibi yerlerde bulunur.
DTrace, her sistem çağrısı için bir prob oluşturmak üzere dtrace_probe_create
işlevini kullanır. Bu prob'lar, her sistem çağrısının giriş ve çıkış noktasında tetiklenebilir. DTrace ile etkileşim, yalnızca root kullanıcı için mevcut olan /dev/dtrace aracılığıyla gerçekleşir.
Dtrace'ı SIP korumasını tamamen devre dışı bırakmadan etkinleştirmek için kurtarma modunda şunu çalıştırabilirsiniz: csrutil enable --without dtrace
Ayrıca, derlediğiniz dtrace
veya dtruss
ikililerini de kullanabilirsiniz.
Dtrace'ın mevcut prob'ları şunlarla elde edilebilir:
Probe adı dört bölümden oluşur: sağlayıcı, modül, işlev ve ad (fbt:mach_kernel:ptrace:entry
). Adın bazı bölümlerini belirtmezseniz, Dtrace o bölümü joker karakter olarak uygular.
DTrace'i probeleri etkinleştirmek ve ateşlendiklerinde hangi eylemlerin gerçekleştirileceğini belirtmek için D dilini kullanmamız gerekecek.
Daha ayrıntılı bir açıklama ve daha fazla örnek için https://illumos.org/books/dtrace/chp-intro.html adresine bakabilirsiniz.
Mevcut DTrace betiklerini listelemek için man -k dtrace
komutunu çalıştırın. Örnek: sudo dtruss -n binary
betik
Bu, bir çekirdek izleme aracıdır. Belgelendirilmiş kodlar /usr/share/misc/trace.codes
içinde bulunabilir.
latency
, sc_usage
, fs_usage
ve trace
gibi araçlar bunu dahili olarak kullanır.
kdebug
ile etkileşim kurmak için sysctl
, kern.kdebug
ad alanı üzerinden kullanılır ve kullanılacak MIB'ler bsd/kern/kdebug.c
içinde uygulanan fonksiyonlarla birlikte sys/sysctl.h
içinde bulunabilir.
Özel bir istemci ile kdebug ile etkileşim kurmak için genellikle bu adımlar izlenir:
KERN_KDSETREMOVE ile mevcut ayarları kaldırın
KERN_KDSETBUF ve KERN_KDSETUP ile izlemeyi ayarlayın
Tampon girişlerinin sayısını almak için KERN_KDGETBUF kullanın
KERN_KDPINDEX ile izlemeyi kendi istemcinizden çıkarın
KERN_KDENABLE ile izlemeyi etkinleştirin
KERN_KDREADTR çağrısını yaparak tamponu okuyun
Her bir iş parçacığını süreciyle eşleştirmek için KERN_KDTHRMAP çağrısını yapın.
Bu bilgiyi almak için Apple aracı trace
veya özel araç kDebugView (kdv)** kullanılabilir.**
Kdebug'un aynı anda yalnızca 1 müşteri için mevcut olduğunu unutmayın. Yani aynı anda yalnızca bir k-debug destekli araç çalıştırılabilir.
ktrace_*
API'leri, Kdebug
'ın sarıldığı libktrace.dylib
'den gelir. Ardından, bir istemci sadece ktrace_session_create
ve ktrace_events_[single/class]
çağrısını yaparak belirli kodlar üzerinde geri çağırmaları ayarlayabilir ve ardından ktrace_start
ile başlatabilir.
Bunu SIP etkinleştirilmişken bile kullanabilirsiniz.
İstemci olarak ktrace
aracını kullanabilirsiniz:
Or tailspin
.
Bu, bir çekirdek düzeyinde profil oluşturmak için kullanılır ve Kdebug
çağrıları ile oluşturulmuştur.
Temelde, global değişken kernel_debug_active
kontrol edilir ve ayarlandığında kperf_kdebug_handler
çağrısı yapılır, Kdebug
kodu ve çağrılan çekirdek çerçevesinin adresi ile. Eğer Kdebug
kodu seçilenlerden biri ile eşleşirse, "hareketler" bir bitmap olarak yapılandırılır (seçenekler için osfmk/kperf/action.h
dosyasına bakın).
Kperf'in ayrıca bir sysctl MIB tablosu vardır: (root olarak) sysctl kperf
. Bu kodlar osfmk/kperf/kperfbsd.c
dosyasında bulunabilir.
Ayrıca, Kperf'in bir alt kümesi kpc
içinde yer alır ve bu, makine performans sayaçları hakkında bilgi sağlar.
ProcessMonitor, bir sürecin gerçekleştirdiği süreçle ilgili eylemleri kontrol etmek için çok yararlı bir araçtır (örneğin, bir sürecin hangi yeni süreçleri oluşturduğunu izlemek).
SpriteTree süreçler arasındaki ilişkileri yazdıran bir araçtır.
Mac'inizi sudo eslogger fork exec rename create > cap.json
gibi bir komutla izlemelisiniz (bunu başlatan terminal FDA gerektirir). Ardından, bu aracı kullanarak json'u yükleyebilir ve tüm ilişkileri görüntüleyebilirsiniz:
FileMonitor, dosya olaylarını (oluşturma, değişiklikler ve silme gibi) izlemeye olanak tanır ve bu tür olaylar hakkında ayrıntılı bilgi sağlar.
Crescendo, Windows kullanıcılarının Microsoft Sysinternal’s Procmon'dan tanıyabileceği bir GUI aracıdır. Bu araç, çeşitli olay türlerinin kaydedilmesini başlatıp durdurmaya, bu olayları dosya, süreç, ağ vb. gibi kategorilere göre filtrelemeye ve kaydedilen olayları json formatında kaydetme işlevselliği sunar.
Apple Instruments, Xcode'un Geliştirici araçlarının bir parçasıdır – uygulama performansını izlemek, bellek sızıntılarını tanımlamak ve dosya sistemi etkinliğini takip etmek için kullanılır.
Süreçler tarafından gerçekleştirilen eylemleri takip etmeye olanak tanır:
Taskexplorer bir ikili dosyanın kullandığı kütüphaneleri, kullandığı dosyaları ve ağ bağlantılarını görmek için faydalıdır. Ayrıca ikili süreçleri virustotal ile kontrol eder ve ikili hakkında bilgi gösterir.
bu blog yazısında SIP devre dışı bırakılmış olsa bile hata ayıklamayı önlemek için PT_DENY_ATTACH
kullanan bir çalışan daemon'u hata ayıklama örneğini bulabilirsiniz.
lldb, macOS ikili hata ayıklama için de facto aracıdır.
Ev dizininizde aşağıdaki satırı içeren .lldbinit
adında bir dosya oluşturarak lldb kullanırken intel çeşidini ayarlayabilirsiniz:
lldb içinde, bir işlemi process save-core
ile dökün
objc_sendMsg
fonksiyonu çağrıldığında, rsi kaydedicisi metodun adını null-terminatlı (“C”) dize olarak tutar. Adı lldb üzerinden yazdırmak için:
(lldb) x/s $rsi: 0x1000f1576: "startMiningWithPort:password:coreCount:slowMemory:currency:"
(lldb) print (char*)$rsi:
(char *) $1 = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"
(lldb) reg read $rsi: rsi = 0x00000001000f1576 "startMiningWithPort:password:coreCount:slowMemory:currency:"
sysctl hw.model
komutu host bir MacOS olduğunda "Mac" döner, ancak bir VM olduğunda farklı bir şey döner.
hw.logicalcpu
ve hw.physicalcpu
değerleriyle oynayarak bazı kötü amaçlı yazılımlar bir VM olup olmadığını tespit etmeye çalışır.
Bazı kötü amaçlı yazılımlar, MAC adresine (00:50:56) dayanarak makinenin VMware olup olmadığını da tespit edebilir.
Basit bir kod ile bir işlemin hata ayıklanıp ayıklanmadığını bulmak da mümkündür:
if(P_TRACED == (info.kp_proc.p_flag & P_TRACED)){ //işlem hata ayıklanıyor }
Ayrıca ptrace
sistem çağrısını PT_DENY_ATTACH
bayrağı ile çağırabilir. Bu, bir hata ayıklayıcının bağlanmasını ve izlenmesini engeller.
sysctl
veya ptrace
fonksiyonunun içe aktarıldığını kontrol edebilirsiniz (ancak kötü amaçlı yazılım bunu dinamik olarak içe aktarabilir).
Bu yazıda belirtildiği gibi, “Anti-Debug Tekniklerini Aşmak: macOS ptrace varyantları” : “Process # exited with status = 45 (0x0000002d) mesajı genellikle hata ayıklama hedefinin PT_DENY_ATTACH kullandığını gösteren bir işarettir”
Core dump'lar şu durumlarda oluşturulur:
kern.coredump
sysctl 1 olarak ayarlanmışsa (varsayılan olarak)
İşlem suid/sgid değilse veya kern.sugid_coredump
1 ise (varsayılan olarak 0)
AS_CORE
limiti işlemi izin veriyorsa. Kod dump'larının oluşturulmasını engellemek için ulimit -c 0
çağrılabilir ve yeniden etkinleştirmek için ulimit -c unlimited
kullanılabilir.
Bu durumlarda core dump, kern.corefile
sysctl'e göre oluşturulur ve genellikle /cores/core/.%P
dizininde saklanır.
ReportCrash çöken işlemleri analiz eder ve bir çökme raporunu diske kaydeder. Bir çökme raporu, bir geliştiricinin çökme nedenini teşhis etmesine yardımcı olabilecek bilgileri içerir.
Kullanıcı başına launchd bağlamında çalışan uygulamalar ve diğer işlemler için, ReportCrash bir LaunchAgent olarak çalışır ve çökme raporlarını kullanıcının ~/Library/Logs/DiagnosticReports/
dizinine kaydeder.
Daimonlar, sistem launchd bağlamında çalışan diğer işlemler ve diğer ayrıcalıklı işlemler için, ReportCrash bir LaunchDaemon olarak çalışır ve çökme raporlarını sistemin /Library/Logs/DiagnosticReports
dizinine kaydeder.
Eğer çökme raporlarının Apple'a gönderilmesinden endişe ediyorsanız, bunları devre dışı bırakabilirsiniz. Aksi takdirde, çökme raporları bir sunucunun nasıl çöktüğünü anlamak için faydalı olabilir.
MacOS'ta fuzzing yaparken Mac'in uykuya dalmasına izin vermemek önemlidir:
systemsetup -setsleep Never
pmset, Sistem Tercihleri
Eğer bir SSH bağlantısı üzerinden fuzzing yapıyorsanız, oturumun kapanmayacağından emin olmak önemlidir. Bu nedenle sshd_config dosyasını şu şekilde değiştirin:
TCPKeepAlive Yes
ClientAliveInterval 0
ClientAliveCountMax 0
Aşağıdaki sayfayı kontrol edin hangi uygulamanın belirtilen şemayı veya protokolü işlemekten sorumlu olduğunu bulmak için:
Ağ verilerini yöneten süreçleri bulmak ilginçtir:
Or use netstat
or lsof
CLI araçları için çalışır.
macOS GUI araçlarıyla "sadece çalışır". Bazı macOS uygulamalarının benzersiz dosya adları, doğru uzantı gibi belirli gereksinimleri olduğunu unutmayın, dosyaları sandbox'tan (~/Library/Containers/com.apple.Safari/Data
) okumaları gerekir...
Bazı örnekler:
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Eğitim AWS Kırmızı Ekip Uzmanı (ARTE) GCP Hacking'i öğrenin ve pratik yapın: HackTricks Eğitim GCP Kırmızı Ekip Uzmanı (GRTE)
Argument
Register
(for) objc_msgSend
1st argument
rdi
self: methodun çağrıldığı nesne
2nd argument
rsi
op: metodun adı
3rd argument
rdx
metodun 1. argümanı
4th argument
rcx
metodun 2. argümanı
5th argument
r8
metodun 3. argümanı
6th argument
r9
metodun 4. argümanı
7th+ argument
rsp+ (stack'te)
metodun 5. ve sonrası argümanları
(lldb) Komut
Açıklama
run (r)
Bir kesme noktası vurulana veya işlem sona erene kadar devam edecek şekilde yürütmeyi başlatır.
process launch --stop-at-entry
Giriş noktasında durarak yürütmeyi başlatır
continue (c)
Hata ayıklanan işlemin yürütülmesine devam eder.
nexti (n / ni)
Sonraki talimatı yürütür. Bu komut, işlev çağrılarını atlar.
stepi (s / si)
Sonraki talimatı yürütür. nexti komutunun aksine, bu komut işlev çağrılarına adım atar.
finish (f)
Mevcut işlevdeki (“çerçeve”) geri kalan talimatları yürütür, döner ve durur.
control + c
Yürütmeyi duraklatır. İşlem run (r) veya continue (c) ile çalıştırıldıysa, bu işlem durmasına neden olur ...şu anda yürütüldüğü yerde.
breakpoint (b)
b main
#Herhangi bir main adlı işlev
b <binname>`main
#Bin'in ana işlevi
b set -n main --shlib <lib_name>
#Belirtilen binin ana işlevi
breakpoint set -r '\[NSFileManager .*\]$'
#Herhangi bir NSFileManager yöntemi
breakpoint set -r '\[NSFileManager contentsOfDirectoryAtPath:.*\]$'
break set -r . -s libobjc.A.dylib
# O kütüphanedeki tüm işlevlerde kesme noktası
b -a 0x0000000100004bd9
br l
#Kesme noktası listesi
br e/dis <num>
#Kesme noktasını etkinleştir/etkisiz hale getir
breakpoint delete <num>
help
help breakpoint #Kesme noktası komutu hakkında yardım al
help memory write #Belleğe yazma hakkında yardım al
reg
x/s <reg/bellek adresi>
Belleği null-terminatlı dize olarak görüntüler.
x/i <reg/bellek adresi>
Belleği montaj talimatı olarak görüntüler.
x/b <reg/bellek adresi>
Belleği byte olarak görüntüler.
print object (po)
Bu, parametre ile referans verilen nesneyi yazdırır
po $raw
{
dnsChanger = {
"affiliate" = "";
"blacklist_dns" = ();
Apple’ın Objective-C API'lerinin veya yöntemlerinin çoğu nesne döndürdüğünden, bunlar “print object” (po) komutu ile görüntülenmelidir. Eğer po anlamlı bir çıktı üretmiyorsa x/b
kullanın
memory
memory read 0x000.... memory read $x0+0xf2a memory write 0x100600000 -s 4 0x41414141 #O adrese AAAA yaz memory write -f s $rip+0x11f+7 "AAAA" #Adrese AAAA yaz
disassembly
dis #Mevcut işlevi disassemble et
dis -n <funcname> #İşlevi disassemble et
dis -n <funcname> -b <basename> #İşlevi disassemble et dis -c 6 #6 satırı disassemble et dis -c 0x100003764 -e 0x100003768 #Bir eklemden diğerine kadar dis -p -c 4 #Mevcut adreste disassemble etmeye başla
parray
parray 3 (char **)$x1 # x1 reg'deki 3 bileşenli diziyi kontrol et
image dump sections
Mevcut işlem belleğinin haritasını yazdırır
image dump symtab <library>
image dump symtab CoreNLP
#CoreNLP'den tüm sembollerin adresini al