Vault7: CIA Hacking Tools Revealed
Navigation: » Latest version
Owner: User #15728648
Ghidra
Manual Analysis of a 64-bit kernelcache in Ghidra
Getting Trustcache-related offsets
- Install Ghidra 5.6.3 with AARCH64 processor support
- Run analysis
- find "last entry has non-NULL string in kernelcache by doing a memory search for the string
- this is in a kext, so find mach_header_64 by search backwards in memory, search for 'feedfacf', in hex
- mark as as mach_header_64 (press t)
- next available memory, mark as segment_command_64
- Expand segment to see number of sections
- next avail, mark as an array of section_64
- expand first section, should be __text, __TEXT
- copy size into clipboard, jump to address
- select the size of the section by doing Select -> bytes as shown below
- enter 'd' to disassemble
- jump back to string ref, jump to first xref
- open decompiler
- get unslid function address by:
- Run mop/kernel_cache.py with -s on the kernelcache, and subtract it from the function address
- OR manually looking at the start address of the __text, and find slide by subtracting __text segment start address minus the kernel load address + 0x1000, then subtract it from function address
- Example: 00f003000 - (0xffffff8000202000) + 0x1000 = 0xEE00000
- edit the plist in entry EL_CONFIG_AMFI_ADD_JIT_HASH(4) -> unslid address function addres
- Example: ffffff800f93d420 - 0xEE00000 = 0xffffff8000B3D420
- Now we need the address of EL_CONFIG_AMFI_DYNAMIC_TRUSTCACHE struct. You can find it within the ADD_JIT_HASH function you found above.
Looking at disassembly, you can see a call to a a mutex_lock. The trustcache struct contains the lock being passed as x0, so subtract the DAT_reference by the offset in the disassembly
You can see above that DAT_ffffff800f959278 is the address of the lock being passed to FUN_ffffff800f93ed20, so we subtract 0x48 from ffffff800f959278 to get the address of the EL_CONFIG_AMFI_DYNAMIC_TRUSTCACHE struct. - Once you have the address, get its unslid address like you did above
- edit the plist in entry EL_CONFIG_AMFI_DYNAMIC_TRUSTCACHE(5) -> unslide address
- Example: 00f959230 -0xEE00000 = 0xffffff8000B59230
- Save the plist, build elutil and confirm el_trustcache works.
Hint: When using the Calculator app to get these values, open the large negative integer in scientific mode, then open in programmer mode to view the correct hex conversion.
Generating Sandbox Profiles
- Checkout the apple_sandbox project.
- Edit the pull_profiles.rb file. You will be changing the NAMES_OFFSET and PROFILES_OFFSET global variables.
- Open /usr/libexec/sandboxd into Ghidra/IDA
- In the __const segment, find a string pointer to "AdSheet". Get the address of this pointer, subtract the base address value from it(usually 0x1000). Set the NAMES_OFFSET to this address.
- Move 0x100 ahead - this should be a pointer to the start of the profiles. Set the PROFILES_OFFSET to this address, with the base address subtracted as before.
- run pull_profiles.rb on the sandboxd binary you just disassembled. This should generate *sb.bin files in your output directory of all the profiles.
- Within the apple_sandbox project, cd into sb_decompiler directory.
- run ./sb_decompiler.rb ios_<your version here> <path to binary sandbox profile> <output name>
find ~/Desktop/Research/sandbox_profiles/7.0.3/binary_profiles/ -name "*.sb.bin" -exec ./sb_decompiler.rb ios_703 {} {}.sb \;
- Note: You may need to edit sb_decompiler.rb, and created a new iOS<version>.yaml file in sb_decompiler/src/version_info if the Apple's TinyScheme implementation changes/adds new rules etc.