mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-04-09 14:42:03 +02:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaf5c68c74 | ||
|
|
2f70ddaa65 | ||
|
|
71a7c31448 | ||
|
|
6f9a04bb3c | ||
|
|
75b72b56c5 | ||
|
|
af8e89ab67 | ||
|
|
80bc340015 | ||
|
|
30b1720e5b | ||
|
|
7fbc231ed6 | ||
|
|
04f7318c24 | ||
|
|
588f097c06 | ||
|
|
4a126b3502 | ||
|
|
001df7e406 | ||
|
|
77d0c07cb8 | ||
|
|
b08a5767ef | ||
|
|
8abdf68fad | ||
|
|
dd49f449c3 | ||
|
|
75531c136f | ||
|
|
84bf22e427 | ||
|
|
1e97057f70 | ||
|
|
700a4c045b | ||
|
|
03804fca9a | ||
|
|
c1ef70f01d | ||
|
|
596a88a648 | ||
|
|
51b994cc7b | ||
|
|
8b02698095 | ||
|
|
7adf70fd79 | ||
|
|
5a1ce99e8d | ||
|
|
9ac687389c | ||
|
|
d89de63909 |
36
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.js
Executable file
36
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.js
Executable 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()
|
||||
30
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.py
Executable file
30
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.py
Executable 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)
|
||||
81
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.sh
Executable file
81
App Bundle Extension/custom/calculate_electron_asar_integrity_hash.sh
Executable 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."
|
||||
116
App Bundle Extension/custom/electron_patcher.py
Executable file
116
App Bundle Extension/custom/electron_patcher.py
Executable 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()
|
||||
87
App Bundle Extension/custom/make_bundle.sh
Executable file
87
App Bundle Extension/custom/make_bundle.sh
Executable 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
|
||||
77
App Bundle Extension/custom/make_bundle_exe.sh
Executable file
77
App Bundle Extension/custom/make_bundle_exe.sh
Executable 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
|
||||
16
App Bundle Extension/custom/make_dmg.sh
Executable file
16
App Bundle Extension/custom/make_dmg.sh
Executable 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"
|
||||
3356
App Bundle Extension/python/CrimsonUroboros.py
Executable file
3356
App Bundle Extension/python/CrimsonUroboros.py
Executable file
File diff suppressed because it is too large
Load Diff
421
Article_tags.md
Normal file
421
Article_tags.md
Normal 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 5652–5.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 service’s 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-2023–26818
|
||||
* 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
134
README.md
@@ -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:
|
||||
* ☑ [App Bundle Extension](https://karol-mazurek.medium.com/snake-apple-app-bundle-ext-f5c43a3c84c4?sk=v2%2F3ff105ad-f4f0-464d-b4d5-46b86c66fe14)
|
||||
* ☑ [Cracking macOS apps](https://karol-mazurek.medium.com/cracking-macos-apps-39575dd672e0?sk=v2%2F727dce55-53ee-45f6-b051-2979e62f2ba1)
|
||||
* ☑ [Cracking Electron Integrity](https://karol-mazurek.medium.com/cracking-electron-integrity-0a10e0d5f239?sk=v2%2F7726b99c-c6c9-4d70-8c37-da9f2f0874e8)
|
||||
* ☑ [I. Mach-O](https://karol-mazurek95.medium.com/snake-apple-i-mach-o-a8eda4b87263?sk=v2%2Ffc1cbfa4-e2d4-4387-9a82-b27191978b5b)
|
||||
* ☑ [II. Code Signing](https://karol-mazurek95.medium.com/snake-apple-ii-code-signing-f0a9967b7f02?sk=v2%2Fbbc87007-89ca-4135-91d6-668b5d2fe9ae)
|
||||
* ☑ [III. Checksec](https://karol-mazurek95.medium.com/snake-apple-iii-checksec-ed64a4b766c1?sk=v2%2Fb4b8d637-e906-4b6b-8088-ca1f893cd787)
|
||||
* ☑ [IV. Dylibs](https://karol-mazurek.medium.com/snake-apple-iv-dylibs-2c955439b94e?sk=v2%2Fdef72b7a-121a-47a1-af89-7bf53aed1ea2)
|
||||
* ☑ [V. Dyld](https://karol-mazurek.medium.com/snake-apple-v-dyld-8b36b674cc44?sk=v2%2F4acb16f8-fa88-41f0-8d7c-1362f4060010)
|
||||
* ☑ [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
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [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)
|
||||
* ☑ [VI. AMFI](https://karol-mazurek.medium.com/snake-apple-vi-amfi-31c48fb92d33?sk=v2%2F8116bf86-e0a7-42be-ada9-5348447c01fd)
|
||||
* ☐ [VII. Antivirus](https://karol-mazurek.medium.com/snake-apple-vii-antivirus-0a57acc10185?sk=v2%2F2c46d7ac-4435-41e6-bbda-2acb4eb78c76)
|
||||
* ☑ [VII. Antivirus](https://karol-mazurek.medium.com/snake-apple-vii-antivirus-0a57acc10185?sk=v2%2F2c46d7ac-4435-41e6-bbda-2acb4eb78c76)
|
||||
* ☐ [VIII. Sandbox]()
|
||||
* ☑ [SBPL Compilator](https://karol-mazurek.medium.com/sbpl-compilator-c05f5304d057?sk=v2%2F4ae3bf90-ff12-4fea-b0fc-0f2ef60d7b93)
|
||||
* ☑ [Sandbox Detector](https://karol-mazurek.medium.com/sandbox-detector-4268ab3cd361?sk=v2%2F58fe49fb-1381-4db3-9db9-3f6309e4053a)
|
||||
* ☐ [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)
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
51
VIII. Sandbox/custom/sandbox_detector.c
Normal file
51
VIII. Sandbox/custom/sandbox_detector.c
Normal 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;
|
||||
}
|
||||
44
VIII. Sandbox/custom/sbpl_compiler_wrapper.c
Normal file
44
VIII. Sandbox/custom/sbpl_compiler_wrapper.c
Normal 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
1172
VIII. Sandbox/mac/_compile.c
Normal file
File diff suppressed because it is too large
Load Diff
64
VIII. Sandbox/mac/_sandbox_compile_file.c
Normal file
64
VIII. Sandbox/mac/_sandbox_compile_file.c
Normal 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;
|
||||
}
|
||||
3356
VIII. Sandbox/python/CrimsonUroboros.py
Executable file
3356
VIII. Sandbox/python/CrimsonUroboros.py
Executable file
File diff suppressed because it is too large
Load Diff
29
VIII. Sandbox/python/make_plist.py
Normal file
29
VIII. Sandbox/python/make_plist.py
Normal 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)
|
||||
113
VIII. Sandbox/python/sandbox_inspector.py
Normal file
113
VIII. Sandbox/python/sandbox_inspector.py
Normal 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()
|
||||
@@ -1 +1 @@
|
||||
../VII. Antivirus/python/CrimsonUroboros.py
|
||||
../App Bundle Extension/python/CrimsonUroboros.py
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user