diff --git a/src/macos-hardening/macos-auto-start-locations.md b/src/macos-hardening/macos-auto-start-locations.md index 2f30ed74433..30957688572 100644 --- a/src/macos-hardening/macos-auto-start-locations.md +++ b/src/macos-hardening/macos-auto-start-locations.md @@ -213,6 +213,8 @@ To **add an application to this list** you can use: ### Terminal Preferences +Writeup: [https://theevilbit.github.io/beyond/beyond_0020/](https://theevilbit.github.io/beyond/beyond_0020/) + - Useful to bypass sandbox: [βœ…](https://emojipedia.org/check-mark-button) - TCC bypass: [βœ…](https://emojipedia.org/check-mark-button) - Terminal use to have FDA permissions of the user use it @@ -340,7 +342,7 @@ According to the previous writeups it's possible to **compile some audio plugins ### QuickLook Plugins -Writeup: [https://theevilbit.github.io/beyond/beyond_0028/](https://theevilbit.github.io/beyond/beyond_0028/) +Writeup: [https://theevilbit.github.io/beyond/beyond_0012/](https://theevilbit.github.io/beyond/beyond_0012/) - Useful to bypass sandbox: [βœ…](https://emojipedia.org/check-mark-button) - TCC bypass: [🟠](https://emojipedia.org/large-orange-circle) @@ -1496,7 +1498,7 @@ touch /tmp/manconf ### Apache2 -**Writeup**: [https://theevilbit.github.io/beyond/beyond_0023/](https://theevilbit.github.io/beyond/beyond_0023/) +**Writeup**: [https://theevilbit.github.io/beyond/beyond_0025/](https://theevilbit.github.io/beyond/beyond_0025/) - Useful to bypass sandbox: [🟠](https://emojipedia.org/large-orange-circle) - But you need to be root and apache needs to be running diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md index 5dcd50ce388..a4ba4c5953f 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-gcd-grand-central-dispatch.md @@ -220,7 +220,10 @@ Ghidra will automatically rewrite everything: ## References -- [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) +- [libdispatch β€” `src/queue.c` (queue/thread-pool implementation)](https://github.com/apple-oss-distributions/libdispatch/blob/main/src/queue.c) +- [libdispatch β€” `src/source.c` (dispatch sources)](https://github.com/apple-oss-distributions/libdispatch/blob/main/src/source.c) +- [libdispatch β€” `dispatch/queue.h` (public queue API)](https://github.com/apple-oss-distributions/libdispatch/blob/main/dispatch/queue.h) +- [Apple Developer β€” Dispatch](https://developer.apple.com/documentation/dispatch) {{#include ../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md index 0d4cdeea617..53ca4ff642b 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-privilege-escalation.md @@ -355,35 +355,13 @@ Multiple Apple daemons accept **NSPredicate** objects over XPC and only validate ### CVE-2020-9771 - mount_apfs TCC bypass and privilege escalation -**Any user** (even unprivileged ones) can create and mount a time machine snapshot an **access ALL the files** of that snapshot.\ -The **only privileged** needed is for the application used (like `Terminal`) to have **Full Disk Access** (FDA) access (`kTCCServiceSystemPolicyAllfiles`) which need to be granted by an admin. +**Any user** (even unprivileged ones) can create and mount a Time Machine snapshot with `-o noowners` and **access ALL the files** of that snapshot, bypassing the ownership checks on the live volume. The only privilege needed is for the application used (like `Terminal`) to have **Full Disk Access** (`kTCCServiceSystemPolicyAllfiles`). -
-Mount Time Machine snapshot - -```bash -# Create snapshot -tmutil localsnapshot - -# List snapshots -tmutil listlocalsnapshots / -Snapshots for disk /: -com.apple.TimeMachine.2023-05-29-001751.local - -# Generate folder to mount it -cd /tmp # I didn it from this folder -mkdir /tmp/snap - -# Mount it, "noowners" will mount the folder so the current user can access everything -/sbin/mount_apfs -o noowners -s com.apple.TimeMachine.2023-05-29-001751.local /System/Volumes/Data /tmp/snap +The commands and the full explanation are in the TCC bypasses page: -# Access it -ls /tmp/snap/Users/admin_user # This will work -``` - -
- -A more detailed explanation can be [**found in the original report**](https://theevilbit.github.io/posts/cve_2020_9771/)**.** +{{#ref}} +macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md +{{#endref}} ## Sensitive Information diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/README.md index 7bc97b16bcf..a593c6ab5db 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/README.md @@ -267,12 +267,12 @@ Note that executables compiled with **`pyinstaller`** won't use these environmen ### Shield -[**Shield**](https://theevilbit.github.io/shield/) ([**Github**](https://github.com/theevilbit/Shield)) is an open source application that can **detect and block process injection** actions: +[**Shield**](https://github.com/theevilbit/Shield) is an open source **EndpointSecurity**-based application that detects and blocks process injection. It is a good reference for which signals are actually observable from ES, since it alerts on: -- Using **Environmental Variables**: It will monitor the presence of any of the following environmental variables: **`DYLD_INSERT_LIBRARIES`**, **`CFNETWORK_LIBRARY_PATH`**, **`RAWCAMERA_BUNDLE_PATH`** and **`ELECTRON_RUN_AS_NODE`** -- Using **`task_for_pid`** calls: To find when one process wants to get the **task port of another** which allows to inject code in the process. -- **Electron apps params**: Someone can use **`--inspect`**, **`--inspect-brk`** and **`--remote-debugging-port`** command line argument to start an Electron app in debugging mode, and thus inject code to it. -- Using **symlinks** or **hardlinks**: Typically the most common abuse is to **place a link with our user privileges**, and **point it to a higher privilege** location. The detection is very simple for both hardlink and symlinks. If the process creating the link has a **different privilege level** than the target file, we create an **alert**. Unfortunately in the case of symlinks blocking is not possible, as we don’t have information about the destination of the link prior creation. This is a limitation of Apple’s EndpointSecuriy framework. +- **Injection environment variables** on process exec: `DYLD_INSERT_LIBRARIES`, `CFNETWORK_LIBRARY_PATH`, `RAWCAMERA_BUNDLE_PATH` and `ELECTRON_RUN_AS_NODE`. +- **`task_for_pid`** calls β€” one process asking for another's task port, which is the prerequisite for injecting into it. +- **Electron debugging arguments** β€” `--inspect`, `--inspect-brk` and `--remote-debugging-port`, which start an Electron app in debug mode and let anyone attach and run code in it. +- **Symlink/hardlink creation across privilege levels** β€” the classic "plant a link as a normal user, point it at a privileged location" primitive. Note that **symlinks can be alerted on but not blocked**: EndpointSecurity does not expose the link destination before creation. ### Calls made by other processes @@ -282,7 +282,8 @@ Note that to call that function you need to be **the same uid** as the one runni ## References -- [https://theevilbit.github.io/shield/](https://theevilbit.github.io/shield/) +- [Shield β€” open source macOS process-injection detection (GitHub)](https://github.com/theevilbit/Shield) +- [Apple Developer β€” EndpointSecurity framework](https://developer.apple.com/documentation/endpointsecurity) - [https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f](https://medium.com/@metnew/why-electron-apps-cant-store-your-secrets-confidentially-inspect-option-a49950d6d51f) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/README.md index b04f0f5e96d..b664df42e02 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/README.md @@ -1315,7 +1315,10 @@ HALS_Object + 0x68 -> controlled_object - [https://knight.sc/malware/2019/03/15/code-injection-on-macos.html](https://knight.sc/malware/2019/03/15/code-injection-on-macos.html) - [https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a](https://gist.github.com/knightsc/45edfc4903a9d2fa9f5905f60b02ce5a) - [https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/) -- [*OS Internals, Volume I, User Mode, Jonathan Levin](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) +- [XNU β€” `osfmk/mach/message.h` (Mach message structures and flags)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/message.h) +- [XNU β€” `osfmk/ipc/ipc_port.h` (port rights and internals)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/ipc/ipc_port.h) +- [XNU β€” `osfmk/mach/mach_port.defs` (port manipulation MIG interface)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/mach_port.defs) +- [XNU β€” `osfmk/mach/task.defs` (`task_for_pid`, thread/task port operations)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/task.defs) - [https://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_get_special_port.html](https://web.mit.edu/darwin/src/modules/xnu/osfmk/man/task_get_special_port.html) - [Project Zero – Sound Barrier 2](https://projectzero.google/2026/01/sound-barrier-2.html) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md index 057fd303854..39493d14204 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-mig-mach-interface-generator.md @@ -399,7 +399,10 @@ The code generated by MIG also calles `kernel_debug` to generate logs about oper ## References -- [\*OS Internals, Volume I, User Mode, Jonathan Levin](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) +- [bootstrap_cmds β€” `migcom.tproj` (the MIG compiler itself)](https://github.com/apple-oss-distributions/bootstrap_cmds/tree/main/migcom.tproj) +- [XNU β€” `osfmk/mach/mach_port.defs` (example MIG subsystem definition)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/mach_port.defs) +- [XNU β€” `osfmk/mach/task.defs` (task subsystem MIG definition)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/task.defs) +- [XNU β€” `osfmk/mach/message.h` (Mach message header layout)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/mach/message.h) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-authorization.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-authorization.md index 51084204d40..c1f060f7239 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-authorization.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-authorization.md @@ -461,7 +461,9 @@ int main(void) { ## References -- [https://theevilbit.github.io/posts/secure_coding_xpc_part1/](https://theevilbit.github.io/posts/secure_coding_xpc_part1/) +- [Apple Developer β€” EvenBetterAuthorizationSample](https://developer.apple.com/library/archive/samplecode/EvenBetterAuthorizationSample/Introduction/Intro.html) ([mirror on GitHub](https://github.com/brenwell/EvenBetterAuthorizationSample)) +- [Apple Developer β€” Authorization Services](https://developer.apple.com/documentation/security/authorization-services) +- [Apple Developer β€” `AuthorizationCopyRights`](https://developer.apple.com/documentation/security/authorizationcopyrights(_:_:_:_:_:)) - [https://khronokernel.com/macos/2024/05/01/CVE-2024-4395.html](https://khronokernel.com/macos/2024/05/01/CVE-2024-4395.html) - [https://www.sentinelone.com/vulnerability-database/cve-2025-25251/](https://www.sentinelone.com/vulnerability-database/cve-2025-25251/) - [https://almightysec.com/helpertool-xpc-service-local-privilege-escalation/](https://almightysec.com/helpertool-xpc-service-local-privilege-escalation/) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-connecting-process-check/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-connecting-process-check/README.md index 7fe7c67a6b2..7c483a3af37 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-connecting-process-check/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-ipc-inter-process-communication/macos-xpc/macos-xpc-connecting-process-check/README.md @@ -94,6 +94,24 @@ if ((csFlags & (cs_hard | cs_require_lv)) { } ``` +The `cs_*` constants above are the code-signing flags defined in XNU's `osfmk/kern/cs_blobs.h`, so they can be checked against the source rather than guessed: + +```c +#define CS_HARD 0x00000100 /* don't load invalid pages */ +#define CS_KILL 0x00000200 /* kill process if it becomes invalid */ +#define CS_RESTRICT 0x00000800 /* tell dyld to treat restricted */ +#define CS_REQUIRE_LV 0x00002000 /* require library validation */ +#define CS_RUNTIME 0x00010000 /* Apply hardened runtime policies */ +``` + +## References + +- [Apple Developer β€” Code Signing Requirement Language](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html) +- [Apple Developer β€” `SecCodeCheckValidity`](https://developer.apple.com/documentation/security/seccodecheckvalidity(_:_:_:)) +- [Apple Developer β€” `SecTaskCreateWithAuditToken`](https://developer.apple.com/documentation/security/sectaskcreatewithaudittoken(_:_:)) +- [XNU β€” `osfmk/kern/cs_blobs.h` (`CS_*` code-signing flags)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/cs_blobs.h) +- [Sector 7 β€” XPC audit token spoofing](https://sector7.computest.nl/post/2023-10-xpc-audit-token-spoofing/) + {{#include ../../../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md index 558733f36f2..400770112b2 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/README.md @@ -21,18 +21,14 @@ This is like the [**LD_PRELOAD on Linux**](../../../../linux-hardening/linux-bas This technique may be also **used as an ASEP technique** as every application installed has a plist called "Info.plist" that allows for the **assigning of environmental variables** using a key called `LSEnvironmental`. > [!TIP] -> Since 2012 **Apple has drastically reduced the power** of the **`DYLD_INSERT_LIBRARIES`**. -> -> Go to the code and **check `src/dyld.cpp`**. In the function **`pruneEnvironmentVariables`** you can see that **`DYLD_*`** variables are removed. -> -> In the function **`processRestricted`** the reason of the restriction is set. Checking that code you can see that the reasons are: +> Since 2012 **Apple has drastically reduced the power** of **`DYLD_INSERT_LIBRARIES`**. A process is considered **restricted** β€” and then `dyld` deletes every `DYLD_*` variable from its environment β€” when any of these hold: > > - The binary is `setuid/setgid` -> - Existence of `__RESTRICT/__restrict` section in the macho binary. -> - The software has entitlements (hardened runtime) without [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables) entitlement -> - Check **entitlements** of a binary with: `codesign -dv --entitlements :- ` +> - The Mach-O has a **`__RESTRICT/__restrict`** section +> - The binary is signed with the hardened runtime and AMFI does not grant it the "path/print variables" permissions, i.e. it lacks [`com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables) +> - Check **entitlements** of a binary with: `codesign -dv --entitlements :- ` > -> In more updated versions you can find this logic at the second part of the function **`configureProcessRestrictions`.** However, what is executed in newer versions is the **beginning checks of the function** (you can remove the ifs related to iOS or simulation as those won't be used in macOS. +> In current `dyld` this is no longer decided by `dyld` alone: `ProcessConfig::Security::Security()` asks **AMFI** via `amfi_check_dyld_policy_self()` and then calls `pruneEnvVars()`. The exact code is walked through in [Prune `DYLD_*` env variables](#prune-dyld_-env-variables) below. ### Library Validation @@ -226,56 +222,84 @@ sudo fs_usage | grep "dlopentest" If a **privileged binary/app** (like a SUID or some binary with powerful entitlements) is **loading a relative path** library (for example using `@executable_path` or `@loader_path`) and has **Library Validation disabled**, it could be possible to move the binary to a location where the attacker could **modify the relative path loaded library**, and abuse it to inject code on the process. -## Prune `DYLD_*` and `LD_LIBRARY_PATH` env variables +## Prune `DYLD_*` env variables + +Older `dyld` releases (`dyld2.cpp`) decided this in-process with `issetugid()`, `hasRestrictedSegment()` and `csops(CS_OPS_STATUS)`. In **current `dyld` the decision is delegated to AMFI**, and the code lives in `ProcessConfig::Security::Security()` in `dyld/DyldProcessConfig.cpp`: + +```cpp + const uint64_t amfiFlags = getAMFI(process, syscall); + this->allowAtPaths = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_AT_PATH); + this->allowEnvVarsPrint = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_PRINT_VARS); + this->allowEnvVarsPath = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_PATH_VARS); + this->allowEnvVarsSharedCache = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_CUSTOM_SHARED_CACHE); + this->allowClassicFallbackPaths = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_FALLBACK_PATHS); + this->allowInsertFailures = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_FAILED_LIBRARY_INSERTION); + this->allowInterposing = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_LIBRARY_INTERPOSING); + this->allowEmbeddedVars = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_EMBEDDED_VARS); + this->allowDevelopmentVars = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_DEVELOPMENT_VARS); + this->allowLibSystemOverrides = (amfiFlags & AMFI_DYLD_OUTPUT_ALLOW_LIBSYSTEM_OVERRIDE); + ... + // env vars are only pruned on macOS + switch ( process.platform.value() ) { + case PLATFORM_MACOS: + case PLATFORM_IOSMAC: + case PLATFORM_DRIVERKIT: + break; + default: + return; + } + + // env vars are only pruned when process is restricted + if ( this->allowEnvVarsPrint || this->allowEnvVarsPath || this->allowEnvVarsSharedCache ) + return; + + this->pruneEnvVars(process); +``` + +Two things are worth extracting from this: -In the file `dyld-dyld-832.7.1/src/dyld2.cpp` it's possible to fund the function **`pruneEnvironmentVariables`**, which will remove any env variable that **starts with `DYLD_`** and **`LD_LIBRARY_PATH=`**. +- Pruning only happens on **macOS / Mac Catalyst / DriverKit** β€” and only when AMFI granted **none** of `allowEnvVarsPrint`, `allowEnvVarsPath`, `allowEnvVarsSharedCache`. +- The AMFI query is fed the executable's own properties: -It'll also set to **null** specifically the env variables **`DYLD_FALLBACK_FRAMEWORK_PATH`** and **`DYLD_FALLBACK_LIBRARY_PATH`** for **suid** and **sgid** binaries. +```cpp +uint64_t amfiFlags = sys.amfiFlags(proc.mainExecutableHdr->isRestricted(), + proc.mainExecutableHdr->isFairPlayEncrypted(fpTextOffset, fpSize)); +``` -This function is called from the **`_main`** function of the same file if targeting OSX like this: +where `isRestricted()` is literally the `__RESTRICT` segment check (`mach_o/UnsafeHeader.cpp`): ```cpp -#if TARGET_OS_OSX - if ( !gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache ) { - pruneEnvironmentVariables(envp, &apple); +bool UnsafeHeader::isRestricted() const +{ + return this->hasSection("__RESTRICT", "__restrict"); +} ``` -and those boolean flags are set in the same file in the code: +`pruneEnvVars()` then strips **every** variable whose name begins with `DYLD_` and slides the `apple[]` parameters down, so the children of a restricted process don't inherit them either: ```cpp -#if TARGET_OS_OSX - // support chrooting from old kernel - bool isRestricted = false; - bool libraryValidation = false; - // any processes with setuid or setgid bit set or with __RESTRICT segment is restricted - if ( issetugid() || hasRestrictedSegment(mainExecutableMH) ) { - isRestricted = true; - } - bool usingSIP = (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0); - uint32_t flags; - if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) { - // On OS X CS_RESTRICT means the program was signed with entitlements - if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && usingSIP ) { - isRestricted = true; - } - // Library Validation loosens searching but requires everything to be code signed - if ( flags & CS_REQUIRE_LV ) { - isRestricted = false; - libraryValidation = true; - } - } - gLinkContext.allowAtPaths = !isRestricted; - gLinkContext.allowEnvVarsPrint = !isRestricted; - gLinkContext.allowEnvVarsPath = !isRestricted; - gLinkContext.allowEnvVarsSharedCache = !libraryValidation || !usingSIP; - gLinkContext.allowClassicFallbackPaths = !isRestricted; - gLinkContext.allowInsertFailures = false; - gLinkContext.allowInterposing = true; + // For security, setuid programs ignore DYLD_* environment variables. + // Additionally, the DYLD_* enviroment variables are removed + // from the environment, so that any child processes doesn't see them. + for ( const char* const* s = proc.envp; *s != NULL; s++ ) { + if ( strncmp(*s, "DYLD_", 5) != 0 ) { + *d++ = *s; + } + ... ``` -Which basically means that if the binary is **suid** or **sgid**, or has a **RESTRICT** segment in the headers or it was signed with the **CS_RESTRICT** flag, then **`!gLinkContext.allowEnvVarsPrint && !gLinkContext.allowEnvVarsPath && !gLinkContext.allowEnvVarsSharedCache`** is true and the env variables are pruned. +> [!TIP] +> Practical consequence: **`DYLD_*` is pruned when the process is restricted** β€” setuid/setgid, a `__RESTRICT/__restrict` section, or hardened-runtime/entitled binaries that AMFI refuses to grant the path/print flags to. If instead the process only has **library validation** (`CS_REQUIRE_LV`), the variables survive but the inserted dylib must be signed by the **same Team ID** (or by Apple), so you need one of the library-validation-disabling entitlements to actually land code. + +Because the decision is now AMFI's, the fastest way to know what a given binary will get is to look at what AMFI keys off β€” entitlements and signing flags β€” rather than at `dyld` itself: -Note that if CS_REQUIRE_LV is true, then the variables won't be pruned but the library validation will check they are using the same certificate as the original binary. +```bash +BIN=/path/to/bin +codesign -d --entitlements :- "$BIN" 2>/dev/null | \ + egrep "allow-dyld-environment-variables|disable-library-validation|clear-library-validation" +codesign -dvvv "$BIN" 2>&1 | egrep "flags=|TeamIdentifier=" +otool -l "$BIN" | grep -A2 __RESTRICT +``` ## Check Restrictions @@ -336,8 +360,10 @@ DYLD_INSERT_LIBRARIES=inject.dylib ./hello-signed # Won't work ## References -- [https://theevilbit.github.io/posts/dyld_insert_libraries_dylib_injection_in_macos_osx_deep_dive/](https://theevilbit.github.io/posts/dyld_insert_libraries_dylib_injection_in_macos_osx_deep_dive/) -- [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) +- [dyld β€” `dyld/DyldProcessConfig.cpp` (`ProcessConfig::Security`, `getAMFI`, `pruneEnvVars`)](https://github.com/apple-oss-distributions/dyld/blob/main/dyld/DyldProcessConfig.cpp) +- [dyld β€” `mach_o/UnsafeHeader.cpp` (`isRestricted()` / `__RESTRICT` check)](https://github.com/apple-oss-distributions/dyld/blob/main/mach_o/UnsafeHeader.cpp) +- [Apple Developer β€” `com.apple.security.cs.allow-dyld-environment-variables`](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables) +- [dyld β€” `dyld/dyldMain.cpp` (process startup and library insertion)](https://github.com/apple-oss-distributions/dyld/blob/main/dyld/dyldMain.cpp) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md index 9ab75e67de0..e212b55a21b 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-proces-abuse/macos-library-injection/macos-dyld-process.md @@ -312,7 +312,9 @@ find . -type f | xargs grep strcmp| grep key,\ \" | cut -d'"' -f2 | sort -u ## References -- [**\*OS Internals, Volume I: User Mode. By Jonathan Levin**](https://www.amazon.com/MacOS-iOS-Internals-User-Mode/dp/099105556X) +- [dyld β€” `dyld/dyldMain.cpp` (process startup path)](https://github.com/apple-oss-distributions/dyld/blob/main/dyld/dyldMain.cpp) +- [dyld β€” `dyld/DyldProcessConfig.cpp` (process/security configuration)](https://github.com/apple-oss-distributions/dyld/blob/main/dyld/DyldProcessConfig.cpp) +- [XNU β€” `bsd/kern/kern_exec.c` (kernel side of `execve`, loading dyld)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_exec.c) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-amfi-applemobilefileintegrity.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-amfi-applemobilefileintegrity.md index eaa6071fade..12aae7160a9 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-amfi-applemobilefileintegrity.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-amfi-applemobilefileintegrity.md @@ -155,8 +155,11 @@ In iOS and jailbreak research you'll still find the traditional model of **loada ## References -- [**\*OS Internals Volume III**](https://newosxbook.com/home.html) -- [https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/) +- [XNU β€” `security/mac_policy.h` (MACF policy ops AMFI registers, incl. `mpo_policy_syscall`)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_policy.h) +- [XNU β€” `osfmk/kern/cs_blobs.h` (`CS_*` code-signing flags AMFI sets)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/cs_blobs.h) +- [XNU β€” `bsd/kern/ubc_subr.c` (code-signature blob parsing and validation)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/ubc_subr.c) +- [XNU β€” `bsd/sys/codesign.h` (`CS_OPS_*` operations and `CLEAR_LV_ENTITLEMENT`)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/codesign.h) +- [XNU β€” `bsd/kern/kern_proc.c` (`csops` / `CS_OPS_CLEAR_LV` handler)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_proc.c) - [https://support.apple.com/guide/security/trust-caches-sec7d38fbf97/web](https://support.apple.com/guide/security/trust-caches-sec7d38fbf97/web) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing-weaknesses-and-sandbox-escapes.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing-weaknesses-and-sandbox-escapes.md index cf4c2ff2e17..e3cd71cb1b9 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing-weaknesses-and-sandbox-escapes.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing-weaknesses-and-sandbox-escapes.md @@ -346,6 +346,7 @@ cp /tmp/evil.dylib /path/to/writable.dylib * [Apple Developer β€” Code Signing Guide](https://developer.apple.com/library/archive/technotes/tn2206/_index.html) * [Apple Developer β€” App Sandbox](https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AboutAppSandbox/AboutAppSandbox.html) * [Apple Developer β€” Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) -* [The Evil Bit β€” clear-library-validation](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/) +* [XNU β€” `bsd/sys/codesign.h` (`CS_OPS_*` operations and `CLEAR_LV_ENTITLEMENT`)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/codesign.h) +* [XNU β€” `bsd/kern/kern_proc.c` (`csops` / `CS_OPS_CLEAR_LV` handler)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_proc.c) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md index 749f6723865..cb7b7ec3961 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-code-signing.md @@ -408,6 +408,10 @@ struct cs_blob { ## References -- [**\*OS Internals Volume III**](https://newosxbook.com/home.html) +- [XNU β€” `osfmk/kern/cs_blobs.h` (`CodeDirectory`, `CS_*` flags, blob magic values)](https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/cs_blobs.h) +- [XNU β€” `bsd/kern/ubc_subr.c` (`cs_blob` handling and signature validation)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/ubc_subr.c) +- [XNU β€” `bsd/sys/codesign.h` (`csops`/`csops_audittoken` operations)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/codesign.h) +- [Apple Security framework source β€” `libsecurity_codesigning`](https://github.com/apple-oss-distributions/Security/tree/main/OSX/libsecurity_codesigning) +- [Apple Developer β€” Code Signing Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md index 1ee43b56c32..12846221d30 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-dangerous-entitlements.md @@ -33,8 +33,44 @@ This entitlement allows to **load frameworks, plug-ins, or libraries without bei ### `com.apple.private.security.clear-library-validation` -This entitlement is very similar to **`com.apple.security.cs.disable-library-validation`** but **instead** of **directly disabling** library validation, it allows the process to **call a `csops` system call to disable it**.\ -Check [**this for more info**](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/). +This entitlement is very similar to **`com.apple.security.cs.disable-library-validation`** but **instead** of **directly disabling** library validation, it allows the process to **call a `csops` system call to disable it** at runtime. + +The entitlement name is hardcoded in XNU next to the `csops` operation that consumes it: + +```c +/* bsd/sys/codesign.h */ +#define CLEAR_LV_ENTITLEMENT "com.apple.private.security.clear-library-validation" +... +#define CS_OPS_CLEAR_LV 15 /* clear the library validation flag */ +``` + +The kernel handler for `CS_OPS_CLEAR_LV` (`bsd/kern/kern_proc.c`) shows exactly how narrow the primitive is: + +```c +case CS_OPS_CLEAR_LV: { +#if !defined(XNU_TARGET_OS_OSX) + // We only support dropping library validation on macOS + error = ENOTSUP; +#else + if (forself == 1 && IOTaskHasEntitlement(proc_task(pt), CLEAR_LV_ENTITLEMENT)) { + proc_lock(pt); + if (!(proc_getcsflags(pt) & CS_INSTALLER) && (pt->p_subsystem_root_path == NULL)) { + proc_csflags_clear(pt, CS_REQUIRE_LV | CS_FORCED_LV); + error = 0; +``` + +So the operation: + +- Is **macOS-only** (`ENOTSUP` on every other platform). +- Only works on **itself** (`forself == 1`) β€” you cannot strip library validation off another process with it. +- Requires the process to actually **hold the entitlement**, and refuses if the process is flagged `CS_INSTALLER` or is running under a subsystem root path. +- Clears **`CS_REQUIRE_LV | CS_FORCED_LV`** from the process' code-signing flags. + +The XNU comment explains the intended use case, and also why it is interesting to an attacker: + +> This option is used to remove library validation from a running process. This is used in plugin architectures when a program needs to load untrusted libraries. [...] Once a process has loaded the untrusted library, relying on library validation in the future will not be effective. + +In other words, **any binary carrying this entitlement is a dylib-injection target**: get code running inside it (or convince it to load your plug-in) after it has dropped `CS_REQUIRE_LV`, and you inherit whatever the host process is trusted to do. ### `com.apple.security.cs.allow-dyld-environment-variables` @@ -260,6 +296,10 @@ For detailed IOKit/DriverKit exploitation, see: ../mac-os-architecture/macos-iokit.md {{#endref}} +## References +- [Apple Developer β€” Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) +- [XNU β€” `bsd/sys/codesign.h` (`CS_OPS_*` operations and `CLEAR_LV_ENTITLEMENT`)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/codesign.h) +- [XNU β€” `bsd/kern/kern_proc.c` (`csops` / `CS_OPS_CLEAR_LV` handler)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/kern_proc.c) {{#include ../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md index 4ee9bfe1192..8358c8cdfcf 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks/README.md @@ -4,13 +4,15 @@ ## POSIX permissions combinations -Permissions in a **directory**: +For a **directory**, the three permission bits mean something different from what they mean on a regular file. `chmod(1)` calls the execute bit "**search**" when it is applied to a directory: -- **read** - you can **enumerate** the directory entries -- **write** - you can **delete/write** **files** in the directory and you can **delete empty folders**. - - But you **cannot delete/modify non-empty folders** unless you have write permissions over it. - - You **cannot modify the name of a folder** unless you own it. -- **execute** - you are **allowed to traverse** the directory - if you don’t have this right, you can’t access any files inside it, or in any subdirectories. +> `0100` For files, allow execution by owner. For directories, allow the owner to **search** in the directory. + +- **read** - you can **enumerate** the directory entries (list the names). +- **write** - you can **create, rename and delete entries** in the directory. Note this is a property of the *containing* directory, not of the file: you can delete a file you cannot read or write, as long as you can write its parent directory. + - To delete a **subdirectory** it must be empty, which in turn requires enough rights to remove everything inside it. + - If the directory has the **sticky bit** (`S_ISVTX`, like `/tmp`) this is restricted β€” POSIX states that a process may then remove or rename files in it only if it owns the file, owns the directory, or has appropriate privileges. +- **execute / search** - you are **allowed to traverse** the directory. Pathname resolution locates each component "in the directory specified by its predecessor", so **losing search rights on any single component of the path prefix makes everything below it unreachable by path**, even if the leaf file itself is world-readable. ### Dangerous Combinations @@ -22,11 +24,25 @@ Permissions in a **directory**: With any of the previous combinations, an attacker could **inject** a **sym/hard link** the expected path to obtain a privileged arbitrary write. -### Folder root R+X Special case +### Folder root R+X special case + +This falls straight out of the pathname-resolution rule above. If a **directory only grants R+X to root**, the files inside it are unreachable *by path* for everybody else β€” but the **files' own permission bits may still be permissive**. The directory is the only thing standing in the way. -If there are files in a **directory** where **only root has R+X access**, those are **not accessible to anyone else**. So a vulnerability allowing to **move a file readable by a user**, that cannot be read because of that **restriction**, from this folder **to a different one**, could be abuse to read these files. +So any primitive that lets you get the file **out of that directory** β€” a privileged process that **moves/renames/copies** an attacker-chosen path into a location you *can* traverse β€” turns into an arbitrary read, without ever needing to defeat the file's own mode: -Example in: [https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions](https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions) +```bash +# Reproduce the primitive locally +sudo mkdir -p /tmp/locked && sudo chmod 700 /tmp/locked +sudo sh -c 'echo secret > /tmp/locked/data.txt; chmod 644 /tmp/locked/data.txt' + +ls -l /tmp/locked/data.txt # Permission denied: cannot even stat through the directory +cat /tmp/locked/data.txt # Permission denied + +# The file itself is mode 644 - only the parent directory's search bit blocks you. +sudo ls -l /tmp/locked/ +``` + +Look for privileged file movers (installers, log rotators, crash/diagnostic collectors, backup and "export" features) that accept a source path from a lower-privileged user. ## Symbolic Link / Hard Link @@ -495,11 +511,11 @@ This feature is particularly useful for preventing certain classes of security v ## References -- [https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/](https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/) +- [POSIX.1-2024 β€” Base Definitions, Ch. 4 (File Access Permissions, Directory Protection, Pathname Resolution)](https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap04.html) +- [`chmod(1)` man page](https://keith.github.io/xcode-man-pages/chmod.1.html) (directory search/execute bit, ACL inheritance flags) +- [`open(2)` man page](https://keith.github.io/xcode-man-pages/open.2.html) (`O_NOFOLLOW`, `O_NOFOLLOW_ANY`, `O_RESOLVE_BENEATH`) - [SektionEins - OS X 10.10 DYLD_PRINT_TO_FILE Local Privilege Escalation](https://www.sektioneins.de/en/blog/15-07-07-dyld_print_to_file_lpe.html) (leaked FD without close-on-exec) - [The Eclectic Light Company - Which file systems and cloud services preserve extended attributes?](https://eclecticlight.co/2018/01/12/which-file-systems-and-cloud-services-preserve-extended-attributes/) -- [`open(2)` man page](https://keith.github.io/xcode-man-pages/open.2.html) (`O_NOFOLLOW`, `O_NOFOLLOW_ANY`, `O_RESOLVE_BENEATH`) -- [`chmod(1)` man page](https://keith.github.io/xcode-man-pages/chmod.1.html) (ACL inheritance flags) - [Microsoft - Gatekeeper's Achilles heel: unearthing a macOS vulnerability](https://www.microsoft.com/en-us/security/blog/2022/12/19/gatekeepers-achilles-heel-unearthing-a-macos-vulnerability/) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-launch-environment-constraints.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-launch-environment-constraints.md index fe417ba0eea..b0ee85ec93a 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-launch-environment-constraints.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-launch-environment-constraints.md @@ -168,9 +168,23 @@ While implementing constraints on the XPC service might be beneficial by **narro Even if it's required that the application has to be **opened by LaunchService** (in the parents constraints). This can be achieved using **`open`** (which can set env variables) or using the **Launch Services API** (where env variables can be indicated). +### CVE-2025-43253 - Overriding the built-in constraints at spawn time + +Launch constraints (officially **lightweight code requirements**, *LWCR*) are enforced by the **AMFI MAC policy**. `posix_spawn` lets a caller hand an arbitrary blob to a MAC policy through **`posix_spawnattr_setmacpolicyinfo_np()`**, and AMFI accepted a caller-supplied LWCR dictionary through that path. The bug was that the **attacker-supplied constraints replaced the binary's built-in ones** instead of being checked in addition to them: + +- Build a minimal (even empty) launch-constraints dictionary. +- Set the **constraint category to `127`**, a value that AMFI allows in spawn attributes but does **not enforce** β€” it only logs `Launch Constraint Violation (not enforcing)` instead of blocking the execution. +- Pass it via the spawn attributes, and the process launches in a context its real self/parent constraints would have forbidden. + +After the fix, **both** the built-in and the supplied constraints are validated, so the supplied dictionary can no longer weaken the built-in one. + +> [!TIP] +> This is the general shape to look for when auditing constraint enforcement: an API that lets untrusted input *supply* a policy tends to be interesting whenever the policy engine treats the supplied value as a replacement rather than an additional requirement. + ## References - [https://youtu.be/f1HA5QhLQ7Y?t=24146](https://youtu.be/f1HA5QhLQ7Y?t=24146) +- [CVE-2025-43253: Bypassing Launch Constraints on macOS (wts.dev)](https://wts.dev/posts/bypassing-launch-constraints/) - [https://theevilbit.github.io/posts/launch_constraints_deep_dive/](https://theevilbit.github.io/posts/launch_constraints_deep_dive/) - [https://eclecticlight.co/2023/06/13/why-wont-a-system-app-or-command-tool-run-launch-constraints-and-trust-caches/](https://eclecticlight.co/2023/06/13/why-wont-a-system-app-or-command-tool-run-launch-constraints-and-trust-caches/) - [https://developer.apple.com/videos/play/wwdc2023/10266/](https://developer.apple.com/videos/play/wwdc2023/10266/) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-macf-mandatory-access-control-framework.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-macf-mandatory-access-control-framework.md index 5509056f2f4..705a14fa147 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-macf-mandatory-access-control-framework.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-macf-mandatory-access-control-framework.md @@ -488,7 +488,10 @@ For deeper product-specific reversing, check the dedicated pages on [macOS Sandb ## References -- [**\*OS Internals Volume III**](https://newosxbook.com/home.html) +- [XNU β€” `security/mac_policy.h` (the full MACF policy operations vector)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_policy.h) +- [XNU β€” `security/mac_base.c` (`mac_policy_register`, `__mac_syscall`)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_base.c) +- [XNU β€” `security/mac_internal.h` (`MAC_CHECK` / `MAC_GRANT` / `MAC_POLICY_ITERATE` macros)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_internal.h) +- [XNU β€” `bsd/sys/priv.h` (privilege codes used by `priv_check`/`priv_grant`)](https://github.com/apple-oss-distributions/xnu/blob/main/bsd/sys/priv.h) - [**AMFI Syscall (Offensive Security)**](https://www.offsec.com/blog/amfi-syscall/) - [**Uncovering Apple Vulnerabilities: diskarbitrationd and storagekitd Audit Part 2**](https://blog.kandji.io/macos-audit-story-part2) diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md index df5d3931ec8..0aca49f8684 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/README.md @@ -399,7 +399,10 @@ Sandbox also has a user daemon running exposing the XPC Mach service `com.apple. ## References -- [**\*OS Internals Volume III**](https://newosxbook.com/home.html) +- [XNU β€” `security/mac_policy.h` (MACF hooks the Sandbox kext registers)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_policy.h) +- [XNU β€” `security/mac_base.c` (`__mac_syscall`, the entry point behind `__sandbox_ms`)](https://github.com/apple-oss-distributions/xnu/blob/main/security/mac_base.c) +- [`sandbox_init(3)` man page](https://keith.github.io/xcode-man-pages/sandbox_init.3.html) +- [Apple Developer β€” App Sandbox](https://developer.apple.com/documentation/security/app-sandbox) {{#include ../../../../banners/hacktricks-training.md}} diff --git a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md index 97d50d3c405..98f6faff67c 100644 --- a/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md +++ b/src/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-tcc/macos-tcc-bypasses/README.md @@ -491,10 +491,21 @@ This allowed an attacker to do arbitrary mounts in any location, including over The tool **`/usr/sbin/asr`** allowed to copy the whole disk and mount it in another place bypassing TCC protections. -### Location Services +### CVE-2022-22655 - Location Services -There is a third TCC database in **`/var/db/locationd/clients.plist`** to indicate clients allowed to **access location services**.\ -The folder **`/var/db/locationd/` wasn't protected from DMG mounting** so it was possible to mount our own plist. +Location Services are **not** stored in a TCC database like the other services. They are managed by `locationd`, which keeps its own allow-list in **`/var/db/locationd/clients.plist`**: + +```bash +# Requires FDA to read +sudo plutil -p /var/db/locationd/clients.plist | head -40 +``` + +Each entry is keyed by the client (bundle ID or executable path) and carries fields such as `Authorized`, `BundleId`, `Executable` and `Registered`. + +The `clients.plist` file itself is protected by Sandbox/TCC and cannot be edited even as root β€” but the **`/var/db/locationd/` directory was not protected from mounting**. So an attacker running as root could build a disk image containing their own `clients.plist` (with their binary marked `Authorized`), mount it over the directory, and restart `locationd` to have the forged allow-list take effect. + +> [!TIP] +> This is the same pattern as the `hdiutil`/`mount` TCC bypasses above: the *file* is protected, the *directory it lives in* is not, so you replace the whole directory instead of the file. ## By startup apps @@ -525,6 +536,8 @@ Another way using [**CoreGraphics events**](https://objectivebythesea.org/v2/tal - [**https://www.sentinelone.com/labs/bypassing-macos-tcc-user-privacy-protections-by-accident-and-design/**](https://www.sentinelone.com/labs/bypassing-macos-tcc-user-privacy-protections-by-accident-and-design/) - [**20+ Ways to Bypass Your macOS Privacy Mechanisms**](https://www.youtube.com/watch?v=W9GxnP8c8FU) - [**Knockout Win Against TCC - 20+ NEW Ways to Bypass Your MacOS Privacy Mechanisms**](https://www.youtube.com/watch?v=a9hsxPdRxsY) +- [**CVE-2022-22655 - TCC Location Services bypass (original report)**](https://theevilbit.github.io/posts/cve-2022-22655/) +- [**Where in the World is Carmen Sandiego: Abusing Location Services on macOS**](https://slyd0g.medium.com/where-in-the-world-is-carmen-sandiego-abusing-location-services-on-macos-10e9f4eefb71) - [**Jamf Threat Labs - CVE-2024-44131: TCC bypass steals data from iCloud**](https://www.jamf.com/blog/tcc-bypass-steals-data-from-icloud/) - [**SQLite - `test_sqllog.c` (SQLITE_ENABLE_SQLLOG env variables)**](https://github.com/sqlite/sqlite/blob/master/src/test_sqllog.c) - [**Apple - Allow DYLD environment variables entitlement**](https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.security.cs.allow-dyld-environment-variables) diff --git a/src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md b/src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md index bbaa170c3cb..77669e5c8cd 100644 --- a/src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md +++ b/src/mobile-pentesting/android-app-pentesting/shizuku-privileged-api.md @@ -209,6 +209,29 @@ This matters during assessments because a previously one-time Wireless Debugging Observed keep-alive enhancements around this pattern include **1x1 foreground activities**, silent `MediaSession` playback, `WakeLock`s, two services in different processes that rebind each other with `BIND_AUTO_CREATE` / `onServiceDisconnected()`, periodic restart alarms, writes to `/proc//oom_score_adj`, and `mlock()` to pin hot pages in RAM. + +#### Build-specific kernel exploit staging and KernelSU late-load handoff +Another practical pattern is to use **shell-backed Shizuku only as the staging bridge** for a **build-specific local kernel exploit**, then hand the post-root workflow to **KernelSU/ReSukiSU**. + +A robust wrapper usually does all of the following **before** launching the native payload: + +1. Collect an **exact target profile** from JNI / shell-visible sources such as `getprop`, `/proc/version`, `uname`, `getconf PAGESIZE`, and `ro.build.display.id`. +2. Match **codename + build ID + kernel version + ABI + page size** against an explicit allowlist (for example an embedded `profiles.json`) and **abort on mismatch**. +3. Use a Binder-bound **Shizuku UserService** or similar helper to extract the matching native payload into **`/data/local/tmp`** and execute it as **UID `2000` (`shell`)**. +4. If the exploit succeeds, immediately convert the one-shot kernel primitive into a **reusable local root channel** such as a privileged daemon or **Unix-domain socket** (for example `temp_su.sock`) so later steps do not need to rerun the kernel exploit. +5. Stage a `ksud` binary matching the target **KMI** and late-load KernelSU: + +```bash +getprop ro.build.display.id +getconf PAGESIZE +uname -a +ksud late-load --kmi +``` + +This pattern is useful because **Shizuku gives reliable ADB/shell execution and file-placement primitives on non-rooted devices**, while the fragile build-dependent exploit is kept inside a native payload selected only for the exact firmware. After the root channel is up, the workflow can verify KernelSU activation by checking artifacts such as **`/dev/kernelsu`**, **`/sys/kernel/kernelsu`**, and **`/data/adb/ksu`**. + +The same design is also a good detection model: watch for **Shizuku-authorised apps dropping native helpers into `/data/local/tmp`**, launching shell-owned payloads, creating local privileged sockets, and then invoking **`ksud late-load --kmi ...`** or triggering a **soft reboot / `system_server` restart** to stabilize the new root environment. + --- ## 4. Security considerations / detection 1. Shizuku needs **ADB debugging** or **root** first, so _Developer Options -> USB/Wireless debugging_ must be enabled on non-rooted devices. Unexpected enablement of **Developer Options**, **Wireless debugging**, or pairing-code dialogs on a production handset is already a strong signal. @@ -239,5 +262,6 @@ Observed keep-alive enhancements around this pattern include **1x1 foreground ac - [Shizuku-API Developer Guide](https://github.com/RikkaApps/Shizuku-API) - [awesome-shizuku - list of supported apps](https://github.com/timschneeb/awesome-shizuku) - [RedHook Returns with a Dangerous Upgrade](https://www.group-ib.com/blog/redhook-android-rat-upgraded/) +- [Root My Pixel: Automated Temporary Root and KernelSU Late Loading on Google Pixel Devices](https://github.com/alex193a/Root-My-Pixel) {{#include ../../banners/hacktricks-training.md}}