-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
313 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
# Entitlements | ||
|
||
Collection of scripts for determining which [Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) macOS (Mach-O) binaries have. | ||
|
||
Inspired by: | ||
* [Cedric Owens](https://twitter.com/cedowens)'s [EntitlementCheck](https://github.com/cedowens/EntitlementCheck) | ||
* [Jonathan Levin](https://twitter.com/morpheus______)'s [OS X/iOS Entitlement Database](http://newosxbook.com/ent.jl) | ||
|
||
For lists of and descriptions of Entitlements see: | ||
* Apple Developer Documentation | ||
* [Bundle Resources > Entitlements](https://developer.apple.com/documentation/bundleresources/entitlements) | ||
* [Security > App Sandbox](https://developer.apple.com/documentation/security/app_sandbox) | ||
|
||
|
||
# Hardened Runtime | ||
|
||
|
||
## Sources | ||
* [Notarization: the hardened runtime](https://eclecticlight.co/2021/01/07/notarization-the-hardened-runtime/) by [Howard Oakley](https://twitter.com/howardnoakley) | ||
* [The ‘hardened runtime’ explained](https://eclecticlight.co/2019/08/10/the-hardened-runtime-explained/) by [Howard Oakley](https://twitter.com/howardnoakley) | ||
* [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime) by Apple | ||
* [Your Apps and the Future of macOS Security (WWDC2018 Session 702)](https://developer.apple.com/videos/play/wwdc2018/702/) (22:00 mark) by Apple | ||
|
||
# Interesting Entitlements | ||
|
||
|
||
## `com.apple.private.security.clear-library-validation` | ||
* Formerly `com.apple.security.cs.disable-library-validation` | ||
* Can load arbitrary unsigned plugins/frameworks | ||
* [About com.apple.private.security.clear-library-validation](https://theevilbit.github.io/posts/com.apple.private.security.clear-library-validation/) by [Csaba Fitzl](https://twitter.com/theevilbit) | ||
|
||
|
||
## `com.apple.security.cs-allow-dyld-environment-variables` | ||
* [Allow DYLD Environment Variables Entitlement](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-dyld-environment-variables/) | ||
* Allows injecting Dynamic Libraries (dylib's) via the `DYLD_INSERT_LIBRARIES` environment variable | ||
* [DYLD_INSERT_LIBRARIES DYLIB injection in macOS / OSX](https://theevilbit.github.io/posts/dyld_insert_libraries_dylib_injection_in_macos_osx_deep_dive/) by [Csaba Fitzl](https://twitter.com/theevilbit) | ||
|
||
|
||
## `com.apple.security.get-task-allow` | ||
* Allows other processes to attach via a debugger | ||
## `com.apple.security.cs.allow-unsigned-executable-memory` | ||
* [Allow Unsigned Executable Memory Entitlement](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-unsigned-executable-memory/) | ||
* Allows overriding or patching C code | ||
* Via `NSCreateObjectFileImageFromMemory` (which is fundamentally insecure) | ||
* Or use the DVDPlayback framework | ||
## `com.apple.security.files.downlaods.read-only` | ||
* [`com.apple.security.files.downloads.read-only`](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_files_downloads_read-only/) | ||
* May have access to files the user has selected in an open or save dialog | ||
## `com.apple.security.files.downloads.read-write` | ||
* May have access to files the user has selected in an open or save dialog | ||
## `com.apple.security.files.all` | ||
## `com.apple.security.files.user-selected.read-only` | ||
## `com.apple.security.files.user-selected.read-write` | ||
## `com.apple.private.tcc.allow` | ||
* May have TCC access to some protected portions of the OS | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#!/usr/bin/env zsh | ||
# # macos-scripts/entitlements/dump-entitlements | ||
|
||
# dump-entitlements | ||
|
||
set -uo pipefail | ||
# -o pipefail force pipelines to fail on first non-zero status code | ||
# -u prevent using undefined variables | ||
|
||
IFS=$'\n\t' | ||
# Set Internal Field Separator to newlines and tabs | ||
# This makes bash consider newlines and tabs as separating words | ||
# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/ | ||
|
||
|
||
function usage { | ||
echo | ||
echo " Find all binaries on disk, dump their entitlements, uniquely sort the entitlements" | ||
echo " Usage: ./dump-entitlements {find | dump | sort}" | ||
echo | ||
|
||
echo " find Find all binaries on disk and dump them to ${BINARIES_FILENAME}" | ||
echo " dump Process ${BINARIES_FILENAME} and dump the entitlements for each binary to ${ENTITLEMENTS_FILENAME}" | ||
echo " sort Uniquely sort ${ENTITLEMENTS_FILENAME} to ${SORTED_ENTITLEMENTS_FILENAME}" | ||
echo | ||
|
||
exit 0 | ||
} | ||
|
||
|
||
### Utility Functions ### | ||
# ctrl_c | ||
|
||
function ctrl_c { | ||
echo -e "\\n[❌] ${USER} has chosen to quit!" | ||
exit 1 | ||
} | ||
|
||
### END Utility Functions ### | ||
|
||
|
||
function find_binaries { | ||
# find_binaries | ||
|
||
sudo --prompt="[⚠️ ] sudo required to search everywhere" -v | ||
|
||
sudo find / -type f -exec file {} \; -print | grep 'Mach-O' | awk -F ':' '{print $1}' > "${BINARIES_FILENAME}" | ||
} | ||
|
||
|
||
function dump_entitlements { | ||
# dump_entitlements | ||
|
||
while read binary; do | ||
/usr/bin/codesign --display --entitlements - "${binary}" 2>&1 > "${ENTITLEMENTS_FILENAME}" | ||
done < "${BINARIES_FILENAME}" | ||
} | ||
|
||
|
||
function sort_entitlements { | ||
# sort_entitlements | ||
|
||
awk '{print $2}' "${ENTITLEMENTS_FILENAME}" | grep com.apple | sort -u > "${SORTED_ENTITLEMENTS_FILENAME}" | ||
} | ||
|
||
|
||
function main { | ||
|
||
trap ctrl_c SIGINT | ||
# Detect and react to the user hitting CTRL + C | ||
|
||
declare -r ARG=${1:-"usage"} | ||
declare -r DATE=$(date +"%d-%m-%Y") | ||
declare -r BINARIES_FILENAME="Mach-O.txt-${DATE}" | ||
declare -r ENTITLEMENTS_FILENAME="entitlements-${DATE}.txt" | ||
declare -r SORTED_ENTITLEMENTS_FILENAME="sorted-entitlements-${DATE}.txt" | ||
|
||
case "${ARG}" in | ||
|
||
usage|help|-h|--help|🤷♂️|🤷♀️|"¯\_(ツ)_/¯") | ||
usage | ||
;; | ||
|
||
find|-f|--find) | ||
echo "[⚠️ ] This takes a looong time to run" | ||
echo "Will dump list of binaries to ${BINARIES_FILENAME}" | ||
sleep 3 | ||
find_binaries | ||
;; | ||
|
||
dump|-d|--dump) | ||
dump_entitlements | ||
;; | ||
|
||
sort|-s|--sort) | ||
sort_entitlements | ||
;; | ||
|
||
*) | ||
usage | ||
;; | ||
esac | ||
} | ||
|
||
main "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#!/usr/bin/env zsh | ||
# macos-scripts/entitlements/treebeard | ||
|
||
# treebeard | ||
|
||
set -uo pipefail | ||
# -o pipefail force pipelines to fail on first non-zero status code | ||
# -u prevent using undefined variables | ||
|
||
IFS=$'\n\t' | ||
# Set Internal Field Separator to newlines and tabs | ||
# This makes bash consider newlines and tabs as separating words | ||
# See: http://redsymbol.net/articles/unofficial-bash-strict-mode/ | ||
|
||
|
||
### Define Colours ### | ||
tput sgr0; | ||
# reset colors | ||
|
||
RESET=$(tput sgr0) | ||
readonly RESET | ||
RED=$(tput setaf 1) | ||
readonly RED | ||
YELLOW=$(tput setaf 3) | ||
readonly YELLOW | ||
GREEN=$(tput setaf 64) | ||
readonly GREEN | ||
### END Colours ### | ||
|
||
|
||
function usage { | ||
echo | ||
echo " " | ||
echo " Usage: ./treebeard" | ||
echo | ||
|
||
echo " shit some shit" | ||
echo | ||
|
||
exit 0 | ||
} | ||
|
||
|
||
### Utility Functions ### | ||
# ctrl_c | ||
|
||
function ctrl_c { | ||
echo -e "\\n[❌] ${USER} has chosen to quit!" | ||
exit 1 | ||
} | ||
|
||
### END Utility Functions ### | ||
|
||
function get_binaries { | ||
# get_binaries | ||
|
||
for binary in /Applications/*.app/Contents/MacOS/* \ | ||
/usr/bin/* \ | ||
/usr/local/bin/* \ | ||
/usr/sbin/*; do | ||
|
||
if [[ "${binary}" =~ Xcode.app ]]; then | ||
continue | ||
# Skip Xcode because it takes ages to run codesign on it | ||
elif [[ "${binary}" =~ Safari.app ]]; then | ||
continue | ||
# Skip Safari because it is a system application | ||
# TODO: Skip other systems apps like Pages? | ||
fi | ||
|
||
binaries+=("${binary}"); | ||
|
||
done | ||
} | ||
|
||
|
||
function check_hardened_runtime { | ||
# check_hardened_runtime | ||
# | ||
|
||
declare -r binary_to_check=${1:?binary_to_check not passed to check_hardened_runtime} | ||
|
||
if codesign --display --verbose "${binary_to_check}" 2>&1 | awk 'FNR == 4 {print $4}' | grep --quiet 'runtime'; then | ||
# awk: print 4th column of 4th line | ||
# e.g. flags=0x0(none), flags=0x10000(runtime), flags=0x12000(library-validation,runtime) | ||
# For bitmask values see: | ||
# https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/kern/cs_blobs.h | ||
return 0 | ||
else | ||
return 1 | ||
fi | ||
} | ||
|
||
|
||
function check_entitlements { | ||
# check_entitlements | ||
|
||
declare -r binary=${1:?binary_to_check not passed to check_entitlements} | ||
|
||
declare -a entitlements | ||
entitlements=(com.apple.security.cs.allow-dyld-environment-variables\ | ||
com.apple.security.cs.disable-library-validation\ | ||
com.apple.private.security.clear-library-validation\ | ||
com.apple.security.get-task-allow\ | ||
com.apple.security.cs.allow-unsigned-executable-memory\ | ||
com.apple.security.files.downloads.read-only\ | ||
com.apple.security.files.all\ | ||
com.apple.security.files.user-selected.read-only\ | ||
com.apple.private.security.clear-library-validation\ | ||
com.apple.private.tcc.allow) | ||
|
||
codesign_entitlements_output=$(/usr/bin/codesign --display --entitlements - "${binary}" 2>&1) | ||
current_binary="${binary}" | ||
|
||
for entitlement in "${entitlements[@]}"; do | ||
|
||
if echo "${codesign_entitlements_output}" | grep --quiet "${entitlement}"; then | ||
|
||
if [[ "${current_binary}" = "${binary}" ]]; then | ||
|
||
echo | ||
if check_hardened_runtime "${binary}"; then | ||
echo "${binary} (${GREEN}Hardened Runtime${RESET})" | ||
else | ||
echo "${binary}" | ||
fi | ||
|
||
current_binary="" | ||
fi | ||
echo "${entitlement}" | ||
fi | ||
done | ||
} | ||
|
||
|
||
function main { | ||
|
||
trap ctrl_c SIGINT | ||
# Detect and react to the user hitting CTRL + C | ||
|
||
declare -a binaries | ||
|
||
get_binaries | ||
|
||
for binary in "${binaries[@]}"; do | ||
check_entitlements "${binary}" | ||
done | ||
|
||
} | ||
|
||
main "$@" |