mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-15 01:17:36 +00:00
GITBOOK-4322: No subject
This commit is contained in:
parent
2221c23349
commit
cef895c028
1 changed files with 106 additions and 13 deletions
|
@ -113,11 +113,20 @@ struct mach_header_64 {
|
|||
};
|
||||
```
|
||||
|
||||
**Filetypes**:
|
||||
### Mach-O File Types
|
||||
|
||||
* MH\_EXECUTE (0x2): Standard Mach-O executable
|
||||
* MH\_DYLIB (0x6): A Mach-O dynamic linked library (i.e. .dylib)
|
||||
* MH\_BUNDLE (0x8): A Mach-O bundle (i.e. .bundle)
|
||||
There are different file types, you can find them defined in the [**source code for example here**](https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL\_HEADERS/mach-o/loader.h). The most important ones are:
|
||||
|
||||
* `MH_OBJECT`: Relocatable object file (intermediate products of compilation, not executables yet).
|
||||
* `MH_EXECUTE`: Executable files.
|
||||
* `MH_FVMLIB`: Fixed VM library file.
|
||||
* `MH_CORE`: Code Dumps
|
||||
* `MH_PRELOAD`: Preloaded executable file (no longer supported in XNU)
|
||||
* `MH_DYLIB`: Dynamic Libraries
|
||||
* `MH_DYLINKER`: Dynamic Linker
|
||||
* `MH_BUNDLE`: "Plugin files". Generated using -bundle in gcc and explicitly loaded by `NSBundle` or `dlopen`.
|
||||
* `MH_DYSM`: Companion `.dSym` file (file with symbols for debugging).
|
||||
* `MH_KEXT_BUNDLE`: Kernel Extensions.
|
||||
|
||||
```bash
|
||||
# Checking the mac header of a binary
|
||||
|
@ -131,6 +140,25 @@ Or using [Mach-O View](https://sourceforge.net/projects/machoview/):
|
|||
|
||||
<figure><img src="../../../.gitbook/assets/image (1130).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## **Mach-O Flags**
|
||||
|
||||
The source code also defines several flags useful for loading libraries:
|
||||
|
||||
* `MH_NOUNDEFS`: No undefined references (fully linked)
|
||||
* `MH_DYLDLINK`: Dyld linking
|
||||
* `MH_PREBOUND`: Dynamic references prebound.
|
||||
* `MH_SPLIT_SEGS`: File splits r/o and r/w segments.
|
||||
* `MH_WEAK_DEFINES`: Binary has weak defined symbols
|
||||
* `MH_BINDS_TO_WEAK`: Binary uses weak symbols
|
||||
* `MH_ALLOW_STACK_EXECUTION`: Make the stack executable
|
||||
* `MH_NO_REEXPORTED_DYLIBS`: Library not LC\_REEXPORT commands
|
||||
* `MH_PIE`: Position Independent Executable
|
||||
* `MH_HAS_TLV_DESCRIPTORS`: There is a section with thread local variables
|
||||
* `MH_NO_HEAP_EXECUTION`: No execution for heap/data pages
|
||||
* `MH_HAS_OBJC`: Binary has oBject-C sections
|
||||
* `MH_SIM_SUPPORT`: Simulator support
|
||||
* `MH_DYLIB_IN_CACHE`: Used on dylibs/frameworks in shared library cache.
|
||||
|
||||
## **Mach-O Load commands**
|
||||
|
||||
The **file's layout in memory** is specified here, detailing the **symbol table's location**, the context of the main thread at execution start, and the required **shared libraries**. Instructions are provided to the dynamic loader **(dyld)** on the binary's loading process into memory.
|
||||
|
@ -215,35 +243,100 @@ otool -lv /bin/ls
|
|||
Common segments loaded by this cmd:
|
||||
|
||||
* **`__PAGEZERO`:** It 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 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 innaccesible (except in i386). A binary could fulfil this requirements 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`: Constant data
|
||||
* `__cstring`: String constants
|
||||
* `__const`: Constant data (read only)
|
||||
* `__[c/u/os_log]string`: C, Unicode or os logs string constants
|
||||
* `__stubs` and `__stubs_helper`: Involved during the dynamic library loading process
|
||||
* `__unwind_info`: Stack unwind data.
|
||||
* 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`**: Contains data that is **readable** and **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`: Should be read-only data (not really)
|
||||
* `__cfstring`: CoreFoundation strings
|
||||
* `__data`: Global variables (that have been initialized)
|
||||
* `__bss`: Static variables (that have not been initialized)
|
||||
* `__objc_*` (\_\_objc\_classlist, \_\_objc\_protolist, etc): Information used by the Objective-C runtime
|
||||
* **`__LINKEDIT`**: Contains information for the linker (dyld) such as, "symbol, string, and relocation table entries."
|
||||
* **`__DATA_CONST`**: \_\_DATA.\_\_const is not guaranteed to be constant (write permissions), nor are other pointers and the GOT. This section makes `__const`, some initializers and the GOT table (once resolved) **read only** using `mprotect`.
|
||||
* **`__LINKEDIT`**: Contains information for the linker (dyld) such as, symbol, string, and relocation table entries. It' a generic container for contents that are neither in `__TEXT` or `__DATA` and its content is decribed in other load commands.
|
||||
* dyld information: Rebase, Non-lazy/lazy/weak binding opcodes and export info
|
||||
* Functions starts: Table of start addresses of functions
|
||||
* Data In Code: Data islands in \_\_text
|
||||
* SYmbol Table: Symbols in binary
|
||||
* Indirect Symbol Table: Pointer/stub symbols
|
||||
* String Table
|
||||
* Code Signature
|
||||
* **`__OBJC`**: Contains information used by the Objective-C runtime. Though this information might also be found in the \_\_DATA segment, within various in \_\_objc\_\* sections.
|
||||
* **`__RESTRICT`**: A segment without content with a single section called **`__restrict`** (also empty) that ensures that when running the binary, it will ignore DYLD environmental variables.
|
||||
|
||||
### **`LC_MAIN`**
|
||||
As it was possible to see in the code, **segments also support flags** (although they aren't used very much):
|
||||
|
||||
Contains the entrypoint in the **entryoff attribute.** At load time, **dyld** simply **adds** this value to the (in-memory) **base of the binary**, then **jumps** to this instruction to start execution of the binary’s code.
|
||||
* `SG_HIGHVM`: Core only (not used)
|
||||
* `SG_FVMLIB`: Not used
|
||||
* `SG_NORELOC`: Segment has no relocation
|
||||
* `SG_PROTECTED_VERSION_1`: Encryption. Used for example by Finder to encrypt text `__TEXT` segment.
|
||||
|
||||
### **LC\_CODE\_SIGNATURE**
|
||||
### **`LC_UNIXTHREAD/LC_MAIN`**
|
||||
|
||||
**`LC_MAIN`** contains the entrypoint in the **entryoff attribute.** At load time, **dyld** simply **adds** this value to the (in-memory) **base of the binary**, then **jumps** to this instruction to start execution of the binary’s code.
|
||||
|
||||
**`LC_UNIXTHREAD`** contains the values the register must have when starting the main thread. This was already deprecated but **`dyld`** still uses it. It's possible to see the vlaues of the registers set by this with:
|
||||
|
||||
```bash
|
||||
otool -l /usr/lib/dyld
|
||||
[...]
|
||||
Load command 13
|
||||
cmd LC_UNIXTHREAD
|
||||
cmdsize 288
|
||||
flavor ARM_THREAD_STATE64
|
||||
count ARM_THREAD_STATE64_COUNT
|
||||
x0 0x0000000000000000 x1 0x0000000000000000 x2 0x0000000000000000
|
||||
x3 0x0000000000000000 x4 0x0000000000000000 x5 0x0000000000000000
|
||||
x6 0x0000000000000000 x7 0x0000000000000000 x8 0x0000000000000000
|
||||
x9 0x0000000000000000 x10 0x0000000000000000 x11 0x0000000000000000
|
||||
x12 0x0000000000000000 x13 0x0000000000000000 x14 0x0000000000000000
|
||||
x15 0x0000000000000000 x16 0x0000000000000000 x17 0x0000000000000000
|
||||
x18 0x0000000000000000 x19 0x0000000000000000 x20 0x0000000000000000
|
||||
x21 0x0000000000000000 x22 0x0000000000000000 x23 0x0000000000000000
|
||||
x24 0x0000000000000000 x25 0x0000000000000000 x26 0x0000000000000000
|
||||
x27 0x0000000000000000 x28 0x0000000000000000 fp 0x0000000000000000
|
||||
lr 0x0000000000000000 sp 0x0000000000000000 pc 0x0000000000004b70
|
||||
cpsr 0x00000000
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
### **`LC_CODE_SIGNATURE`**
|
||||
|
||||
Contains information about the **code signature of the Macho-O file**. It only contains an **offset** that **points** to the **signature blob**. This is typically at the very end of the file.\
|
||||
However, you can find some information about this section in [**this blog post**](https://davedelong.com/blog/2018/01/10/reading-your-own-entitlements/) and this [**gists**](https://gist.github.com/carlospolop/ef26f8eb9fafd4bc22e69e1a32b81da4).
|
||||
|
||||
### **LC\_LOAD\_DYLINKER**
|
||||
### **`LC_ENCRYPTION_INFO[_64]`**
|
||||
|
||||
Support for binary encryption. However, of course, if an attacker manages to compromise the process, he will be able to dump the memory unencrypted.
|
||||
|
||||
### **`LC_LOAD_DYLINKER`**
|
||||
|
||||
Contains the **path to the dynamic linker executable** that maps shared libraries into the process address space. The **value is always set to `/usr/lib/dyld`**. It’s important to note that in macOS, dylib mapping happens in **user mode**, not in kernel mode.
|
||||
|
||||
### **`LC_IDENT`**
|
||||
|
||||
Obsolete but when configured to geenrate dumps on panic, a Mach-O core dump is created and the kernel version is set in the `LC_IDENT` command.
|
||||
|
||||
### **`LC_UUID`**
|
||||
|
||||
Random UUID. It's useful for anything directly but XNU caches it with the rest of the process info. It can be used in crash reports.
|
||||
|
||||
### **`LC_DYLD_ENVIRONMENT`**
|
||||
|
||||
Allows to indicate environment variables to the dyld beforenthe process is executed. This can be vary dangerous as it can allow to execute arbitrary code inside the process so this load command is only used in dyld build with `#define SUPPORT_LC_DYLD_ENVIRONMENT` and further restricts processing only to variables of the form `DYLD_..._PATH` specifying load paths.
|
||||
|
||||
### **`LC_LOAD_DYLIB`**
|
||||
|
||||
This load command describes a **dynamic** **library** dependency which **instructs** the **loader** (dyld) to **load and link said library**. There is a LC\_LOAD\_DYLIB load command **for each library** that the Mach-O binary requires.
|
||||
This load command describes a **dynamic** **library** dependency which **instructs** the **loader** (dyld) to **load and link said library**. There is a `LC_LOAD_DYLIB` load command **for each library** that the Mach-O binary requires.
|
||||
|
||||
* This load command is a structure of type **`dylib_command`** (which contains a struct dylib, describing the actual dependent dynamic library):
|
||||
|
||||
|
|
Loading…
Reference in a new issue