30 Commits
v0.7 ... v0.8

Author SHA1 Message Date
Karmaz95
eaf5c68c74 Adding App Bundle Ext. link 2024-07-26 13:24:38 +02:00
Karmaz95
2f70ddaa65 Update with Sandbox Detector 2024-07-23 14:27:22 +02:00
Karmaz95
71a7c31448 Adding code related to Sandbox Detector article 2024-07-23 14:22:50 +02:00
Karmaz95
6f9a04bb3c Adding link to Sandbox Detector article 2024-07-23 14:19:13 +02:00
Karmaz95
75b72b56c5 Patching bug in binaryInit 2024-07-20 23:18:30 +02:00
Karmaz95
af8e89ab67 New usage for CrimsonUroboros 2024-07-20 21:17:46 +02:00
Karmaz95
80bc340015 Redo changes to latest release, for a clean start 2024-07-20 21:14:58 +02:00
Karmaz95
30b1720e5b SnakeHatchery patch 2024-07-20 21:12:22 +02:00
Karmaz95
7fbc231ed6 Updating tools section. 2024-07-20 14:07:01 +02:00
Karmaz95
04f7318c24 Adding +x permissions to scripts. 2024-07-20 14:05:37 +02:00
Karmaz95
588f097c06 Script for packing the app in a compressed DMG container 2024-07-20 13:48:02 +02:00
Karmaz95
4a126b3502 Bash template for building a PoC app bundle with Mach-O binary that utilizes Framework 2024-07-20 13:47:41 +02:00
Karmaz95
001df7e406 Small change with Articles in README.md 2024-07-20 13:32:28 +02:00
Karmaz95
77d0c07cb8 Adding links and tags for Cracking Electron Integrity 2024-07-20 12:51:10 +02:00
Karmaz95
b08a5767ef Code related to Bypassing Electron Integrity article 2024-07-19 18:42:49 +02:00
Karmaz95
8abdf68fad Commented code bug fix in main 2024-07-19 00:33:45 +02:00
Karmaz95
dd49f449c3 Preparing CrimsonUroboros for SnakeVIII - Sandbox article 2024-07-18 20:25:41 +02:00
Karmaz95
75531c136f Updating tests for the latest CrimsonUroboros from App Bundle Extension 2024-07-18 20:16:11 +02:00
Karmaz95
84bf22e427 Adding make_bundle.sh script for building a codeless app bundle 2024-07-18 20:12:42 +02:00
Karmaz95
1e97057f70 Extending CrimsonUroboros with the App Bundle parser 2024-07-18 20:12:00 +02:00
Karmaz95
700a4c045b Moving article tags from Readme.md to Article_tags.md 2024-07-18 20:07:58 +02:00
Karmaz95
03804fca9a Moving article tags from Readme.md to Article_tags.md 2024-07-18 20:04:45 +02:00
Karmaz95
c1ef70f01d App Bundle Extension initial commit 2024-07-11 09:46:31 +02:00
Karmaz95
596a88a648 Adding new tools and links 2024-07-09 18:28:10 +02:00
Karmaz95
51b994cc7b Added sbpl_compiler_wrapper 2024-07-09 18:21:39 +02:00
Karmaz95
8b02698095 Added sandbox_inspector.py 2024-07-09 16:03:12 +02:00
Karmaz95
7adf70fd79 Add make_plist.py script 2024-07-09 15:25:53 +02:00
Karmaz95
5a1ce99e8d Decompiled functions uploaded to VIII. Sandbox 2024-07-09 12:16:02 +02:00
Karmaz95
9ac687389c Decompiled functions uploaded to VIII. Sandbox 2024-07-09 12:13:47 +02:00
Karmaz95
d89de63909 2024-06-28 13:07:24 +02:00
19 changed files with 9701 additions and 231 deletions

View File

@@ -0,0 +1,36 @@
// https://medium.com/@karol-mazurek/cracking-macos-apps-39575dd672e0
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var crypto = require("crypto");
var asar = require("asar");
var fs = require("fs");
// Function to generate the integrity hash
var generateAsarIntegrity = function (asarPath) {
var headerString = asar.getRawHeader(asarPath).headerString;
var hash = crypto
.createHash('sha256')
.update(headerString)
.digest('hex');
return {
algorithm: 'SHA256',
hash: hash
};
};
// Main script execution
var main = function () {
if (process.argv.length !== 3) {
console.error('Usage: node calculate_hash.ts <path_to_asar_file>');
process.exit(1);
}
var asarPath = process.argv[2];
// Check if the file exists
if (!fs.existsSync(asarPath)) {
console.error("File not found: ".concat(asarPath));
process.exit(1);
}
var result = generateAsarIntegrity(asarPath);
console.log("Algorithm: ".concat(result.algorithm));
console.log("Hash: ".concat(result.hash));
};
// Run the script
main()

View File

@@ -0,0 +1,30 @@
import sys
import struct
import hashlib
def getASARHeaderSize(file_path):
with open(file_path, 'rb') as f:
asar_header = f.read(16)
asar_header_size_bytes = asar_header[12:16]
header_size = struct.unpack('<I', asar_header_size_bytes)[0]
return(header_size)
def readASARHeader(file_path, header_size):
with open(file_path, 'rb') as f:
f.seek(16)
asar_header = f.read(header_size)
return(asar_header)
def calcASARHeaderHash(asar_header):
return(hashlib.sha256(asar_header).hexdigest())
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python3 ElectronAsarIntegrityCalculator.py PATH_TO_ASAR_FILE")
sys.exit(1)
file_path = sys.argv[1]
asar_header_size = getASARHeaderSize(file_path)
asar_header_bytes = readASARHeader(file_path, asar_header_size)
asar_header_hash = calcASARHeaderHash(asar_header_bytes)
print(asar_header_hash)

View File

@@ -0,0 +1,81 @@
#!/bin/bash
# This script installs the necessary tools, sets up the project, creates the TypeScript file, compiles it, and runs the script with the specified ASAR file path.
# https://medium.com/@karol-mazurek/cracking-macos-apps-39575dd672e0
# Define the TypeScript file and ASAR path
TS_FILE="calculate_hash.ts"
ASAR_PATH="$1"
# Step 1: Install Node.js and npm (if not installed)
echo "Ensure Node.js and npm are installed..."
# Step 2: Install TypeScript and ts-node globally
echo "Installing TypeScript and ts-node globally..."
npm install -g typescript ts-node
# Step 3: Initialize npm project (if not already done)
if [ ! -f "package.json" ]; then
echo "Initializing npm project..."
npm init -y
fi
# Step 4: Install dependencies
echo "Installing asar and @types/node..."
npm install asar
npm install --save-dev @types/node
# Step 5: Create TypeScript file
cat <<EOL > $TS_FILE
import * as crypto from 'crypto';
import * as asar from 'asar';
import * as fs from 'fs';
// Function to generate the integrity hash
const generateAsarIntegrity = (asarPath: string) => {
const headerString = asar.getRawHeader(asarPath).headerString;
const hash = crypto
.createHash('sha256')
.update(headerString)
.digest('hex');
return {
algorithm: 'SHA256' as const,
hash
};
};
// Main script execution
const main = () => {
if (process.argv.length !== 3) {
console.error('Usage: node calculate_hash.ts <path_to_asar_file>');
process.exit(1);
}
const asarPath = process.argv[2];
// Check if the file exists
if (!fs.existsSync(asarPath)) {
console.error(\`File not found: \${asarPath}\`);
process.exit(1);
}
const result = generateAsarIntegrity(asarPath);
console.log(\`Algorithm: \${result.algorithm}\`);
console.log(\`Hash: \${result.hash}\`);
};
// Run the script
main();
EOL
# Step 6: Compile TypeScript to JavaScript
echo "Compiling TypeScript to JavaScript..."
tsc $TS_FILE
# Step 7: Run the JavaScript file
echo "Running the script with ASAR path: $ASAR_PATH"
node calculate_hash.js "$ASAR_PATH"
echo "Done."

View File

@@ -0,0 +1,116 @@
import sys
import struct
import hashlib
import argparse
import os
class ASARCalculator:
def __init__(self, file_path):
self.file_path = file_path
self.asar_header_size = self.getASARHeaderSize()
self.asar_header_bytes = self.readASARHeader()
self.asar_header_hash = self.calcASARHeaderHash()
def getASARHeaderSize(self):
with open(self.file_path, 'rb') as f:
asar_header = f.read(16)
asar_header_size_bytes = asar_header[12:16]
header_size = struct.unpack('<I', asar_header_size_bytes)[0]
return header_size
def readASARHeader(self):
with open(self.file_path, 'rb') as f:
f.seek(16)
asar_header = f.read(self.asar_header_size)
return asar_header
def calcASARHeaderHash(self):
return hashlib.sha256(self.asar_header_bytes).hexdigest()
class ASARPatcher:
def __init__(self):
pass
def extractASAR(self, app_path, output_path):
'''Extracts {input_path} asar file to {output_path} directory.'''
input_path = os.path.join(app_path, "Contents/Resources/app.asar")
status_code = os.system(f"npx asar extract {input_path} {output_path}")
if status_code == 0:
print(f"Extracted {input_path} to {output_path} directory.")
else:
print(f"Failed to extract {input_path} to {output_path} directory. Error code: {status_code}")
def dumpEntitlements(self, app_path):
output_path='/tmp/extracted_entitlements.xml'
status_code = os.system(f"codesign -d --entitlements :- {app_path} > {output_path}")
if status_code == 0:
print(f"Dumped entitlements from {app_path} to {output_path}")
else:
print(f"Failed to dump entitlements from {app_path} to {output_path}. Error code: {status_code}")
def checkIfElectronAsarIntegrityIsUsed(self, app_path):
status_code = os.system(f"plutil -p {app_path}/Contents/Info.plist | grep -q ElectronAsarIntegrity")
if status_code == 0:
return True
else:
return False
def packASAR(self, input_path, app_path):
'''Packs {input_path} directory to {output_path} asar file.
Check if ElectronAsarIntegrity is used in Info.plist, and if so, calculate hash and replace it.
Codesign the
'''
output_path = os.path.join(app_path, "Contents/Resources/app.asar")
info_plist_path = os.path.join(app_path, "Contents/Info.plist")
status_code = os.system(f"npx asar pack {input_path} {output_path}")
if status_code == 0:
print(f"Packed {input_path} into {output_path}")
if self.checkIfElectronAsarIntegrityIsUsed(app_path):
print("ElectronAsarIntegrity is used in Info.plist. Calculating hash and replacing it.")
asar_calculator = ASARCalculator(output_path)
new_hash = asar_calculator.calcASARHeaderHash()
print(f"New hash: {new_hash}")
print("Replacing ElectronAsarIntegrity in Info.plist")
os.system(f"/usr/libexec/PlistBuddy -c 'Set :ElectronAsarIntegrity:Resources/app.asar:hash {new_hash}' {info_plist_path}")
print("Resigning app")
self.dumpEntitlements(app_path)
os.system(f"codesign --force --entitlements /tmp/extracted_entitlements.xml --sign - {app_path}")
os.remove('/tmp/extracted_entitlements.xml')
print("Done!")
def main():
parser = argparse.ArgumentParser(description="ASAR File Operations")
subparsers = parser.add_subparsers(dest='command')
# Subparser for the extract command
extract_parser = subparsers.add_parser('extract', help='Extract an ASAR file')
extract_parser.add_argument('input_path', type=str, help='Path to the ASAR file to extract')
extract_parser.add_argument('output_path', type=str, help='Directory to extract the ASAR file into')
# Subparser for the pack command
pack_parser = subparsers.add_parser('pack', help='Pack files into an ASAR file')
pack_parser.add_argument('input_directory', type=str, help='Directory to pack into an ASAR file')
pack_parser.add_argument('output_path', type=str, help='Path to the output ASAR file')
args = parser.parse_args()
patcher = ASARPatcher()
if args.command == 'extract':
patcher.extractASAR(args.input_path, args.output_path)
elif args.command == 'pack':
patcher.packASAR(args.input_directory, args.output_path)
else:
print("Invalid command. Use 'extract' or 'pack'.")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,87 @@
#!/bin/bash
### --- CREATE APP ICON --- ###
# Create a red icon using Python
python3 -c "from PIL import Image; Image.new('RGB', (1024, 1024), 'red').save('red_icon.png')"
# Prepare iconset directory
mkdir -p red_icon.iconset
# Convert the red icon to all necessary sizes and place them in the iconset directory
sips -z 16 16 red_icon.png --out red_icon.iconset/icon_16x16.png
sips -z 32 32 red_icon.png --out red_icon.iconset/icon_16x16@2x.png
sips -z 32 32 red_icon.png --out red_icon.iconset/icon_32x32.png
sips -z 64 64 red_icon.png --out red_icon.iconset/icon_32x32@2x.png
sips -z 128 128 red_icon.png --out red_icon.iconset/icon_128x128.png
sips -z 256 256 red_icon.png --out red_icon.iconset/icon_128x128@2x.png
sips -z 256 256 red_icon.png --out red_icon.iconset/icon_256x256.png
sips -z 512 512 red_icon.png --out red_icon.iconset/icon_256x256@2x.png
sips -z 512 512 red_icon.png --out red_icon.iconset/icon_512x512.png
sips -z 1024 1024 red_icon.png --out red_icon.iconset/icon_512x512@2x.png
# Convert iconset to icns
iconutil -c icns red_icon.iconset
# Clean up temporary files
rm -r red_icon.iconset red_icon.png
### --- MAKING BUNDLE --- ###
# Prepare a minimal bundle structure
mkdir -p bare_bone.app/Contents/MacOS
# Create a simple script that opens Calculator
echo '#!/bin/bash\nopen -a Calculator' > bare_bone.app/Contents/MacOS/bare_bone
# Add executable permissions to binary/script
chmod +x bare_bone.app/Contents/MacOS/bare_bone
# Creating Info.plist
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>bare_bone_exe</string>
</dict>
</plist>' > bare_bone.app/Contents/Info.plist
# Renaming executable
mv bare_bone.app/Contents/MacOS/bare_bone bare_bone.app/Contents/MacOS/bare_bone_exe
# Creating Resources directory
mkdir -p bare_bone.app/Contents/Resources
# Move icon to Resources
mv red_icon.icns bare_bone.app/Contents/Resources/red_icon.icns
# Update Info.plist to use new icon
plutil -insert CFBundleIconFile -string "red_icon" bare_bone.app/Contents/Info.plist
# Creating Frameworks directory
mkdir -p bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/Resources
# Create a script in the framework that opens Clock
echo '#!/bin/bash\nopen -a Clock' > bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/ClockOpen
chmod +x bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/ClockOpen
# Create necessary symbolic links in the framework
ln -s A bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/Current
ln -s Versions/Current/ClockOpen bare_bone.app/Contents/Frameworks/ClockOpen.framework/ClockOpen
ln -s Versions/Current/Resources bare_bone.app/Contents/Frameworks/ClockOpen.framework/Resources
# Creating Info.plist for Framework
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>ClockOpen</string>
</dict>
</plist>' > bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/Resources/Info.plist
# Modify the main executable to use the script from ClockOpen Framework
echo 'SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"' >> bare_bone.app/Contents/MacOS/bare_bone_exe
echo '"$SCRIPT_DIR/../Frameworks/ClockOpen.framework/ClockOpen"' >> bare_bone.app/Contents/MacOS/bare_bone_exe
# Sign the application
codesign -f -s - --deep bare_bone.app

View File

@@ -0,0 +1,77 @@
#!/bin/bash
### --- SETUP BUNDLE STRUCTURE --- ###
mkdir -p bare_bone.app/Contents/MacOS
mkdir -p bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/{Headers,Resources}
# Create the header file for the dynamic library
cat << 'EOF' > bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/Headers/ClockOpen.h
void openClock();
EOF
# Create the C source file for the dynamic library
cat << 'EOF' > ClockOpen.c
#include <stdlib.h>
void openClock() {
system("open -a Clock");
}
EOF
# Compile the dynamic library
clang -dynamiclib -o bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/ClockOpen ClockOpen.c
# Set the install name for the framework
install_name_tool -id @rpath/ClockOpen.framework/Versions/A/ClockOpen bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/ClockOpen
# Create necessary symbolic links in the framework
ln -s A bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/Current
ln -s Versions/Current/ClockOpen bare_bone.app/Contents/Frameworks/ClockOpen.framework/ClockOpen
ln -s Versions/Current/Headers bare_bone.app/Contents/Frameworks/ClockOpen.framework/Headers
ln -s Versions/Current/Resources bare_bone.app/Contents/Frameworks/ClockOpen.framework/Resources
# Create Info.plist for the Framework
cat << 'EOF' > bare_bone.app/Contents/Frameworks/ClockOpen.framework/Versions/A/Resources/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>ClockOpen</string>
</dict>
</plist>
EOF
# Create the C source file for the main binary
cat << 'EOF' > bare_bone.c
#include <stdio.h>
#include <stdlib.h>
#include "ClockOpen/ClockOpen.h"
int main() {
system("open -a Calculator");
openClock();
return 0;
}
EOF
# Compile the main binary and link it to the framework
clang -o bare_bone.app/Contents/MacOS/bare_bone_exe bare_bone.c -Fbare_bone.app/Contents/Frameworks -framework ClockOpen -Wl,-rpath,@executable_path/../Frameworks
# Clean up C source files
rm bare_bone.c ClockOpen.c
# Creating Info.plist for the App
cat << 'EOF' > bare_bone.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>bare_bone_exe</string>
</dict>
</plist>
EOF
# Sign the application
codesign -f -s - --deep bare_bone.app

View File

@@ -0,0 +1,16 @@
#!/bin/bash
# Variables
APP_NAME="bare_bone.app"
DMG_NAME="bare_bone.dmg"
TEMP_DIR="temp_dmg"
# Create a temporary directory and copy the app bundle into it
mkdir "$TEMP_DIR"
cp -R "$APP_NAME" "$TEMP_DIR"
# Create the DMG file
hdiutil create "$DMG_NAME" -srcfolder "$TEMP_DIR" -format UDZO -volname "Bare Bone App"
# Clean up
rm -rf "$TEMP_DIR"

File diff suppressed because it is too large Load Diff

421
Article_tags.md Normal file
View File

@@ -0,0 +1,421 @@
### [App Bundle Extension]()
* Application Bundle
* App Bundle Structure
* Info.plist
* CFBundleExecutable
* plutil
* __info_plist
* Gatekeeper Bypass (not)using Info.plist
* Resources
* Dirty NIB
* Frameworks
* CFBundlePackageType
* FMWK
* PlugIns
* pluginkit
* _CodeSignature
* CodeDirectory
* CodeRequirements
* CodeResources
* CodeSignature
* CodeEntitlements
* Inconsistency in codesign
* Re-signing apps
* Re-signing system applications
* make_bundle.sh
___
### [Cracking macOS apps](https://karol-mazurek.medium.com/cracking-macos-apps-39575dd672e0?sk=v2%2F727dce55-53ee-45f6-b051-2979e62f2ba1)
* Binary patching methods
* Application patching methods
* Resigning the app without losing entitlements
* Resigning the app for debugging
* Electron Apps
* /Contents/Resources/app.asar
___
### [Cracking Electron Integrity](https://karol-mazurek.medium.com/cracking-electron-integrity-0a10e0d5f239?sk=v2%2F7726b99c-c6c9-4d70-8c37-da9f2f0874e8)
getRawHeader | node:crypto | generateAsarIntegrity | electron_patcher | ElectronAsarIntegrity
___
### [I. Mach-O](https://karol-mazurek95.medium.com/snake-apple-i-mach-o-a8eda4b87263?sk=v2%2Ffc1cbfa4-e2d4-4387-9a82-b27191978b5b)
* Universal Binary (Fat Binary)
* Memory Pages
* mprotect()
* mmap()
* Mach-O structure
* mach_header_64
* Magic
* cputype
* cpusubtype
* filetype
* flags
* load_command
* segment_command_64
* section_64
* __PAGEZERO
* __TEXT
* __DATA_CONST
* __DATA
* __RESTRICT
* __LINKEDIT
* Chained Fixups
* Binding
* Rebasing
* LC_DYLD_CHAINED_FIXUPS
* dyld_chained_fixups_header
* LC_DYLD_CHAINED_FIXUPS
* dyld_chained_starts_in_image
* dyld_chained_starts_in_segment
* dyld_info
* LC_DYLD_EXPORTS_TRIE
* LC_SYMTAB
* symtab_command
* nlist_64
* ntype
* n_desc
* REFERENCE_TYPE
* REFERENCED_DYNAMICALLY
* N_NO_DEAD_STRIP
* N_DESC_DISCARDED
* N_WEAK_REF
* N_WEAK_DEF
* N_REF_TO_WEAK
* LIBRARY_ORDINAL
* LC_DYSYMTAB
* DYNAMIC LINKER & ENVIRONMENT VARIABLES
* LC_LOAD_DYLINKER
* dylinker_command
* LC_ID_DYLINKER
* LC_DYLD_ENVIRONMENT
* UUID
* uuid_command
* uuidgen
* BUILD VERSION
* LC_BUILD_VERSION
* build_version_command
* build_tool_version
* build_version_command
* Source Version
* LC_SOURCE_VERSION
* source_version_command
* ENTRY POINT
* LC_MAIN
* entry_point_command
* Dynamic Libraries
* dylib_command
* Function Addresses
* LC_FUNCTION_STARTS
* linkedit_data_command
* DATA_IN_CODE
* data_in_code_entry
* ENDIANESS
___
### [II. Code Signing](https://karol-mazurek95.medium.com/snake-apple-ii-code-signing-f0a9967b7f02?sk=v2%2Fbbc87007-89ca-4135-91d6-668b5d2fe9ae)
* CS_CodeDirectory
* CDHash
* signature
* CMS
* Certificate Chain of Trust
* Ad hoc signing
* TrustCacheParser
* Notarization
* Code Signature
* LC_CODE_SIGNATURE
* Super Blob
* Code Directory
* Requirement
* Entitlements (XML and DER)
* CMS Signature
* Info.plist
* cs_flags
* CodeResources
* ASN.1 and DER
* openssl
* RFC 56525.4. Message Digest Calculation Process.
* signedAttrs
___
### [III. Checksec](https://karol-mazurek95.medium.com/snake-apple-iii-checksec-ed64a4b766c1?sk=v2%2Fb4b8d637-e906-4b6b-8088-ca1f893cd787)
* PIE — Position-Independent Executable
* -fno-pie
* ModifyMachOFlags
* MH_PIE
* ARC — Automatic Reference Counting
* -fobjc-arc
* _objc_release
* SS — Stripped Symbols
* __mh_execute_header
* SC — Stack Canary / Stack Cookie
* ___stack_chk_fail
* ___stack_chk_guard
* NX stack
* -allow_stack_execute
* MH_ALLOW_STACK_EXECUTION
* NX heap
* NO_HEAP_EXECUTION
* XN — Execute Never
* mmap.PROT_READ
* mmap.PROT_WRITE
* mmap.PROT_EXEC
* com.apple.security.cs.allow-jit
* Code Signature
* Notarization
* notarytool
* notary services REST API.
* spctl
* Encryption
* cryptid
* ipatool
* LC_ENCRYPTION_INFO
* Restrict
* __RESTRICT
* -sectcreate
* Hardened Runtime
* App Sandbox
* com.apple.security.app-sandbox
* Fortify
* -D_FORTIFY_SOURCE
* RPath
___
### [IV. Dylibs](https://karol-mazurek.medium.com/snake-apple-iv-dylibs-2c955439b94e?sk=v2%2Fdef72b7a-121a-47a1-af89-7bf53aed1ea2)
* Libraries — Static vs Dynamic
* Frameworks
* Dylib Hijacking
* com.apple.security.cs.disable-library-validation
* com.apple.private.security.clear-library-validation
* DYLD_PRINT_SEARCHING
* libSystem.B.dylib
* Dyld Shared Cache
* /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/
* /System/Volumes/Preboot/Cryptexes/OS/System/DriverKit/System/Library/dyld/
* ipsw
* dyld-shared-cache-extractor
* dyld_cache_format.h.
* Loading Process
* dylibtree
* MachOFile.cpp
* Loader.cpp
* Header.cpp
* MachODylibLoadCommandsFinder
* Load Commands
* LC_LOAD_DYLIB
* LC_LOAD_WEAK_DYLIB
* LC_REEXPORT_DYLIB
* LC_LOAD_UPWARD_DYLIB
* LC_ID_DYLIB
* dylib_command
* loader_path
* executable_path
* install_name_tool
* current_version
* compatibility_version
* enforceCompatVersion
* CVE-202326818
* dlopen
* DYLD_PRINT_APIS
* dtruss
* fs_usage
___
### [V. Dyld](https://karol-mazurek.medium.com/snake-apple-v-dyld-8b36b674cc44?sk=v2%2F4acb16f8-fa88-41f0-8d7c-1362f4060010)
* /usr/lib/dyld
* com.apple.darwin.ignition
* dylinker_command
* LC_DYLD_ENVIRONMENT
* dyldStartup.s
* __dyld_start
* dyldMain.cpp
* dyld_usage
* dyld_info
* vmmap
* lldb
* symbols
* Memory Layouts
* DYLD_IN_CACHE
* Interposing
* DYLD_PRINT_INTERPOSING
* DYLD_INSERT_LIBRARIES
___
### [DYLD — Do You Like Death? (I)](https://karol-mazurek.medium.com/dyld-do-you-like-death-i-8199faad040e?sk=v2%2F359b081f-d944-409b-9e7c-95f7c171b969)
Startup | kernArgs | rebaseSelf | initializeLibc | task_self_trap | stack_guard | findArgv | findEnvp | findApple
___
### [DYLD — Do You Like Death? (II)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ii-b74360b8af47?sk=v2%2Ff0cff71c-5345-4228-a639-653325fc979d)
handleDyldInCache| isBuiltForSimulator | isTranslated | crossarch_trap | Calling Convention on ARM64v8 | __unused attribute | Dyld Shared Region | thisDyldUuid | hasExistingDyldCache | shared_region_check_np | Carry flag | dynamic data header | dyldInCacheMH
___
### [DYLD — Do You Like Death? (III)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iii-af77701a3034?sk=v2%2F06c92503-2db9-40e2-b139-c9ae0a35e7b3)
handleDyldInCache | DYLD_IN_CACHE | restartWithDyldInCache | dyld_all_image_infos | calculating offset for debugging Dyld in Cache
___
### [DYLD — Do You Like Death? (IV)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iv-ede6b157752c?sk=v2%2F87ebe38d-004c-41a6-bc1f-43898494a512)
RuntimeLocks | MemoryManager | dyld_hw_tpro | Lambda Capture | withWritableMemory | PAC | arm64e_preview_abi | __ptrauth_dyld_tpro0 | WriteProtectionState | previousState | os_compiler_barrier
___
### [DYLD — Do You Like Death? (V)](https://karol-mazurek.medium.com/dyld-do-you-like-death-v-c40a267573cb?sk=v2%2F4c9f16b2-59bd-406a-945d-10a1fba1001b)
Linker Standard Library | EphemeralAllocator | Dyld Private Memory | PersistentAllocator | vm_allocate | vm_protect | _kernelrpc_mach_vm_allocate_trap | _kernelrpc_mach_vm_protect_trap
___
### [DYLD — Do You Like Death? (VI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vi-1013a69118ff?sk=v2%2F37b3a61f-8483-4b38-977d-7f860944862b)
ProcessConfig | Process::Process | Process::Security | csr_check | CSR_ALLOW_APPLE_INTERNAL | csrctl | syscall_csr_check | AMFI | internalInstall | isRestricted | isFairPlayEncrypted | amfiFlags | amfi_check_dyld_policy_self | ___sandbox_ms | ___mac_syscall | mpo_policy_syscall_t | MAC policy | com.apple.driver.AppleMobileFileIntegrity | _policy_syscall | _check_dyld_policy_internal | macos_Dyld_policy_collect_state | logDyldPolicyData | DYLD_AMFI_FAKE | getAMFI | pruneEnvVars | com.apple.security.cs.allow-dyld-environment-variables
___
### [DYLD — Do You Like Death? (VII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vii-62c202f98610?sk=v2%2Fab26bfcf-ba56-493d-9af3-2d8790ca6208)
ProcessConfig | Process::Logging | Process::dyldCache | DYLD_PRINT_TO_STDERR | DYLD_PRINT_INTERPOSING | allowEnvVarsSharedCache | allowEnvVarsPrint | openLogFile | DYLD_PRINT_TO_FILE | BSD open syscall | DYLD_SHARED_REGION | Shared Library Cache | DYLD_SHARED_CACHE_DIR | dyldCache | CacheFinder | Ignite | ignitionPayload | ignition | open_console | log_init | sysctlbyname | __sysctl | dyld_parse_boot_arg_int | dyld_parse_boot_arg_cstr | libignition | boot_init | stage_fire | getDyldCache | loadDyldCache | mapSplitCachePrivate | reuseExistingCache | mapSplitCacheSystemWide | jettison
___
### [DYLD — Do You Like Death? (VIII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-viii-327d7e7f3c0f?sk=v2%2F6c6b611d-fee4-4d9d-8a36-d59a05116e23)
ProcessConfig | Process::PathOverrides | Overrides and path fallbacks for Dylibs | security.allowEnvVarsPath | crashMsg | addEnvVar | DYLD_LIBRARY_PATH | DYLD_FRAMEWORK_PATH | DYLD_FALLBACK_FRAMEWORK_PATH | DYLD_FALLBACK_LIBRARY_PATH | DYLD_VERSIONED_FRAMEWORK_PATH | DYLD_VERSIONED_LIBRARY_PATH | DYLD_INSERT_LIBRARIES | DYLD_IMAGE_SUFFIX | DYLD_ROOT_PATH | _dylibPathOverridesExeLC | _dylibPathOverridesEnv | isLC_DYLD_ENV | CRSetCrashLogMessage2 | LC_DYLD_ENVIRONMENT | allowEmbeddedVars | _insertedDylibs | cryptexOSPath | VersionedPaths | processVersionedPaths | checkVersionedPath | LC_ID_DYLIB | sys.getDylibInfo | addPathOverride | dontUsePrebuiltForApp | adjustDevelopmentMode
___
### [DYLD — Do You Like Death? (IX)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ix-5052c865100e?sk=v2%2Fe078d739-ab30-4f2d-8a12-eefc63dd73b4)
RuntimeState | ProcessConfig | finalizeListTLV | FileManager | _fsUUIDMap | OrderedMap | UUIDs | PermanentRanges | state APIs
___
### [DYLD — Do You Like Death? (X)](https://karol-mazurek.medium.com/dyld-do-you-like-death-x-76408570c357?sk=v2%2F8b69c2f1-ce13-4d05-bba1-e0164c3de381)
ExternallyViewableState | externallyViewable.init | dyld_all_image_info | exec_prefault_data | task_info | com.apple.security.get-task-allow | get_dyld_info | lsl:Vector | ProcessSnapshot | compact info | makeUnique | release | setDyldState | setInitialExternallyVisibleState | setShareCacheInfo | setDyld | inDyldCache | DYLD_IN_CACHE | recordFromInfo | FileRecord | Image | addImage | _snapshot | addImageInfo | setInitialImageCount | commit | compactInfoData | RemoteNotificationResponder
___
### [DYLD — Do You Like Death? (XI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-xi-cef76bc8dc14?sk=v2%2F0b88b392-ae94-43d0-9120-109306051e00)
prepare | APIs | isSimulatorPlatform | state.initializeClosureMode() | PrebuiltLoaders | JustInTimeLoader | PrebuilLoaderSet | dyld3 | dyld4 | Closures | initializeClosureMode | Loaders | validHeader | hasValidMagic | kmagic | dontUsePrebuiltForApp | findLaunchLoaderSet | cachePBLS | hasLaunchLoaderSetWithCDHash | findLaunchLoaderSetWithCDHash | findLaunchLoaderSet | allowOsProgramsToSaveUpdatedClosures | reserve | bit_ceil | allowNonOsProgramsToSaveUpdatedClosures | DYLD_USE_CLOSURES | reserveExact | getOnDiskBinarySliceOffset | STACK_ALLOC_OVERFLOW_SAFE_ARRAY | topLevelLoaders | loadDependents | notifyDebuggerLoad | notifyDtrace | DOF | addPermamentRanges | STACK_ALLOC_ARRAY | weakDefMap | buildInterposingTables | handleStrongWeakDefOverrides | visibility | applyFixups | applyCachePatches | doSingletonPatching | applyInterposingToDyldCache | Libdyld.dylib | libdyld4Section | allImageInfos | storeProcessInfoPointer | __chkstk_darwin | partitionDelayLoads | DYLD_JUST_BUILD_CLOSURE | prewarming | notifyMonitorNeeded | LC_MAIN | LC_THREAD | getEntry | appMain | restorePreviousState | TPRO | libSystemHelpers | __exit
___
### [VI. AMFI](https://karol-mazurek.medium.com/snake-apple-vi-amfi-31c48fb92d33?sk=v2%2F8116bf86-e0a7-42be-ada9-5348447c01fd)
* Kernel Extension
* AppleMobileFileIntegrity.kext
* /System/Library/Extensions
* Kext binary extraction
* Kernelcache.
* kextstat
* Dependent kexts
* KEXT_BUNDLE
* Mach-O analysis
* Kext Information Property List
* __PRELINK_INFO
* kmod_info
* _PrelinkKmodInfo
* AMFI Startup
* Entrypoint
* OSBundleRequired
* IOKitPersonalities
* ioreg
* kxld
* OSKext::start
* __realmain
* initializeAppleMobileFileIntegrity
* mac_policy_init
* kernel_startup_initialize_upto
* kernel_bootstrap_thread
* mac_policy_initmach
* load_security_extensions_function
* load_security_extensions_function
* bootstrapLoadSecurityExtensions
* bootstrapLoadSecurityExtensions
* loadSecurityExtensions
* OSKext::loadKextWithIdentifier
* register_kmod
* OSRuntimeInitializeCPP
* vftable
* KEXT_NAME::start(IOService*)
* Turning off AMFI
* amfi_get_out_of_my_way
* nvram boot-args=""
* MAC policy syscall
* __mac_syscall
* mpo_cred_label_init_t
* PROTECTIONS
* macos_dyld_policy_collect_state
* DYLD_INSERT_LIBRARIES
* cs.allow-relative-library-loads
* policy_syscall
* SUID GUID
* Signature Validation
* vnode_check_signature
* mpo_vnode_check_signature_t
* cs_validate_page
* com.apple.private.amfi.can-execute-cdhash
* com.apple.rootless.storage.cvms
* jit-codesigning
* com.apple.security.get-task-allow
* com.apple.private.oop-jit.loader
* com.apple.private.amfi.can-execute-cdhash
* com.apple.dyld_sim
* com.apple.private.oop-jit.runner
* Launch Constraints
* _proc_check_launch_constraints
* Amfid
* /usr/libexec/amfid
* verify_code_directory
* _MIG_subsystem_1000
* routine_descriptor
* mach_msg
___
### [VII. Antivirus](https://karol-mazurek.medium.com/snake-apple-vii-antivirus-0a57acc10185?sk=v2%2F2c46d7ac-4435-41e6-bbda-2acb4eb78c76)
* GATEKEEPER
* Application Whitelisting
* Quarantine attribute
* com.apple.quarantine
* De-Quarantining
* xattr
* ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV*
* LSQuarantine.h
* LAUNCH SERVICES
* Reversing DSC
* libquarantine.dylib
* App Translocation
* QUARANTINE KEXT
* Tracing hooks
* hook_vnode_check_exec
* sandbox_enforce
* Double call mystery of apply_exec_quarantine
* quarantine_get_flags
* getxattr
* Flags default values for quarantined volume
* Quarantine flags logic
* SYSTEM POLICY
* System Policy Database
* System Policy Daemon
* System Policy Manager (spctl)
* XProtect
* gk.db
* XProtect.meta.plist
* XProtect.yara
* XProtect.plist
* Logging
* CoreSerivcesUIAgent
* Eicar test
* Malware creator test
___
### [VIII. Sandbox]()
___
### [SBPL Compilator](https://karol-mazurek.medium.com/sbpl-compilator-c05f5304d057?sk=v2%2F4ae3bf90-ff12-4fea-b0fc-0f2ef60d7b93)
* .com.apple.containermanagerd.metadata.plist
* SandboxProfileData
* /System/Library/Sandbox/Profiles/
* sandbox_compile_file
* com.apple.security.get-task-allow
* sandbox-exec
* Sandbox.kext
___
### [Sandbox Detector](https://karol-mazurek.medium.com/sandbox-detector-4268ab3cd361?sk=v2%2F58fe49fb-1381-4db3-9db9-3f6309e4053a)
libsystem_sandbox.dylib | com.apple.security.app-sandbox | Activity Monitor.app | _sandbox_check | /usr/lib/libSystem.B.dylib | dyld-shared-cache-extractor | arm64e_preview_abi | kernel_task | sandbox_operation_fixup_0 | CTL_KERN | KERN_PROC | KERN_PROC_PID | struct kinfo_proc info | kinfo_getproc | sysctl | mib | sandbox_check_common_0
___
### [IX. TCC]()
___
### [X. NU]()
___
### [Kernel Debugging Setup on MacOS](https://karol-mazurek.medium.com/kernel-debugging-setup-on-macos-07dd8c86cdb6?sk=v2%2F782bf539-a057-4f14-bbe7-f8e1ace26701)
* KDK
* sw_vers
* BuildVersion
* /Library/Developer/KDKs/
* /var/tmp/PanicDumps
* com.apple.kdumpd
* kdp_match_name
* DB_NMI_BTN_ENA
* DB_REBOOT_POST_CORE
* DB_ARP
* DB_NMI
* _panicd_ip
* DB_DBG_POST_CORE
* InstantPanic/build/InstantPanic.kext

134
README.md
View File

@@ -8,33 +8,40 @@ Each article directory contains three subdirectories:
* `python` - contains the latest CrimsonUroboros and other Python scripts created during research.
## ARTICLES
The short introduction is written in [Snake&Apple Intro](https://karol-mazurek95.medium.com/snake-apple-ff87a399ecc4?sk=v2%2Fb2295773-88e6-4654-9d3d-61d73b9001e5)
The tags for each article are in the [Article_tags.md](Article_tags.md).
The table of contents showing links to all articles is below:
* &#9745; [App Bundle Extension](https://karol-mazurek.medium.com/snake-apple-app-bundle-ext-f5c43a3c84c4?sk=v2%2F3ff105ad-f4f0-464d-b4d5-46b86c66fe14)
* &#9745; [Cracking macOS apps](https://karol-mazurek.medium.com/cracking-macos-apps-39575dd672e0?sk=v2%2F727dce55-53ee-45f6-b051-2979e62f2ba1)
* &#9745; [Cracking Electron Integrity](https://karol-mazurek.medium.com/cracking-electron-integrity-0a10e0d5f239?sk=v2%2F7726b99c-c6c9-4d70-8c37-da9f2f0874e8)
* &#9745; [I. Mach-O](https://karol-mazurek95.medium.com/snake-apple-i-mach-o-a8eda4b87263?sk=v2%2Ffc1cbfa4-e2d4-4387-9a82-b27191978b5b)
* &#9745; [II. Code Signing](https://karol-mazurek95.medium.com/snake-apple-ii-code-signing-f0a9967b7f02?sk=v2%2Fbbc87007-89ca-4135-91d6-668b5d2fe9ae)
* &#9745; [III. Checksec](https://karol-mazurek95.medium.com/snake-apple-iii-checksec-ed64a4b766c1?sk=v2%2Fb4b8d637-e906-4b6b-8088-ca1f893cd787)
* &#9745; [IV. Dylibs](https://karol-mazurek.medium.com/snake-apple-iv-dylibs-2c955439b94e?sk=v2%2Fdef72b7a-121a-47a1-af89-7bf53aed1ea2)
* &#9745; [V. Dyld](https://karol-mazurek.medium.com/snake-apple-v-dyld-8b36b674cc44?sk=v2%2F4acb16f8-fa88-41f0-8d7c-1362f4060010)
* &#9745; [DYLD — Do You Like Death? (I)](https://karol-mazurek.medium.com/dyld-do-you-like-death-i-8199faad040e?sk=v2%2F359b081f-d944-409b-9e7c-95f7c171b969) - Startup | kernArgs | rebaseSelf | initializeLibc | task_self_trap | stack_guard | findArgv | findEnvp | findApple
* &#9745; [DYLD — Do You Like Death? (II)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ii-b74360b8af47?sk=v2%2Ff0cff71c-5345-4228-a639-653325fc979d) - handleDyldInCache| isBuiltForSimulator | isTranslated | crossarch_trap | Calling Convention on ARM64v8 | __unused attribute | Dyld Shared Region | thisDyldUuid | hasExistingDyldCache | shared_region_check_np | Carry flag | dynamic data header | dyldInCacheMH
* &#9745; [DYLD — Do You Like Death? (III)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iii-af77701a3034?sk=v2%2F06c92503-2db9-40e2-b139-c9ae0a35e7b3) - handleDyldInCache | DYLD_IN_CACHE | restartWithDyldInCache | dyld_all_image_infos | calculating offset for debugging Dyld in Cache
* &#9745; [DYLD — Do You Like Death? (IV)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iv-ede6b157752c?sk=v2%2F87ebe38d-004c-41a6-bc1f-43898494a512) - RuntimeLocks | MemoryManager | dyld_hw_tpro | Lambda Capture | withWritableMemory | PAC | arm64e_preview_abi | __ptrauth_dyld_tpro0 | WriteProtectionState | previousState | os_compiler_barrier |
* &#9745; [DYLD — Do You Like Death? (V)](https://karol-mazurek.medium.com/dyld-do-you-like-death-v-c40a267573cb?sk=v2%2F4c9f16b2-59bd-406a-945d-10a1fba1001b) - Linker Standard Library | EphemeralAllocator | Dyld Private Memory | PersistentAllocator | vm_allocate | vm_protect | _kernelrpc_mach_vm_allocate_trap | _kernelrpc_mach_vm_protect_trap
* &#9745; [DYLD — Do You Like Death? (VI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vi-1013a69118ff?sk=v2%2F37b3a61f-8483-4b38-977d-7f860944862b) - ProcessConfig | Process::Process | Process::Security | csr_check | CSR_ALLOW_APPLE_INTERNAL | csrctl | syscall_csr_check | AMFI | internalInstall | isRestricted | isFairPlayEncrypted | amfiFlags | amfi_check_dyld_policy_self | ___sandbox_ms | ___mac_syscall | mpo_policy_syscall_t | MAC policy | com.apple.driver.AppleMobileFileIntegrity | _policy_syscall | _check_dyld_policy_internal | macos_Dyld_policy_collect_state | logDyldPolicyData | DYLD_AMFI_FAKE | getAMFI | pruneEnvVars | com.apple.security.cs.allow-dyld-environment-variables
* &#9745; [DYLD — Do You Like Death? (VII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vii-62c202f98610?sk=v2%2Fab26bfcf-ba56-493d-9af3-2d8790ca6208) - ProcessConfig | Process::Logging | Process::dyldCache | DYLD_PRINT_TO_STDERR | DYLD_PRINT_INTERPOSING | allowEnvVarsSharedCache | allowEnvVarsPrint | openLogFile | DYLD_PRINT_TO_FILE | BSD open syscall | DYLD_SHARED_REGION | Shared Library Cache | DYLD_SHARED_CACHE_DIR | dyldCache | CacheFinder | Ignite | ignitionPayload | ignition | open_console | log_init | sysctlbyname | __sysctl | dyld_parse_boot_arg_int | dyld_parse_boot_arg_cstr | libignition | boot_init | stage_fire | getDyldCache | loadDyldCache | mapSplitCachePrivate | reuseExistingCache | mapSplitCacheSystemWide | jettison
* &#9745; [DYLD — Do You Like Death? (VIII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-viii-327d7e7f3c0f?sk=v2%2F6c6b611d-fee4-4d9d-8a36-d59a05116e23) - ProcessConfig | Process::PathOverrides | Overrides and path fallbacks for Dylibs | security.allowEnvVarsPath | crashMsg | addEnvVar | DYLD_LIBRARY_PATH | DYLD_FRAMEWORK_PATH | DYLD_FALLBACK_FRAMEWORK_PATH | DYLD_FALLBACK_LIBRARY_PATH | DYLD_VERSIONED_FRAMEWORK_PATH | DYLD_VERSIONED_LIBRARY_PATH | DYLD_INSERT_LIBRARIES | DYLD_IMAGE_SUFFIX | DYLD_ROOT_PATH | _dylibPathOverridesExeLC | _dylibPathOverridesEnv | isLC_DYLD_ENV | CRSetCrashLogMessage2 | LC_DYLD_ENVIRONMENT | allowEmbeddedVars | _insertedDylibs | cryptexOSPath | VersionedPaths | processVersionedPaths | checkVersionedPath | LC_ID_DYLIB | sys.getDylibInfo | addPathOverride | dontUsePrebuiltForApp | adjustDevelopmentMode
* &#9745; [DYLD — Do You Like Death? (IX)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ix-5052c865100e?sk=v2%2Fe078d739-ab30-4f2d-8a12-eefc63dd73b4) - RuntimeState | ProcessConfig | finalizeListTLV | FileManager | _fsUUIDMap | OrderedMap | UUIDs | PermanentRanges | state APIs
* &#9745; [DYLD — Do You Like Death? (X)](https://karol-mazurek.medium.com/dyld-do-you-like-death-x-76408570c357?sk=v2%2F8b69c2f1-ce13-4d05-bba1-e0164c3de381) - ExternallyViewableState | externallyViewable.init | dyld_all_image_info | exec_prefault_data | task_info | com.apple.security.get-task-allow | get_dyld_info | lsl:Vector | ProcessSnapshot | compact info | makeUnique | release | setDyldState | setInitialExternallyVisibleState | setShareCacheInfo | setDyld | inDyldCache | DYLD_IN_CACHE | recordFromInfo | FileRecord | Image | addImage | _snapshot | addImageInfo | setInitialImageCount | commit | compactInfoData | RemoteNotificationResponder
* &#9745; [DYLD — Do You Like Death? (XI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-xi-cef76bc8dc14?sk=v2%2F0b88b392-ae94-43d0-9120-109306051e00) - prepare | APIs | isSimulatorPlatform | state.initializeClosureMode() | PrebuiltLoaders | JustInTimeLoader | PrebuilLoaderSet | dyld3 | dyld4 | Closures | initializeClosureMode | Loaders | validHeader | hasValidMagic | kmagic | dontUsePrebuiltForApp | findLaunchLoaderSet | cachePBLS | hasLaunchLoaderSetWithCDHash | findLaunchLoaderSetWithCDHash | findLaunchLoaderSet | allowOsProgramsToSaveUpdatedClosures | reserve | bit_ceil | allowNonOsProgramsToSaveUpdatedClosures | DYLD_USE_CLOSURES | reserveExact | getOnDiskBinarySliceOffset | STACK_ALLOC_OVERFLOW_SAFE_ARRAY | topLevelLoaders | loadDependents | notifyDebuggerLoad | notifyDtrace | DOF | addPermamentRanges | STACK_ALLOC_ARRAY | weakDefMap | buildInterposingTables | handleStrongWeakDefOverrides | visibility | applyFixups | applyCachePatches | doSingletonPatching | applyInterposingToDyldCache | Libdyld.dylib | libdyld4Section | allImageInfos | storeProcessInfoPointer | __chkstk_darwin | partitionDelayLoads | DYLD_JUST_BUILD_CLOSURE | prewarming | notifyMonitorNeeded | LC_MAIN | LC_THREAD | getEntry | appMain | restorePreviousState | TPRO | libSystemHelpers | __exit
* &#9745; [DYLD — Do You Like Death? (I)](https://karol-mazurek.medium.com/dyld-do-you-like-death-i-8199faad040e?sk=v2%2F359b081f-d944-409b-9e7c-95f7c171b969)
* &#9745; [DYLD — Do You Like Death? (II)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ii-b74360b8af47?sk=v2%2Ff0cff71c-5345-4228-a639-653325fc979d)
* &#9745; [DYLD — Do You Like Death? (III)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iii-af77701a3034?sk=v2%2F06c92503-2db9-40e2-b139-c9ae0a35e7b3)
* &#9745; [DYLD — Do You Like Death? (IV)](https://karol-mazurek.medium.com/dyld-do-you-like-death-iv-ede6b157752c?sk=v2%2F87ebe38d-004c-41a6-bc1f-43898494a512)
* &#9745; [DYLD — Do You Like Death? (V)](https://karol-mazurek.medium.com/dyld-do-you-like-death-v-c40a267573cb?sk=v2%2F4c9f16b2-59bd-406a-945d-10a1fba1001b)
* &#9745; [DYLD — Do You Like Death? (VI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vi-1013a69118ff?sk=v2%2F37b3a61f-8483-4b38-977d-7f860944862b)
* &#9745; [DYLD — Do You Like Death? (VII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-vii-62c202f98610?sk=v2%2Fab26bfcf-ba56-493d-9af3-2d8790ca6208)
* &#9745; [DYLD — Do You Like Death? (VIII)](https://karol-mazurek.medium.com/dyld-do-you-like-death-viii-327d7e7f3c0f?sk=v2%2F6c6b611d-fee4-4d9d-8a36-d59a05116e23)
* &#9745; [DYLD — Do You Like Death? (IX)](https://karol-mazurek.medium.com/dyld-do-you-like-death-ix-5052c865100e?sk=v2%2Fe078d739-ab30-4f2d-8a12-eefc63dd73b4)
* &#9745; [DYLD — Do You Like Death? (X)](https://karol-mazurek.medium.com/dyld-do-you-like-death-x-76408570c357?sk=v2%2F8b69c2f1-ce13-4d05-bba1-e0164c3de381)
* &#9745; [DYLD — Do You Like Death? (XI)](https://karol-mazurek.medium.com/dyld-do-you-like-death-xi-cef76bc8dc14?sk=v2%2F0b88b392-ae94-43d0-9120-109306051e00)
* &#9745; [VI. AMFI](https://karol-mazurek.medium.com/snake-apple-vi-amfi-31c48fb92d33?sk=v2%2F8116bf86-e0a7-42be-ada9-5348447c01fd)
* &#9744; [VII. Antivirus](https://karol-mazurek.medium.com/snake-apple-vii-antivirus-0a57acc10185?sk=v2%2F2c46d7ac-4435-41e6-bbda-2acb4eb78c76)
* &#9745; [VII. Antivirus](https://karol-mazurek.medium.com/snake-apple-vii-antivirus-0a57acc10185?sk=v2%2F2c46d7ac-4435-41e6-bbda-2acb4eb78c76)
* &#9744; [VIII. Sandbox]()
* &#9745; [SBPL Compilator](https://karol-mazurek.medium.com/sbpl-compilator-c05f5304d057?sk=v2%2F4ae3bf90-ff12-4fea-b0fc-0f2ef60d7b93)
* &#9745; [Sandbox Detector](https://karol-mazurek.medium.com/sandbox-detector-4268ab3cd361?sk=v2%2F58fe49fb-1381-4db3-9db9-3f6309e4053a)
* &#9744; [IX. TCC]()
* &#9744; [X. NU]()
* &#9745; [Kernel Debugging Setup on MacOS](https://karol-mazurek.medium.com/kernel-debugging-setup-on-macos-07dd8c86cdb6?sk=v2%2F782bf539-a057-4f14-bbe7-f8e1ace26701)
## TOOLS
[CrimsonUroboros](#crimsonuroboros) • [MachOFileFinder](#machofilefinder) • [TrustCacheParser](#trustcacheparser) • [SignatureReader](#signaturereader) • [extract_cms.sh](#extract_cmssh) • [ModifyMachOFlags](#modifymachoflags) • [LCFinder](#lcfinder) • [MachODylibLoadCommandsFinder](#machodylibloadcommandsfinder) •[AMFI_test.sh](VI.%20AMFI/custom/AMFI_test.sh)
[CrimsonUroboros](#crimsonuroboros) • [MachOFileFinder](#machofilefinder) • [TrustCacheParser](#trustcacheparser) • [SignatureReader](#signaturereader) • [extract_cms.sh](#extract_cmssh) • [ModifyMachOFlags](#modifymachoflags) • [LCFinder](#lcfinder) • [MachODylibLoadCommandsFinder](#machodylibloadcommandsfinder) • [AMFI_test.sh](VI.%20AMFI/custom/AMFI_test.sh) • [make_plist](VIII.%20Sandbox/python/make_plist.py) • [sandbox_inspector](VIII.%20Sandbox/python/sandbox_inspector.py) • [spblp_compiler_wrapper](VIII.%20Sandbox/custom/sbpl_compiler_wrapper) • [make_bundle](#make_bundle) • [make_bundle_exe](#make_bundle_exe) • [make_dmg](#make_dmg) • [electron_patcher](#electron_patcher)
***
### [CrimsonUroboros](tests/CrimsonUroboros.py)
@@ -42,9 +49,12 @@ Each article directory contains three subdirectories:
Core program resulting from the Snake&Apple article series for binary analysis. You may find older versions of this script in each article directory in this repository.
* Usage
```console
usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian]
[--header] [--load_commands] [--has_cmd LC_MAIN]
[--segments] [--has_segment __SEGMENT] [--sections]
usage: CrimsonUroboros [-h] [-p PATH] [-b BUNDLE] [--bundle_structure]
[--bundle_info] [--bundle_info_syntax_check]
[--bundle_frameworks] [--bundle_plugins] [--file_type]
[--header_flags] [--endian] [--header]
[--load_commands] [--has_cmd LC_MAIN] [--segments]
[--has_segment __SEGMENT] [--sections]
[--has_section __SEGMENT,__section] [--symbols]
[--imports] [--exports] [--imported_symbols]
[--chained_fixups] [--exports_trie] [--uuid] [--main]
@@ -53,18 +63,20 @@ usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian]
[--save_strings all_strings.txt] [--info]
[--dump_data [offset,size,output_path]]
[--calc_offset vm_offset] [--constructors]
[--dump_section __SEGMENT,__section]
[--verify_signature] [--cd_info] [--cd_requirements]
[--entitlements [human|xml|var]]
[--extract_cms cms_signature.der]
[--extract_certificates certificate_name]
[--remove_sig unsigned_binary]
[--sign_binary [adhoc|identity]] [--cs_offset]
[--cs_flags] [--has_pie] [--has_arc] [--is_stripped]
[--has_canary] [--has_nx_stack] [--has_nx_heap]
[--has_xn] [--is_notarized] [--is_encrypted]
[--is_restricted] [--is_hr] [--is_as] [--is_fort]
[--has_rpath] [--has_lv] [--checksec] [--dylibs]
[--rpaths] [--rpaths_u] [--dylibs_paths]
[--cs_flags] [--verify_bundle_signature]
[--remove_sig_from_bundle] [--has_pie] [--has_arc]
[--is_stripped] [--has_canary] [--has_nx_stack]
[--has_nx_heap] [--has_xn] [--is_notarized]
[--is_encrypted] [--is_restricted] [--is_hr] [--is_as]
[--is_fort] [--has_rpath] [--has_lv] [--checksec]
[--dylibs] [--rpaths] [--rpaths_u] [--dylibs_paths]
[--dylibs_paths_u] [--broken_relative_paths]
[--dylibtree [cache_path,output_path,is_extracted]]
[--dylib_id] [--reexport_paths] [--hijack_sec]
@@ -82,13 +94,31 @@ usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian]
[--kext_exit kext_name] [--mig] [--has_suid]
[--has_sgid] [--has_sticky] [--injectable_dyld]
[--test_insert_dylib] [--test_prune_dyld]
[--test_dyld_print_to_file]
[--test_dyld_print_to_file] [--test_dyld_SLC] [--xattr]
[--xattr_value xattr_name] [--xattr_all]
[--has_quarantine] [--remove_quarantine]
[--add_quarantine]
Mach-O files parser for binary analysis
options:
-h, --help show this help message and exit
GENERAL ARGS:
-p PATH, --path PATH Path to the Mach-O file
-b BUNDLE, --bundle BUNDLE
Path to the App Bundle (can be used with -p to change
path of binary which is by default set to:
/target.app/Contents/MacOS/target)
BUNDLE ARGS:
--bundle_structure Print the structure of the app bundle
--bundle_info Print the Info.plist content of the app bundle (JSON
format)
--bundle_info_syntax_check
Check if bundle info syntax is valid
--bundle_frameworks Print the list of frameworks in the bundle
--bundle_plugins Print the list of plugins in the bundle
MACH-O ARGS:
--file_type Print binary file type
@@ -130,6 +160,9 @@ MACH-O ARGS:
Calculate the real address (file on disk) of the given
Virtual Memory {vm_offset} (e.g. 0xfffffe000748f580)
--constructors Print binary constructors
--dump_section __SEGMENT,__section
Dump '__SEGMENT,__section' to standard output as a raw
bytes
CODE SIGNING ARGS:
--verify_signature Code Signature verification (if the contents of the
@@ -155,6 +188,11 @@ CODE SIGNING ARGS:
(default: adhoc)
--cs_offset Print Code Signature file offset
--cs_flags Print Code Signature flags
--verify_bundle_signature
Code Signature verification (if the contents of the
bundle have been modified)
--remove_sig_from_bundle
Remove Code Signature from the bundle
CHECKSEC ARGS:
--has_pie Check if Position-Independent Executable (PIE) is set
@@ -258,7 +296,8 @@ AMFI ARGS:
from Kernel Cache
--kext_entry kext_name
Calculate the virtual memory address of the __start
(entrpoint) for the given {kext_name} Kernel Extension
(entrypoint) for the given {kext_name} Kernel
Extension
--kext_exit kext_name
Calculate the virtual memory address of the __stop
(exitpoint) for the given {kext_name} Kernel Extension
@@ -275,9 +314,23 @@ AMFI ARGS:
DYLD_PRINT_INITIALIZERS=1) (INVASIVE - the binary is
executed)
--test_dyld_print_to_file
Check if YLD_PRINT_TO_FILE Dyld Environment Variables
Check if DYLD_PRINT_TO_FILE Dyld Environment Variables
works (INVASIVE - the binary is executed)
--test_dyld_SLC Check if DYLD_SHARED_REGION=private Dyld Environment
Variables works and code can be injected using
DYLD_SHARED_CACHE_DIR (INVASIVE - the binary is
executed)
ANTIVIRUS ARGS:
--xattr Print all extended attributes names
--xattr_value xattr_name
Print single extended attribute value
--xattr_all Print all extended attributes names and their values
--has_quarantine Check if the file has quarantine extended attribute
--remove_quarantine Remove com.apple.quarantine extended attribute from
the file
--add_quarantine Add com.apple.quarantine extended attribute to the
file
```
* Example:
```bash
@@ -424,7 +477,33 @@ Simple script for calculating `amfiFlags` (described [here](https://karol-mazure
```console
python3 check_amfi.py 0x1df
```
***
### [make_bundle](App%20Bundle%20Extension/custom/make_bundle.sh)
Build a codeless bundle with a red icon.
* Usage:
```console
./make_bundle.sh
```
***
### [make_bundle_exe](App%20Bundle%20Extension/custom/make_bundle_exe.sh)
Bash template for building a PoC app bundle with Mach-O binary that utilizes Framework:
* Usage:
```console
./make_bundle_exe.sh
```
***
### [make_dmg](App%20Bundle%20Extension/custom/make_dmg.sh)
Script for packing the app in a compressed DMG container:
* Usage (change names in the script):
```console
./make_dmg.sh
```
### [electron_patcher](App%20Bundle%20Extension/custom/electron_patcher.py)
Pytthon script for extracting ASAR files from Electron apps and patching them with a custom ASAR file.
```
python3 electron_patcher.py extract app_bundle.app extracted_asar
python3 electron_patcher.py pack extracted_asar app_bundle.app
```
## INSTALL
```
@@ -434,6 +513,7 @@ chmod +x /usr/local/bin/trustcache
xattr -d com.apple.quarantine /usr/local/bin/trustcache
brew install keith/formulae/dyld-shared-cache-extractor
brew install blacktop/tap/ipsw
brew install tree
```
## LIMITATIONS

View File

@@ -0,0 +1,51 @@
// clang -o sandbox_detector sandbox_detector.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysctl.h>
// Prototype for the sandbox_check function
int sandbox_check(pid_t pid, int *operation, int flags);
// Function to check if a process exists
int pid_exists(pid_t pid) {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
struct kinfo_proc info;
size_t info_size = sizeof(info);
if (sysctl(mib, 4, &info, &info_size, NULL, 0) < 0) {
return 0; // PID does not exist
}
return (info_size > 0) ? 1 : 0; // Check if info_size is non-zero
}
void usage() {
fprintf(stderr, "Usage: %s <pid>\n", getprogname());
fprintf(stderr, "Checks if the process with the specified PID is sandboxed.\n");
fprintf(stderr, "\n");
exit(1);
}
int main(int argc, char **argv) {
if (argc != 2){
usage();
}
pid_t pid = atoi(argv[1]);
// Check if the PID exists
if (pid_exists(pid) == 0) {
fprintf(stderr, "%d: No such process\n", pid);
exit(2);
}
// Check if the process is sandboxed
int rc = sandbox_check(pid, 0, 0);
if (rc == 0) {
printf("Process %d is not sandboxed.\n", pid);
}else{
printf("Process %d is sandboxed.\n", pid);
}
return 0;
}

View File

@@ -0,0 +1,44 @@
// clang -o sbpl_compiler_wrapper sbpl_compiler_wrapper.c -lsandbox
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Define a struct to hold the compiled sandbox profile
struct compiled_sbp {
int64_t field_0; // unknown, maybe type?
void * data; // pointer to the compiled sandbox profile
size_t size; // size of the compiled sandbox profile
};
// Declare the sandbox_compile_file function
struct compiled_sbp *sandbox_compile_file(const char *inputPath, __int64_t a2, char **error_msg);
int main(int argc, char *argv[]) {
if (argc < 3) {
fprintf(stderr, "Usage: %s input_sb output_bin\n", argv[0]);
return 1;
}
// Get the full path of the input file so we skip the sandbox_compile_file relative path check
char *inputPath = realpath(argv[1], NULL);
if (!inputPath) {
perror("Failed to resolve input file path");
return 1;
}
const char *outputPath = argv[2];
// Declare variables to store the compiled sandbox profile and error message
char *error_msg = NULL;
struct compiled_sbp *compiled_file = NULL;
// Call sandbox_compile_file
compiled_file = sandbox_compile_file(inputPath, 0, &error_msg);
// Write result (bytecode) to output file
FILE *outputFile = fopen(outputPath, "wb");
if (!outputFile) {
perror("Failed to open output file");
return 1;
}
size_t bytesWritten = fwrite(compiled_file->data, 1, compiled_file->size, outputFile);
if (bytesWritten != compiled_file->size) {
fprintf(stderr, "Failed to write all bytecode to output file\n");
}
fclose(outputFile);
return 0;
}

1172
VIII. Sandbox/mac/_compile.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
__int64 __fastcall sandbox_compile_file(const char *a1, __int64 a2, char **a3)
{
FILE *v6; // x0
FILE *v7; // x24
char *v8; // x2
const char *v9; // x8
char **i; // x25
FILE *v11; // x0
char *v12; // t1
int *v13; // x0
__int64 v14; // x19
char *v16; // [xsp+18h] [xbp-48h] BYREF
v16 = 0LL;
if ( *a1 )
{
if ( *a1 != 47 )
{
v9 = "/System/Library/Sandbox/Profiles";
for ( i = &off_1E4D35420; ; ++i )
{
j__asprintf_11(&v16, "%s/%s.sb", v9, a1);
if ( !v16 )
{
j__asprintf_11(a3, "out of memory");
return 0LL;
}
v11 = j__fopen_15(v16, "r");
v8 = v16;
if ( v11 )
break;
j__free_34(v16);
v12 = *i;
v9 = v12;
if ( !v12 )
{
j__asprintf_11(a3, "%s: profile not found");
return 0LL;
}
}
v7 = v11;
goto LABEL_15;
}
v6 = j__fopen_15(a1, "r");
if ( v6 )
{
v7 = v6;
v8 = a1;
LABEL_15:
v14 = compile(0LL, v7, v8, 0LL, a2, 0LL, a3);
j__free_34(v16);
j__fclose_16(v7);
return v14;
}
v13 = j____error_27();
j__strerror_15(*v13);
j__asprintf_11(a3, "%s: %s");
}
else
{
j__asprintf_11(a3, "path is empty");
}
return 0LL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
# make_plist.py
import sys
import plistlib
def convert_xml_to_plist(xml_file, plist_file):
try:
with open(xml_file, 'rb') as f:
xml_content = f.read()
plist = plistlib.loads(xml_content)
with open(plist_file, 'wb') as f:
plistlib.dump(plist, f, fmt=plistlib.FMT_BINARY)
except FileNotFoundError:
print(f"Error: File '{xml_file}' not found.")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python3 make_plist.py <input_xml_file> <output_plist_file>")
sys.exit(1)
input_xml_file = sys.argv[1]
output_plist_file = sys.argv[2]
convert_xml_to_plist(input_xml_file, output_plist_file)

View File

@@ -0,0 +1,113 @@
import os
import plistlib
import argparse
class SandboxInspector:
def __init__(self, home_dir):
self.home_dir = home_dir
def container_exists(self, bundle_id):
# Construct the expected path of the container
container_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id)
# Check if the path exists
return os.path.exists(container_path)
@staticmethod
def get_bundle_id(app_path):
# Construct the path to the Info.plist file
info_plist_path = os.path.join(app_path, 'Contents', 'Info.plist')
# Read the Info.plist file to get the bundle identifier
with open(info_plist_path, 'rb') as f:
plist = plistlib.load(f)
return plist.get('CFBundleIdentifier')
def get_metadata(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
return plistlib.dumps(plist, fmt=plistlib.FMT_XML).decode('utf-8')
else:
return None
def get_redirectable_paths(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
redirectable_paths = plist.get('MCMMetadataInfo', {}).get('SandboxProfileDataValidationInfo', {}).get('RedirectablePaths', [])
return redirectable_paths
else:
return None
def get_sandbox_profile_data(self, bundle_id):
# Construct the path to the metadata plist file
metadata_plist_path = os.path.join(self.home_dir, 'Library', 'Containers', bundle_id, '.com.apple.containermanagerd.metadata.plist')
if os.path.exists(metadata_plist_path):
with open(metadata_plist_path, 'rb') as f:
plist = plistlib.load(f)
sandbox_profile_data = plist.get('MCMMetadataInfo', {}).get('SandboxProfileData', None)
return sandbox_profile_data
else:
return None
def parse_sandbox_profile_data(self, sandbox_profile_data):
# Placeholder for actual parsing logic
# This function will take raw bytes and interpret them as Sandbox Profile Language (SBPL)
if sandbox_profile_data:
return sandbox_profile_data# sandbox_profile_data.decode('utf-8', errors='ignore')
return None
def main():
parser = argparse.ArgumentParser(description="Inspect sandbox containers for macOS apps.")
parser.add_argument('-p', '--path', type=str, required=True, help="Path to the application (e.g., /Applications/Notes.app)")
parser.add_argument('-m', '--metadata', action='store_true', help="Print the .com.apple.containermanagerd.metadata.plist contents")
parser.add_argument('-r', '--redirectable', action='store_true', help="Print the redirectable paths")
parser.add_argument('-s', '--sandbox_profile_data', action='store_true', help="Print the SandboxProfileData bytes")
args = parser.parse_args()
app_path = args.path
inspector = SandboxInspector(os.path.expanduser("~"))
bundle_id = inspector.get_bundle_id(app_path)
if bundle_id:
exists = inspector.container_exists(bundle_id)
# print(f"Container for {bundle_id} exists: {exists}")
if args.metadata:
metadata = inspector.get_metadata(bundle_id)
if metadata:
#print(f"Metadata for {bundle_id}:\n{metadata}")
print(f"{metadata}")
else:
print(f"No metadata plist found for {bundle_id}.")
if args.redirectable:
redirectable_paths = inspector.get_redirectable_paths(bundle_id)
if redirectable_paths:
print(f"Redirectable paths for {bundle_id}:")
for path in redirectable_paths:
print(f"{path}")
else:
print(f"No redirectable paths found for {bundle_id}.")
if args.sandbox_profile_data:
sandbox_profile_data = inspector.get_sandbox_profile_data(bundle_id)
if sandbox_profile_data:
parsed_data = inspector.parse_sandbox_profile_data(sandbox_profile_data)
print(f"SandboxProfileData for {bundle_id}:\n{parsed_data}")
else:
print(f"No SandboxProfileData found for {bundle_id}.")
else:
print("Unable to find the CFBundleIdentifier. Please check the app path.")
if __name__ == "__main__":
main()

View File

@@ -1 +1 @@
../VII. Antivirus/python/CrimsonUroboros.py
../App Bundle Extension/python/CrimsonUroboros.py

File diff suppressed because it is too large Load Diff