sniffing mach messages
TRANSCRIPT
Sniffing Mach Messages
Mikhail SosonkinSlides: http://www.slideshare.net/MikhailSosonkin
ME! Employer!
Challenge Review: loading Mach-O from memory
- Understand injectdyld_file.c- Figure out how to dynamically load a dylib- Can use injectdyld_file.c as a base
- Hint: you will need to read the DYLD sourcecode.
Hint: you will need to read the DYLD sourcecode.ImageLoader* loadFromMemory(const uint8_t* mem, uint64_t len, const char* moduleName){
// if fat wrapper, find usable sub-fileconst fat_header* memStartAsFat = (fat_header*)mem;uint64_t fileOffset = 0;uint64_t fileLength = len;if ( memStartAsFat->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
if ( fatFindBest(memStartAsFat, &fileOffset, &fileLength) ) {mem = &mem[fileOffset];len = fileLength;
dyld.cpp, not exported.
Load from memory
Make part of process
Parse into class object
Getting started with iOS
- Get iPhone 5s- Swappa
- Apply Jailbreak- Install OpenSSH via Cydia- Use tcprelay to SSH over USB
- Start exploring- Debugserver
- Objective-c: Phrack 0x42- http://phrack.org/issues/66/4.html
- https://github.com/iosre/iOSAppReverseEngineering- https://nabla-c0d3.github.io/blog/2014/12/30/tcprelay-multiple-devices/
Before we begin...
Let’s cover some basics.
ARM64 Registers
31 General purpose registers
X0 … X30 or W0 … W30
X31 - (zr) The Zero register
X30 - (lr) Procedure Link Register (RIP)
X29 - (fp) Frame pointer (RBP)
X18 - Reserved on iOS
ARM64 Instructions
Conditional Branches
B.EQ, B.NE, TBNZ (Test bit and Branch if Nonzero), etc.
Unconditional Branches
B, RET, SVC
Conditional Select
CSEL W9, W9, W10, EQ
“W9 = EQ?W9:W10”
Calling Convention
On ARM64:
X0 … X8 Contain function parameters
X16 has the system call number
Positive for Posix
Negative for Mach Ports
0x80000000 for thread_set_self
SVC 0x80; jumps to kernel
Syscall numbers
OSX:
0x01000000 - mach calls
0x02000000 - Posix
0x03000003 - pthread_set_self
IOS
0x00000000 and below - mach calls
0x00000000 and above - Posix
0x80000000 - pthread_set_self
More details
See the iOS ABI Function Call Guide
What are Mach Messages?
The OS X/iOS IPC mechanism
Auditing and Exploiting Apple IPC by Ian Beer
The OS X/iOS IPC mechanism
● Message based communication○ Ports -> sockets○ Port numbers are dynamically assigned○ Port numbers are process specific
● Mechanism for sandbox enforcement○ Network comms go through mach ports○ Send messages to a broker to perform actions
The messages
Sending a message
https://opensource.apple.com/source/xnu/xnu-1456.1.26/libsyscall/mach/mach_msg.c
Finding ports
● Launchd - the DNS of Mach Messages.○ Bootstrap.h
■ bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp);
■ kern_return_t bootstrap_look_up(mach_port_t bp,const name_t service_name,mach_port_t *sp);
○ Rocketbootstrap - for jailbreaks■ kern_return_t rocketbootstrap_look_up(
mach_port_t bp,const name_t service_name,mach_port_t *sp);
Let’s observe them!
1. Allocate a page - a jump page
2. Set mach_msg readable and writable
3. Copy preamble bytes from mach_msg
4. Check for branch instructions in preamble
5. Modify mach_msg preamble
6. Set jump page to readable and executable
7. Set mach_msg readable and executable
Objc_Trace
Call Sequence
Hook Steps
Tracing ObjC messages
Basic Process
1. Attach with LLDB2. Breakpoint on Bootstrap Lookups3. Breakpoint on mach_msg and friends4. Run the application and collect the messages5. Post process the results
I prefer to automate this!
Attaching to a process
Create an LLDB command
In ~/.lldbinit:
“Let’s look at some code!”
mach_sniff.py
LLDB Python Reference
First ret is the end of function
1. Break point of symbol bootstrap_look_up2 (beginning of function)a. Expecting only one location
2. Set script function to executea. Python function rocketbootstrap_look_up
3. Find the end of functiona. First ret instruction within 100 instructionb. Use IDAPro reverse engineering to figure this one outc. Very specific to this function
4. Breakpoint on end of function5. Set script function to execute
a. Call python script function rocketbootstrap_look_up_end
Get the port name, 2nd argument
Record the state for return of the function
What’s the initial state of the call?
What the port number?
Once discovered, start sniffing!
Message to be sent
Message response
“Let’s look at some output!”
Events from libsimulatetouch
The header
Message payload
Parsed using mach_whale.py
The Challenge
“Port LLDB scripts to MacOS and
identify various uses of mach messages”
“Try doing the same thing using Frida”
If you don’t have a mac challenge: Get a MacOS VM running on a windows host. Beware of malware!
Where to learn about security?
- iOS Reverse Engineering Book- https://seccasts.com/- http://www.opensecuritytraining.info/- https://www.corelan.be- youtube for conference- Security meetups
- Just practice- Read/follow walkthroughs
- follow the reddits:- netsec- reverseengineering- malware- lowlevel- blackhat- securityCTF- rootkit- vrd
Thank you!
Mikhail Sosonkin
Slides: http://www.slideshare.net/MikhailSosonkin