macOS Universal binaries & Mach-O Format
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Mac OS binaries kwa kawaida zinakusanywa kama universal binaries. Universal binary inaweza kuunga mkono usanifu mwingi katika faili moja.
Binaries hizi zinafuata Mach-O structure ambayo kimsingi inajumuisha:
Header
Load Commands
Data
Tafuta faili kwa: mdfind fat.h | grep -i mach-o | grep -E "fat.h$"
Header ina magic bytes ikifuatiwa na idadi ya archs faili inayo (nfat_arch
) na kila arch itakuwa na fat_arch
struct.
Angalia kwa:
au kwa kutumia zana ya Mach-O View:
Kama unavyofikiria kawaida universal binary iliyokusanywa kwa usanifu 2 inaongeza ukubwa wa moja iliyokusanywa kwa usanifu 1 tu.
Header ina taarifa za msingi kuhusu faili, kama vile magic bytes kutambua kama faili la Mach-O na taarifa kuhusu usanifu wa lengo. Unaweza kuipata katika: mdfind loader.h | grep -i mach-o | grep -E "loader.h$"
Kuna aina tofauti za faili, unaweza kuziona zikifafanuliwa katika kanuni ya chanzo kwa mfano hapa. Zile muhimu zaidi ni:
MH_OBJECT
: Faili ya kitu inayoweza kuhamishwa (bidhaa za kati za uundaji, bado si executable).
MH_EXECUTE
: Faili zinazoweza kutekelezwa.
MH_FVMLIB
: Faili ya maktaba ya VM iliyowekwa.
MH_CORE
: Mifumo ya Kanuni
MH_PRELOAD
: Faili ya executable iliyopakiwa mapema (haipati tena msaada katika XNU)
MH_DYLIB
: Maktaba za Kijadi
MH_DYLINKER
: Mshikamano wa Kijadi
MH_BUNDLE
: "Faili za Plugin". Zilizozalishwa kwa kutumia -bundle katika gcc na kupakiwa wazi na NSBundle
au dlopen
.
MH_DYSM
: Faili ya mshirika .dSym
(faili yenye alama za kutatua matatizo).
MH_KEXT_BUNDLE
: Nyongeza za Kernel.
Or using Mach-O View:
Msimbo wa chanzo pia unafafanua bendera kadhaa zinazofaa kwa ajili ya kupakia maktaba:
MH_NOUNDEFS
: Hakuna marejeleo yasiyofafanuliwa (imeunganishwa kikamilifu)
MH_DYLDLINK
: Kuunganisha Dyld
MH_PREBOUND
: Marejeleo ya dinamik yanayofungwa mapema.
MH_SPLIT_SEGS
: Faili inagawanya sehemu r/o na r/w.
MH_WEAK_DEFINES
: Binary ina alama zisizofafanuliwa dhaifu
MH_BINDS_TO_WEAK
: Binary inatumia alama dhaifu
MH_ALLOW_STACK_EXECUTION
: Fanya stack iweze kutekelezwa
MH_NO_REEXPORTED_DYLIBS
: Maktaba haina amri za LC_REEXPORT
MH_PIE
: Mtendaji Huru wa Nafasi
MH_HAS_TLV_DESCRIPTORS
: Kuna sehemu yenye mabadiliko ya nyuzi za ndani
MH_NO_HEAP_EXECUTION
: Hakuna utekelezaji kwa kurasa za heap/data
MH_HAS_OBJC
: Binary ina sehemu za oBject-C
MH_SIM_SUPPORT
: Msaada wa simulator
MH_DYLIB_IN_CACHE
: Inatumika kwenye dylibs/frameworks katika cache ya maktaba ya pamoja.
Muundo wa faili katika kumbukumbu umefafanuliwa hapa, ukielezea mahali pa jedwali la alama, muktadha wa nyuzi kuu wakati wa kuanza utekelezaji, na maktaba za pamoja zinazohitajika. Maagizo yanatolewa kwa mzigo wa dinamik (dyld) kuhusu mchakato wa kupakia binary katika kumbukumbu.
Inatumia muundo wa load_command, uliofafanuliwa katika loader.h
:
There are about 50 different types of load commands that the system handles differently. The most common ones are: LC_SEGMENT_64
, LC_LOAD_DYLINKER
, LC_MAIN
, LC_LOAD_DYLIB
, and LC_CODE_SIGNATURE
.
Kimsingi, aina hii ya Load Command inaelezea jinsi ya kupakia __TEXT (kanuni inayotekelezeka) na __DATA (data kwa ajili ya mchakato) sehemu kulingana na offsets zilizotajwa katika sehemu ya Data wakati binary inatekelezwa.
These commands define segments that are mapped into the virtual memory space of a process when it is executed.
There are different types of segments, such as the __TEXT segment, which holds the executable code of a program, and the __DATA segment, which contains data used by the process. These segments are located in the data section of the Mach-O file.
Each segment can be further divided into multiple sections. The load command structure contains information about these sections within the respective segment.
In the header first you find the segment header:
Example of segment header:
This header defines the number of sections whose headers appear after it:
Example of section header:
Ikiwa un ongeza section offset (0x37DC) + offset ambapo arch inaanza, katika kesi hii 0x18000
--> 0x37DC + 0x18000 = 0x1B7DC
Pia inawezekana kupata headers information kutoka kwa command line na:
Common segments loaded by this cmd:
__PAGEZERO
: Instructs the kernel to map the address zero so it cannot be read from, written to, or executed. The maxprot and minprot variables in the structure are set to zero to indicate there are no read-write-execute rights on this page.
This allocation is important to mitigate NULL pointer dereference vulnerabilities. This is because XNU enforces a hard page zero that ensures the first page (only the first) of memory is inaccessible (except in i386). A binary could fulfill this requirement by crafting a small __PAGEZERO (using the -pagezero_size
) to cover the first 4k and having the rest of 32bit memory accessible in both user and kernel mode.
__TEXT
: Contains executable code with read and execute permissions (no writable). Common sections of this segment:
__text
: Compiled binary code
__const
: Data ya kudumu (read only)
__[c/u/os_log]string
: C, Unicode au os logs string constants
__stubs
and __stubs_helper
: Involved during the dynamic library loading process
__unwind_info
: Takwimu za stack unwind.
Note that all this content is signed but also marked as executable (creating more options for exploitation of sections that doesn't necessarily need this privilege, like string dedicated sections).
__DATA
: Inahusisha data ambayo ni readable na writable (no executable).
__got:
Global Offset Table
__nl_symbol_ptr
: Non lazy (bind at load) symbol pointer
__la_symbol_ptr
: Lazy (bind on use) symbol pointer
__const
: Inapaswa kuwa data ya kusoma tu (sio kweli)
__cfstring
: CoreFoundation strings
__data
: Global variables (ambazo zimeanzishwa)
__bss
: Static variables (ambazo hazijaanzishwa)
__objc_*
(__objc_classlist, __objc_protolist, nk): Taarifa inayotumiwa na Objective-C runtime
__DATA_CONST
: __DATA.__const haikuhakikishiwa kuwa ya kudumu (write permissions), wala viashiria vingine na GOT. Sehemu hii inafanya __const
, baadhi ya waanzilishi na meza ya GOT (mara tu inapohakikishwa) read only kwa kutumia mprotect
.
__LINKEDIT
: Inahusisha taarifa kwa linker (dyld) kama, alama, string, na entries za relocation table. Ni chombo cha jumla kwa maudhui ambayo hayapo katika __TEXT
au __DATA
na maudhui yake yanaelezewa katika amri nyingine za upakiaji.
taarifa za dyld: Rebase, Non-lazy/lazy/weak binding opcodes na taarifa za usafirishaji
Functions starts: Meza ya anwani za kuanzia za kazi
Data In Code: Data islands katika __text
SYmbol Table: Alama katika binary
Indirect Symbol Table: Pointer/stub symbols
String Table
Code Signature
__OBJC
: Inahusisha taarifa inayotumiwa na Objective-C runtime. Ingawa taarifa hii inaweza pia kupatikana katika sehemu ya __DATA, ndani ya sehemu mbalimbali za __objc_*.
__RESTRICT
: Sehemu isiyo na maudhui yenye sehemu moja inayoitwa __restrict
(pia tupu) ambayo inahakikisha kwamba wakati wa kuendesha binary, itapuuzilia mbali mabadiliko ya mazingira ya DYLD.
Kama ilivyokuwa inawezekana kuona katika msimbo, sehemu pia zinaunga mkono bendera (ingawa hazitumiki sana):
SG_HIGHVM
: Core tu (haijatumiwa)
SG_FVMLIB
: Haijatumiwa
SG_NORELOC
: Sehemu haina relocation
SG_PROTECTED_VERSION_1
: Ulinzi. Inatumika kwa mfano na Finder kupeleka maandiko ya sehemu ya __TEXT
.
LC_UNIXTHREAD/LC_MAIN
LC_MAIN
ina kiingilio katika entryoff attribute. Wakati wa upakiaji, dyld kwa urahisi ongeza thamani hii kwa (katika kumbukumbu) msingi wa binary, kisha jump kwa hii amri kuanza utekelezaji wa msimbo wa binary.
LC_UNIXTHREAD
ina thamani ambazo register lazima iwe nazo wakati wa kuanzisha thread kuu. Hii tayari ilikuwa imeondolewa lakini dyld
bado inaitumia. Inawezekana kuona thamani za register zilizowekwa na hii kwa:
LC_CODE_SIGNATURE
Inashikilia taarifa kuhusu sahihi ya msimbo wa faili ya Macho-O. Inashikilia tu offset inayopointia signature blob. Hii kwa kawaida iko mwishoni mwa faili. Hata hivyo, unaweza kupata taarifa fulani kuhusu sehemu hii katika hiki kipande cha blog na hii gists.
LC_ENCRYPTION_INFO[_64]
Msaada wa usimbuaji wa binary. Hata hivyo, bila shaka, ikiwa mshambuliaji atafanikiwa kuathiri mchakato, ataweza kutupa kumbukumbu bila usimbuaji.
LC_LOAD_DYLINKER
Inashikilia njia ya executable ya dynamic linker inayopanga maktaba za pamoja katika nafasi ya anwani ya mchakato. Thamani kila wakati imewekwa kwenye /usr/lib/dyld
. Ni muhimu kutambua kwamba katika macOS, uhamasishaji wa dylib unafanyika katika mode ya mtumiaji, si katika mode ya kernel.
LC_IDENT
Imepitwa na wakati lakini wakati imewekwa ili kuunda dumps wakati wa panic, dump ya Mach-O core inaundwa na toleo la kernel linawekwa katika amri ya LC_IDENT
.
LC_UUID
UUID ya nasibu. Ni muhimu kwa chochote moja kwa moja lakini XNU inahifadhi pamoja na taarifa nyingine za mchakato. Inaweza kutumika katika ripoti za ajali.
LC_DYLD_ENVIRONMENT
Inaruhusu kuashiria mabadiliko ya mazingira kwa dyld kabla ya mchakato kutekelezwa. Hii inaweza kuwa hatari sana kwani inaweza kuruhusu kutekeleza msimbo usio na mipaka ndani ya mchakato hivyo amri hii ya kupakia inatumika tu katika ujenzi wa dyld na #define SUPPORT_LC_DYLD_ENVIRONMENT
na inazidisha mchakato tu kwa mabadiliko ya aina DYLD_..._PATH
yanayoelezea njia za kupakia.
LC_LOAD_DYLIB
Amri hii ya kupakia inaelezea utegemezi wa maktaba dynamiki ambayo inaelekeza loader (dyld) kupakia na kuunganisha maktaba hiyo. Kuna amri ya kupakia LC_LOAD_DYLIB
kwa kila maktaba ambayo binary ya Mach-O inahitaji.
Amri hii ya kupakia ni muundo wa aina dylib_command
(ambayo ina muundo wa dylib, unaelezea maktaba halisi ya dinamik):
Unaweza pia kupata habari hii kutoka kwenye cli kwa:
Some potential malware related libraries are:
DiskArbitration: Monitoring USB drives
AVFoundation: Capture audio and video
CoreWLAN: Wifi scans.
A Mach-O binary can contain one or more constructors, that will be executed before the address specified in LC_MAIN. The offsets of any constructors are held in the __mod_init_func section of the __DATA_CONST segment.
At the core of the file lies the data region, which is composed of several segments as defined in the load-commands region. A variety of data sections can be housed within each segment, with each section holding code or data specific to a type.
The data is basically the part containing all the information that is loaded by the load commands LC_SEGMENTS_64
This includes:
Function table: Which holds information about the program functions.
Symbol table: Which contains information about the external function used by the binary
It could also contain internal function, variable names as well and more.
To check it you could use the Mach-O View tool:
Or from the cli:
Katika sehemu ya __TEXT
(r-x):
__objc_classname
: Majina ya darasa (nyuzi)
__objc_methname
: Majina ya mbinu (nyuzi)
__objc_methtype
: Aina za mbinu (nyuzi)
Katika sehemu ya __DATA
(rw-):
__objc_classlist
: Viashiria kwa madarasa yote ya Objetive-C
__objc_nlclslist
: Viashiria kwa madarasa ya Objective-C yasiyo na uvivu
__objc_catlist
: Kiashiria kwa Kategoria
__objc_nlcatlist
: Kiashiria kwa Kategoria zisizo na uvivu
__objc_protolist
: Orodha ya protokali
__objc_const
: Takwimu za kudumu
__objc_imageinfo
, __objc_selrefs
, objc__protorefs
...
_swift_typeref
, _swift3_capture
, _swift3_assocty
, _swift3_types, _swift3_proto
, _swift3_fieldmd
, _swift3_builtin
, _swift3_reflstr
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)