Releases: Karmaz95/Snake_Apple
v1.1
MAJOR
- Added
SnakeX
class - Added
drivers
andmach_ipc
subdirectories inX. NU/custom
- Added IDAPython script
format_externalmethods.py
- Added
CommPageParser.c
- Added example codes how to communicate with drivers
- Added example kernel extension
- Added IDAPython script
- Added LLDB helper script
set_xpc_breaks.py
- Added article about Snake & Apple X.NU
- Added article about Exceptions on macOS
- Added article about MACF on macOS
- Added article about Kernel Extensions on macOS
- Added article about Mach IPC Security on macOS
- Added article about Drivers on macOS
- Added article about XPC Programming on macOS
- Moved all KEXT related functions to XNU from other Snakes.
--dump_prelink_info [(optional) out_name]
Dump "__PRELINK_INFO,__info" to a given file (default: "PRELINK_info.txt")
--dump_prelink_text [(optional) out_name]
Dump "__PRELINK_TEXT,__text" to a given file (default: "PRELINK_text.txt")
--dump_prelink_kext [kext_name]
Dump prelinked KEXT {kext_name} from decompressed Kernel Cache PRELINK_TEXT segment to a
file named: prelinked_{kext_name}.bin
--kext_prelinkinfo [kext_name]
Print _Prelink properties from PRELINK_INFO,__info for a give {kext_name}
--kmod_info kext_name
Parse kmod_info structure for the given {kext_name} from Kernel Cache
--kext_entry kext_name
Calculate the virtual memory address of the __start (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
--mig Search for MIG subsystem and prints message handlers
--dump_kext kext_name
Dump the kernel extension binary from the kernelcache.decompressed file
MINOR
- Added MPO parser to XNU.
- Added
extract_sandbox_platform_profile
toSnakeVIII
- Added example XPC client-helper app bundle in
App Bundle Extensions/custom/XPC/
Full Changelog: v1.0...v1.1
Snake&Apple IX — TCC
MAJOR
- Added
SnakeIX
class - Added
sip_check.c
andsip_check.py
scripts - Added System Intigrity Protection article
- Added
uuid_manager.py
- Added
uuid_checker.sh
- Added Apple UUID Finder article
- Added
get_uuid.py
- Added
app_UUID_finder_v1.sh
andapp_UUID_finder_v2.sh
- Added
UUIDFinder.py
- Big changes for
MachOFileFinder
- faster and more error resistance - Added Optimizing Mach-O Detection
- Added Fixing an Infinite Loop article
MINOR
- Bug fix - file_path was missing self ()
❯ CrimsonUroboros -b /Applications/Safari.app --checksec
<==== CHECKSEC ======
PIE: True
ARC: False
STRIPPED: True
CANARY: False
NX STACK: True
NX HEAP: False
Traceback (most recent call last):
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 3664, in <module>
checksec_processor.process(args)
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1203, in process
print("XN:".ljust(16) + str(snake_instance.hasXN()))
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1325, in hasXN
if self.hasAllowJITentitlement(self.file_path) or self.checkIfCompiledForOtherThanARM():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1319, in checkIfCompiledForOtherThanARM
print(f"[INFO -> XN]: {os.path.basename(file_path)} is compiled for other CPUs than ARM or ARM64.")
^^^^^^^^^
NameError: name 'file_path' is not defined. Did you mean: 'self.file_path'?
- Bug fix - LIEF in version 0.15.0 re-scoped
CPU_TYPES
intolief.MachO.Header.CPU_TYPE
.
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 510, in extractArm64MachOFromUniversalBinary
if binary.header.cpu_type == lief.MachO.CPU_TYPES.ARM64:
- Bug fix - LIEF Re-scope
HEADER_FLAGS
intolief.MachO.Header.FLAGS
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1255, in hasNXstack
return not bool(self.binary.header.flags & lief.MachO.HEADER_FLAGS.ALLOW_STACK_EXECUTION.value
- Other similar issues patched according to
lief
15.0.1
changelog changes and some modification intest_CrimsonUroboros.py
- Set stable versions of the dependant pip libraries in
requirements.txt
so the tool can be stable:
lief=0.15.1
uuid=1.30
argparse=1.4.0
asn1crypto=1.5.1
pyimg4=0.8
treelib=1.7.0
xattr=1.1.0
python-magic=0.4.27
- Adding
sip_entitlements.txt
list of SIP-specific entitlements. - Uploaded all
kTCCService*
constants inkTCCService_constants.txt
from macOS 15. - Modify the
MachOFileFinder
so it works with lief 15.0.1. Moreover,parse_fat_binary
function check for any architecture by default but allow filtering for ARM64 when the--only_arm64
option is specified. - Added
uuid_checker.sh
that takes a UUID as the first argument and a path to a file list as the second argument. The script will iterate through each file path in the list, usingdwarfdump --uuid
to check for the specified UUID. If a match is found, it prints the file path. - Bug fix in
MachOFileFinder.py
to make it work with lief15.0.1
- Updated
Readme.md
MachOFileFinder.py
optimization changes, output is still the same:
❯ MachOFileFinder .
BUNDLE:/Users/karmaz/snake_apple/macho_files/samples/BUNDLE_type
DSYM:/Users/karmaz/snake_apple/macho_files/samples/DSYM_type
PRELOAD:/Users/karmaz/snake_apple/macho_files/samples/PRELOAD_type
FVMLIB:/Users/karmaz/snake_apple/macho_files/samples/FVMLIB_type
DYLINKER:/Users/karmaz/snake_apple/macho_files/samples/DYLINKER_type
DYLIB:/Users/karmaz/snake_apple/macho_files/samples/DYLIB_STUB_type
BUNDLE:/Users/karmaz/snake_apple/macho_files/samples/KEXT_BUNDLE_type
DYLIB:/Users/karmaz/snake_apple/macho_files/samples/DYLIB_type
UNKNOWN:/Users/karmaz/snake_apple/macho_files/samples/UNKNOWN_type
CORE:/Users/karmaz/snake_apple/macho_files/samples/CORE_type
OBJECT:/Users/karmaz/snake_apple/macho_files/samples/OBJECT_type
EXECUTE:/Users/karmaz/snake_apple/macho_files/samples/EXECUTE_type
- Added
create_macho_samples.py
template for creating macho headers samples. - Added
python-magic=0.4.27
torequirements.txt
- Further
MachOFileFinder.py
patches (output is still the same).
Full Changelog: v0.9...v1.0
Snake&Apple VIII — App Sandbox
MAJOR
- Added
SnakeVIII
class. - Added
spbl_compilator_wrapper.c
for compiling Sandbox Profile files.sb
. - Added
make_plist.py
for converting XML back to PLIST. - Added
sandbox_inspector
for various tasks related to App Sandbox (it is standalone, but I also implemented all functionalities to the latest SnakeVIII) - Added
sandbox_validator
for checking if a given operation is allowed for the sandboxed process - Added
sandbox_detector
for checking if the process is sandboxed - Some modifications & additions to the current code (see below).
SnakeI
- Added
--dump_binary
for extracting binary from Fat archives. - Modified
--dump_section
to dump raw bytes (no more b'\x01......') just raw binary to stdout. - Modified
getStringSection
so it now returns strings in the order they appear in the binary (not in random order like previously)
def getStringSection(self):
'''Return strings from the __cstring (string table).'''
extracted_strings = []
for section in self.binary.sections:
if section.type == lief.MachO.SECTION_TYPES.CSTRING_LITERALS:
strings_bytes = section.content.tobytes()
strings = strings_bytes.decode('utf-8', errors='ignore')
extracted_strings.extend(strings.split('\x00'))
return extracted_strings
- Bug patch in
MachOFileFinder.py
, it did not print file type correctly, due tolief
update.
print(f"{binary.header.file_type.__name__}:{file_path}")
SnakeAppExtension
- Added
--bundle_id
flag for printing theCFBundleIdentifier
value from theInfo.plist
file if it exists.
MINOR
- Added decompiled code of Sandbox components.
- Added
sandbox_operations_extractor.py
a simple script for extracting Sandbox Operations fromSandbox.kext
- Added
sonoma_sandbox_operations.txt
list of all Sandbox Operations extracted fromSandbox.kext
on Sonoma usingsandbox_operations_extractor.py
- Added
SBPL Compilator
article link. - Added
Sandbox Detector
article link. - Added
Sandbox Validator
article link. - Added
Unexpected but expected behavior
article link. - Updated README.md
- Patched one of the helper testing functions because it could not handle some bytes while decoding. Now it looks like this:
def run_and_get_stdout(command):
command_with_stdout = f"{command} 2>&1"
# Run the command and capture the output in bytes
result = subprocess.run(command_with_stdout, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Decode with utf-8, ignoring invalid characters or replacing them
return result.stdout.decode('utf-8', errors='replace').strip()
Snake & Apple: App Bundle Extension
MAJOR
- This update changed the concept of the tool, which at the beginning had to be only a Mach-O analyzer.
- From now on, it will also support app bundles as it grows.
- There is a new
APP BUNDLE EXTENSION
- Adding new tools for working with App Bundles:
- Added
BundleProcessor
class:
'''This class contains part of the code related to the App Bundle Extension.
It extends the Snake instance abilities beyond only Mach-O analysis.
When -b/--bundle flag is used, it will analyze the App Bundle when an instance of this (BundleProcessor) class is created.
Then, it can be communicated from Snake object with the new methods dependent on the files in App Bundle.'''
- Now tool can work without
-p
, if-b
is used (it supports Codeless bundles - if no valid executable is in a bundle):
def parseArgs(self):
args = self.parser.parse_args()
if not args.path and not args.bundle:
self.parser.error('One of arguments: -p/--path or -b/--bundle is required.')
return args
- We can use
-p
and-b
together if we want to change thepath
of analyzed binary in context of the bundled app by default binary path is taken fromInfo.plist
or if it not exists from:/target.app/Contents/MacOS/target
. The logic behind it lies in a new class method:SnakeHatchery.hatch()
def hatch(self):
''' This function initiates 3 global classes:
1. bundle_processor - BundleProcessor class instance, which is used to parse the App Bundle.
2. binaries - Universal binary from wich arm64 Mach-O is extracted (used for most of the flags in CrimsonUroboros).
3. snake_instance - the latest Snake class instance, which holds all the CrimsonUroboros flags logic (inherited starting from SnakeAppBundleExtension).
In the end, it process the arguments related to --bundle flag.
'''
self.pathExistanceCheck()
if self.bundleInit():
self.filePathInit()
self.binaryInit()
if binaries is None and bundle_processor is None:
print('QUITING: The file used in -p is not a valid Mach-O and you did not specify a bundle (-b).')
print('It will only work if bundle is specified AND|OR file is a valid Mach-O.')
exit() # Exit if the file is not valid macho and bundle is not specified
global snake_instance # Must be global for further processors classes.
snake_instance = self.snake_class(binaries, self.file_path)
if bundle_processor is not None:
bundle_processor.process(self.args)
- The biggest change is the new class
SnakeHatchery
. All starting logic fromMachOAnalyzer
was moved to this class. Basically, the whole startup is rebuild. - Usually
process
methods are exeuted in main. There is one exception in withBundleProcessor
class, as it is executed insideSnakeHatchery
in the end ofhatch
method.
if __name__ == "__main__":
arg_parser = ArgumentParser()
args = arg_parser.parseArgs()
### --- APP BUNDLE EXTENSION --- ###
snake_hatchery = SnakeHatchery(args, SnakeVII)
snake_hatchery.hatch()
### --- I. MACH-O --- ###
macho_processor = MachOProcessor()
macho_processor.process(args)
- The extension itself does not provide much flags, instead, there are new options for existing modules that uses information stored in the object of the extension class
bundle_processor = BundleProcessor(bundle_path)
SnakeAppExtension
- This is a new class, it is a part of
APP BUNDLE EXTENSION
and it stores only logic for CrimsonUroboros flags. Most of the code related to parsing and extracting data from App Bundle is inBundleProcessor
class:
* Added `--bundle_structure` for printing bundle structure in Tree format.
* Added `--bundle_info` for printing `Info.plist` in JSON format.
* Added `--bundle_info_syntax_check`for checking inf `Info.plist` has correct sytnax.
* Added `--bundle_frameworks` for enumerating bundled `Frameworks`.
* Added `--bundle_plugins` for enumerating bundled `PlugIns`.
SnakeI
- Added
--dump_section
for dumping section by its name. - Added logic for Mach-O verification:
if binaries is not None: # Exception for bundles where binaries are not valid Mach-O
self.binary = self.parseFatBinary(binaries)
self.segments_count, self.file_start, self.file_size, self.file_end = self.getSegmentsInfo()
self.load_commands = self.getLoadCommands()
self.endianess = self.getEndianess()
self.format_specifier = '<I' if self.getEndianess() == 'little' else '>I' # For struct.pack
self.reversed_format_specifier = '>I' if self.getEndianess() == 'little' else '<I' # For CS blob which is in Big Endian.
self.fat_offset = self.binary.fat_offset # For various calculations, if ARM64 Mach-O extracted from Universal Binary
- The exception related to the wrong Mach-O file specified in the path can now be bypassed by specifying
-b
for bundle analysis (it is because the executable in the bundle can be a script, for instance).
if binaries is None and bundle_processor.bundle_path is None:
exit() # Exit if the file is not valid macho and bundle is not specified
- Bug fixes related to section dumping - the code changes are implemented in
SnakeI
, but they are related to usage of these functions in theSnakeIV
.
def dumpSection(self, segment_name, section_name, filename):
...
segment_name = segment_name.lower()
section_name = section_name.lower()
...
def getSectionRange(self, segment_name, section_name):
...
segment_name = segment_name.lower()
section_name = section_name.lower()
...
- Added
printEntitlements
for printing XML entitlements withoutb'...\n'
.
def printEntitlements(self, file_path, format=None):
''' Helper function for printing entitlements. '''
entitlements = self.getEntitlementsFromCodeSignature(file_path, format)
try:
print(entitlements.decode('utf-8'))
except:
print(entitlements)
SnakeII
- Added
--remove_sig_from_bundle
for removing the signature from application. - Added
-verify_bundle_signature
for validating the app's code signature.
SnakeIV
- Added similar logic as in
SnakeI
for handling Codeless bundles.
if binaries is not None: # Exception for bundles where binaries are not valid Mach-O
self.dylib_id_path = self.getPathFromDylibID() # Get Dylib ID for @loader_path resolving
self.dylib_loading_commands, self.dylib_loading_commands_names = self.getDylibLoadCommands() # 1. Get dylib specific load commands
self.rpath_list = self.resolveRunPathLoadCommands() # 2. Get LC_RPATH list
self.absolute_paths = self.resolveDylibPaths() # 3. Get all dylib absolute paths dictionary {dylib_name[dylib_paths]}
MINOR
- Added new tests for all new flags.
- Changed all tests to inlcude app bundle extension, the big change is how
bundle_processor
is passed to theMachOProcessor
during initial logic:- In main we pass bundle_processor
macho_processor = MachOProcessor(file_path, bundle_processor)
* It is then updated to global scope in MachOProcessor:
global bundle_processor
bundle_processor = self.bundle_processor
- Added
Cracking macOS apps
article link. - Added
App Bundle Extension
article link. - Created an
Article_tags.md
for hashtags related to the articles, because the list of articles did not look very aesthetic. - Until now, only the Dyld series had hashtags - I added them for the rest of the articles.
README.md
update
Snake & Apple: Antivirus
MAJOR
-
Repaired bug in
checkDyldInsertLibraries
that was missing the case for0x10000
+ insecure entitlements -
I repaired all the bugs I missed after the latest updates to the
lief
library. -
All tests were successful, so it should work for the latest
lief
version. -
Added
testDyldSLC
andprinttestDyldSLC
to support--test_dyld_SLC
option to test for code injection usingDYLD_SHARED_CACHE_DIR
. -
New Snake VII. Antivirus class with bunch of new functionalities.
-
Added
AMFI_test.sh
script.
MINOR
- Patched Type-error because of changes in
lief
library:
if arm64_bin == None:
^^^^^^^^^^^^^^^^^
TypeError: __eq__(): incompatible function arguments. The following argument types are supported:
1. __eq__(self, arg: lief._lief.Object, /) -> bool
Invoked with types: lief._lief.MachO.Binary, NoneType
Now it cannot use ==
as the operator arm64_bin is None
.
- Patched the
getEndianess
function because of changes in thelief
library.
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 261, in getEndianess
magic = self.binary.header.magic.name
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'lief._lief.MachO.MACHO_TYPES' object has no attribute 'name
Now we must use __name__
property.
__name__
patch ingetDylibID
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1365, in getDylibID
if cmd.command.name == 'ID_DYLIB':
^^^^^^^^^^^^^^^^
AttributeError: 'lief._lief.MachO.LOAD_COMMAND_TYPES' object has no attribute 'name'
__name__
patch ingetDylibLoadCommands
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1176, in getDylibLoadCommands
cmd_name = cmd.command.name
^^^^^^^^^^^^^^^^
AttributeError: 'lief._lief.MachO.LOAD_COMMAND_TYPES' object has no attribute 'name'
__name__
patch ingetUnresolvedRunPathLoadCommandsPaths
File "/Users/karmaz/.local/bin/CrimsonUroboros", line 1188, in getUnresolvedRunPathLoadCommandsPaths
return [cmd.path for cmd in self.load_commands if cmd.command.name == 'RPATH']
^^^^^^^^^^^^^^^^
AttributeError: 'lief._lief.MachO.LOAD_COMMAND_TYPES' object has no attribute 'name'
- ... and other places where
__name__
should be used instead of.name
as from lief verion 14.0 - Minor bug patch with
getSections
where byte string was returned instead of decoded utf. - Added information about success in
dumpPrelink_info
anddumpPrelink_text
- Patched
getSectionRange
bug withif section_name == section.fullname
- lack od.decode()
after changes inlief
.
def getSectionRange(self, segment_name, section_name):
'''
Return section start and end file offset.
If there is no such section return False, False.
'''
for section in self.binary.sections:
if segment_name == section.segment_name:
if section_name == section.fullname.decode():
-
Modified some tests.
-
Added some RE to Dyld according to DYLD VII.
-
Fix the name in Arg parser for amfi_group.
-
Added X. NU directory for storing materials related to macOS kernel.
-
Added some presentations and decompiled code to the
mac
directory ofAntivirus
Snake & Apple: AMFI
MAJOR
- Added
SnakeVI
class! - Added decompiled AMFI code to the
VI. AMFI/mac/AMFI_RE
directory (the ones withPSEUDO_
prefix are my own more readable interpretation) - Added
AppleStructuresManager
class, which stores Apple structures and their parsers - Added
Utils
class, which stores custom tools for debugging CrimsonUroboros code - Partially did one of the TODO points from README.md about building my own Code Signature parser in Python by implementing the
parseCodeDirectoryBlob
methodin SnakeII
and theCodeDirectory
class inAppleStructuresManager
SNAKE I: Mach-O
- Added
calcSectionRange
,getSectionRange
,extractSection
anddumpSection
- Modified
getSections
withcalcSectionRange
- Modified
getMain
so now it also finds Thread Command (LC_THREAD / LC_UNIXTHREAD) - Added
hasLoadCommand
andprintHasLoadCommand
for a new option--has_cmd
- Added
hasSection
andprintHasSection
for a new option--has_section
- Moved the
saveBytesToFile
method fromSnakeII
toSnakeI
- Added
dumpData
anddumpDataArgParser
for a new option--dump_data
- Added
hasSegment
andprintHasSegment
for a new option--has_segment
- Added
getVirtualMemoryStartingAddress
,calcRealAddressFromVM
- Added
calcRealAddressFromVM
andprintCalcRealAddressFromVM
for a new option--calc_offset
- Added
getSection
andgetSegment
functions - Added
self.symbol_types
that stores symbol types masks - Added
getImports
andprintImports
for a new option--imports
- Added
getExports
andprintExports
for a new option--exports
- Added
getSegmentsInfo
helper function for initialization so we can access properties:segments_count
,file_start
,file_size
,file_end
- Added
printConstructors
for a new option--constructors
SNAKE II: Code Signing
- Added
getCodeSignatureOffset
andprintCodeSignatureOffset
for a new option--cs_offset
- Added
printCodeSignatureOffset
,extractCodeSignatureBytes
,findBytes
,parseCodeDirectoryBlob
,getCodeSignatureOffset
andprintCodeSignatureFlags
for a new option--cs_flags
MINOR
- Added tags to the
DYLD
article series - Added
self.
prefix tofile_path
inextractBytesAtOffset
. - Added some new TODO's to
README.md
- Added tests for all new flags
- Added
crimson_stalker
toSourceCodeManager
- Added
MIG_detect.py
from knightsc repo - Added
check_amfi.py
script for calculatingamfiFlags
(described here inProcessConfig — AMFI properties
)
Snake & Apple: Dyld
MAJOR
- Added
SnakeV
class! - Implemented tests
SNAKE I: Mach-O
- I added the
--imported_symbols
flag, which prints external symbols grouped, sorted, and in a grepable form. Example:
symbol_name : library1
symbol_name : library1
symbol_name : library2
symbol_name : library3
SNAKE IV: DYLIBS
- Added
--dylib_hijacking_a
flag - it prints only possible Dylib Hijacking vectors
❯ CrimsonUroboros --dylib_hijacking_a -p executable
VULNERABLE ROOT BINARY: /Users/karmaz95/t/indirect_dylib_hijacking/executable
WRITEABLE EXISTING PATHS: /Users/karmaz95/t/indirect_dylib_hijacking/lib1.dylib
VULNERABLE DEPENDENCY: /Users/karmaz95/t/indirect_dylib_hijacking/lib1.dylib
WRITEABLE EXISTING PATHS: /Users/karmaz95/t/indirect_dylib_hijacking/lib2.dylib
- Cosmetic changes to
--dylib_hijacking
flag. Now it prints if the binary is ROOT and starts from the status, then path:
CrimsonUroboros -p executable --dylib_hijacking
ROOT BINARY NOT PROTECTED: /Users/karmaz95/t/indirect_dylib_hijacking/executable
WRITEABLE EXISTING PATHS: /Users/karmaz95/t/indirect_dylib_hijacking/lib1.dylib
----------------------------
NOT PROTECTED: /Users/karmaz95/t/indirect_dylib_hijacking/lib1.dylib
WRITEABLE EXISTING PATHS: /Users/karmaz95/t/indirect_dylib_hijacking/lib2.dylib
----------------------------
NOT PROTECTED: /Users/karmaz95/t/indirect_dylib_hijacking/lib2.dylib
----------------------------
- I repaired the
prepareRogueDylib
function for--prepare_dylib
. The option was broken because it works on absolute paths, whileDYLIB_ID
could contain unresolved paths like@rpath/something.dylib
. For this reason, the function now works on dylib names:
--prepare_dylib target_dylib_name
SNAKE III: CHECKSEC
- Added Library Validation
--has_lv
.
❯ CrimsonUroboros --has_lv -p executable
LIBRARY VALIDATION: False
- I added LV (Library Validation) to the --checksec option.
❯ CrimsonUroboros --checksec -p executable
<==== CHECKSEC ======
PIE: True
ARC: False
STRIPPED: False
CANARY: False
NX STACK: True
NX HEAP: False
XN: True
NOTARIZED: False
ENCRYPTED: False
RESTRICTED: False
HARDENED: False
APP SANDBOX: False
FORTIFIED: False
RPATH: False
LV: False
=====================>
- Added check for
CS_RESTRICT
(0x800
) in--checksec
toRESTRICTED
; now, it returns True if the__RESTRICT
segment is used or the0x800
flag is set.
MINOR
- Repaired install section (removed uninstallable requirements)
- Completed TODO tasks
- Add check for
DYLIB HIJACKING
to--checksec
- Add check for
CS_RESTRICT
(0x800
) in--checksec
toRESTRICTED
- Add check for
- Updated README.md
- Overall code maintenance for a better reader experience
- Removed try-except blocks in each Snake class for more verbose error logging.
- Added
args
argument to all.process()
methods to make thetest_CrimsonUroboros.py
code simpler. This is just passing theargs
to the method.
Snake & Apple: Dylibs
MAJOR
- Added
SnakeIV
class! - Added
MachODylibLoadCommandsFinder
- Added the
### --- SOURCE CODE --- ###
section with theSourceCodeManager
class for the C code storage to keep it in one Python file. This class stores only thedylib_hijacking
C code and compiles rogue dylib. In the future, the class will store Assembly code and other tricks for injections.
MINOR
- Added
self.file_path
as the property forSnakes
classes. From now on, it must be initialized for every Snake. So it is now:
def __init__(self, binaries, file_path):
super().__init__(binaries, file_path)
- Changed handling any unexpected errors in
except Exception as e:
in each processor class to print the name for the Snake. For example:
print(f"An error occurred during SnakeI: Mach-O processing: {e}")
- Added
load_commands
andendianness
properties to Snake class:
self.load_commands = self.getLoadCommands()
self.endianess = self.getEndianess()
- Added
dyld-shared-cache-extractor
to theINSTALL
section inREADME.md
. - Added
ipsw
to theINSTALL
section inREADME.md
. - Added
--dylib_hijacking
and--dylibtree
flags to theLIMITATIONS
section inREADME.md
. - Added some points to the
TODO - IDEAS / IMPROVES
section inREADME.md
.
Snake & Apple: Checksec
MAJOR
- Added
SnakeIII
class! - Added
LCFinder
! - Added
ModifyMachOFlags
! - Added
getEncryptionInfo()
to theSnakeI
: Mach-O class and--encryption_info
flag for this functionality- If the encryption info load command exists, the information will be printed in the
--info
flag - The user can also specify the output path if he wants to dump the encrypted (or not if
cryptid=0
) data sector from the file (it works with fat binaries)
- If the encryption info load command exists, the information will be printed in the
MINOR
- Wrapped
lief.MachO.parse(self.file_path)
in aparseFatBinary()
method inside aMachOProcessor
class.
Snake & Apple: Code Signing
MAJOR
- I created an additional class,
ArgumentParser
, that stores the code from themain()
responsible for argument parsing from CLI - I created processor classes for each article/snake - this class stores the code from the main. I did it to make the code cleaner in the
main()
, and it is better for the reader because he can read Snake class and then code from the main rather than scrolling to the main to see it Main()
stores only the initialization of the class and processor method to execute the code- Added
SnakeII
class! - Added
TrustCacheParser
program! - Added
SingatureReader
program! - Added
extract_cms.sh
script!
MINOR
- Grouped arguments in argument parser for better readability for the end-user in helper and easier code maintenance
- Added ADDITIONAL LINKS to the
README.md
- Updated description in
README.md
- Removed bug in
SnakeI: Mach-O
code, where program could run even whenbinaries = lief.MachO.parse(file_path)
return None (not Mach-O). - Added the file_path variable for snake_instance initialization so it can be used locally in classes.
- Added
TrustCacheParser
,SingatureReader
andextract_cms.sh
toREADME.md
- Added
.gitignore
- Added
requirements.txt
- Made
README.md
better - Updated links to articles