12.07.2015 Views

Advanced Mac OS X Rootkits.pdf - Reverse Engineering Mac OS X

Advanced Mac OS X Rootkits.pdf - Reverse Engineering Mac OS X

Advanced Mac OS X Rootkits.pdf - Reverse Engineering Mac OS X

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Advanced</strong><strong>Mac</strong> <strong>OS</strong> X <strong>Rootkits</strong>Dino Dai ZoviChief ScientistEndgame Systems


Overview• <strong>Mac</strong> <strong>OS</strong> X and <strong>Mac</strong>h• Why use <strong>Mac</strong>h for rootkits?• User-mode <strong>Mac</strong>h rootkit techniques• Kernel <strong>Mac</strong>h rootkit techniques2


WHAT IS MACH?3


<strong>Mac</strong> <strong>OS</strong> X System Architecture4


<strong>Mac</strong> <strong>OS</strong> X System ArchitectureSUP DAWG,WE HEARDYOU LIKEKERNELS,SO WE PUTA KERNELIN YOURMICRO-KERNEL(SO YOUCAN MACHWHILE YOUBSD)5


Introduction to <strong>Mac</strong>h• <strong>Mac</strong> <strong>OS</strong> X kernel (xnu) is a hybrid between<strong>Mac</strong>h 3.0 and FreeBSD–FreeBSD kernel top-half runs on <strong>Mac</strong>h kernelbottom-half–Multiple system call interfaces: BSD (positivenumbers), <strong>Mac</strong>h (negative)–BSD sysctls, ioctls–<strong>Mac</strong>h in-kernel RPC servers, IOKit userclients, etc6


<strong>Mac</strong>h Microkernel Abstractions• Task: A resource container– Virtual memory address space– 1 or more Threads– IPC port rights• Thread: An entity that can be scheduled by the kernel torun on a processor• Port: An inter-task communication mechanism usingstructured, reliable messages– Think of them as sender-restricted “P.O. Boxes”– Only exist in kernel, Tasks hold Port Rights• Message: Data communicated between ports7


Port Names and Rights• A Port Name is a Task-specific 32-bit numberthat refers to a given port– Similar to file descriptors and Handles• A Task holds unidirectional Port Rights thatdetermine whether they may send and or receivemessages on a Port• Tasks may transfer Port Rights between eachother by sending them in messages–Kernel transfers rights and allocates a newname in the receiving task8


Example: Bootstrap server• Tasks are created with a set of initial ports, one is thebootstrap port, Bootstrap server is the glue thatallows different tasks to send messages to each other• Task X registers a port with Bootstrap server under astring name (“foo”) by sending message on Bootstrapport– Transfers SEND rights to Bootstrap server• Task Y looks up “foo” on bootstrap server by sendingmessage to bootstrap port, replies with server port– Reply transfers SEND rights to Task Y• Task Y can now send messages to Task X over that port9


<strong>Mac</strong>h Security Model• Tasks, ports, and port rights form<strong>Mac</strong>h’s capability-based security model• <strong>Mac</strong>h has no notion of users or groups• Obtaining SEND rights on a port may bea privilege escalation–SEND rights on another task’s task port givesfull control over that task10


<strong>Mac</strong>h Tasks vs. BSD Processes• <strong>Mac</strong>h Tasks own Threads, Ports, and Virtual Memory• BSD Processes own file descriptors, etc.• BSD Processes <strong>Mac</strong>h Task– task_for_pid(), pid_for_task()• P<strong>OS</strong>IX Thread != <strong>Mac</strong>h Thread– Library functions use TLS BSD Process<strong>Mac</strong>hThread<strong>Mac</strong>hThread<strong>Mac</strong>h Task<strong>Mac</strong>h Portnamespace...<strong>Mac</strong>hThreadVirtual Memory(mapping, permissions,memory regions)11


<strong>Mac</strong>h RPC• <strong>Mac</strong>h RPC uses <strong>Mac</strong>h messages forcommunication, NDR for data packing• Interface files (.defs) are compiled by MiGinto client and server stubs• Most <strong>Mac</strong>h kernel services are offered overRPC–i.e. thread, task, and VM control• <strong>Mac</strong>h kernel traps are minimal (it’s amicrokernel, remember?)12


<strong>Mac</strong>h Task/Thread System Calls•<strong>Mac</strong>h kernel RPC calls:–task_create(parent_task, ledgers,ledgers_count, inherit_memory, *child_task)–thread_create(parent_task,*child_activation)–vm_allocate(task, *address, size, flags)–vm_deallocate(task, address, size)–vm_read(task, address, size, *data)–vm_write(task, address, data, data_count)13


MACH-BASED ROOTKITS14


Why <strong>Mac</strong>h-based <strong>Rootkits</strong>?• Traditional Unix rootkit techniques arewell understood• <strong>Mac</strong>h functionality is more obscure• <strong>Rootkits</strong> using obscure functionality areless likely to be detected or noticed• <strong>Mac</strong>h is fun to program–Imagine re-learning Unix all over again15


User-mode <strong>Mac</strong>h <strong>Rootkits</strong>• Not as “sexy” as kernel mode rootkits• Can be just as effective and harder todetect• Are typically application/process -specific• Based on thread injection or executableinfection• Would you notice an extra bundle andthread in your web browser?16


Injecting <strong>Mac</strong>h Threads• Get access to another task’s task port– task_for_pid() or by exploiting a local privilege escalationvulnerability• Allocate memory in remote process for thread stack andcode trampoline• Create new mach thread in remote process– Execute trampoline with previously allocated threadstack segment– Trampoline code promotes <strong>Mac</strong>h Thread to P<strong>OS</strong>IX Thread•Call _pthread_set_self(pthread_t) andcthread_set_self(pthread_t)17


<strong>Mac</strong>h Exceptions• Tasks and Threads generate exceptions on memory errors• Another thread (possibly in another task) may register asthe exception handler for another thread or task• Exception handling process:1. A Thread causes a runtime error, generates anexception2. Exception is delivered to thread exception handler (ifexists)3. Exception is delivered to task’s exception handler (ifexists)4. Exception converted to Unix signal and delivered to BSDProcess18


Injecting <strong>Mac</strong>h Bundles• Inject threads to call functions in the remote process– Remote thread calls injected trampoline code and thentarget function– Function returns to chosen bad address, generates anexception– Injector handles exception, retrieves function return value• Call dlopen(), dlsym(), dlclose() to load bundle from disk• Inject memory, call NSCreateObjectFileImageFromMemory(),NSLinkModule()• Injected bundle can hook library functions, Objective-Cmethods19


inject-bundle• inject-bundle–Inject a bundle from disk into a running process–Usage: inject_bundle path_to_bundle [ pid ]• Sample bundles–test: Print output on load/run/unload–isight: Take a picture using iSight camera–sslspy: Log SSL traffic sent throughSecureTransport–ichat: Log IMs from within iChat20


Hooking and Swizzling• Hooking C functions is basically the sameas on any other platform–see Rentzsch’s mach_override• Objective-C runtime has hooking built-in:–method_exchangeImplementations()–or just switch the method pointers manually–all due to Obj-C’s dynamic runtime–use JRSwizzle for portability21


Rootkitting the Web Browser• What client system doesn’t have the web browseropen at all times?• Will be allowed to connect to *:80 and *:443 byhost-based firewalls (i.e. Little Snitch)• Injected bundles do not invalidate dynamic codesignatures (used by Keychain, etc)22


INJECTED BUNDLE DEMO23


MACHIAVELLI24


NetMessage and NetName servers• Network transparency of IPC was a design goal• Old <strong>Mac</strong>h releases included the NetMessageServer– <strong>Mac</strong>h servers could register themselves on the localNetName server– Clients could lookup named servers on remote hosts– Local NetMessage server would act as a proxy,transmitting <strong>Mac</strong>h IPC messages over the network• These features no longer exist in <strong>Mac</strong> <strong>OS</strong> X• <strong>Mac</strong>hiavelli adds them back25


<strong>Mac</strong>hiavelli• <strong>Mac</strong>h RPC provides high-level remotecontrol–vm_alloc(), vm_write(), thread_create() onkernel or any task• We want to still use MiG generated clientRPC stubs, don’t want to re-implement• <strong>Mac</strong>hiavelli acts as a <strong>Mac</strong>h RPC “bridge”,allowing tasks on two different machines todo RPC between them (both directions)26


<strong>Mac</strong>hiavelli Architecture• <strong>Mac</strong>hiavelli Proxy– Receives messages on proxy ports and sends to remote Agent– Replaces port names in messages received from remote Agentwith proxy ports• <strong>Mac</strong>hiavelli Agent– Receives messages over network from Proxy, sends to reallocal destination– Receives and transmits reply message if a reply is expected• <strong>Mac</strong>hiavelli RPC Server– Provides miscellaneous “glue” functionality like task_for_pid(),sysctl(), etc.27


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stub<strong>Mac</strong>h IPC<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent28


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stubTCP<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent29


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stub<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent<strong>Mac</strong>h IPC30


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stub<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent<strong>Mac</strong>h IPC31


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stubTCP<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent32


<strong>Mac</strong>hiavelli Message Flow<strong>Mac</strong>hiavelliProxy<strong>Mac</strong>h RPCclient stub<strong>Mac</strong>h IPC<strong>Mac</strong>h RPCserver stub<strong>Mac</strong>hiavelliAgent33


<strong>Mac</strong>h messages• <strong>Mac</strong>h messages are structured andunidirectional• Header:typedef struct{mach_msg_bits_tmach_msg_size_tmach_port_tmach_port_tmach_msg_size_tmach_msg_id_tmsgh_bits;msgh_size;msgh_remote_port;msgh_local_port;msgh_reserved;msgh_id;} mach_msg_header_t;• Body consists of typed data items34


Complex <strong>Mac</strong>h Messages• “Complex” <strong>Mac</strong>h messages contain out-of-linedata and may transfer port rights and/ormemory pages to other tasks• In the message body, descriptors describe theport rights and memory pages to be transferred• Kernel grants port rights to the receivingprocess• Kernel maps transferred pages to receivingprocess, sometimes at message-specifiedaddress35


Proxying <strong>Mac</strong>h Messages• Proxy maintains a <strong>Mac</strong>h port set– A port set has the same interface as a single port and canbe used identically in mach_msg()– Each proxy port in the set corresponds to the realdestination port name in the remote Agent– Port names can be arbitrary 32-bit values, so port setnames are pointers to real destination port name values• Received messages must be translated (local remote ports and descriptor bits)• Messages are serialized to byte buffers and thensent to Agent36


Serializing <strong>Mac</strong>h Messages• Serializing “simple” messages is simple asthey don’t contain any out-of-line data• Out-of-line data is appended to theserialized buffer in order of thedescriptors in the body• Port names are translated duringdeserialization–Translating to an intermediate “virtual portname” might be cleaner37


Deserializing <strong>Mac</strong>h Messages• Port names in the mach message must bereplaced with local port names• On Agent, this is done to receive the reply• On Proxy, this is done to replace transferredport names with proxy port names–Ensures that only the initial port must be manuallyobtained from the proxy, the rest are handledautomatically• OOL memory is mapped+copied into addressspace38


<strong>Mac</strong>hiavelli exampleint main(int argc, char* argv[]){kern_return_t kr;mach_port_t port;vm_size_t page_size;machiavelli_t m = machiavelli_init();machiavelli_connect_tcp(m, "192.168.13.37", "31337");port = machiavelli_host_self(m);if ((kr = _host_page_size(port, &page_size)) != KERN_SUCCESS) {errx(EXIT_FAILURE, "_host_page_size: %s", mach_error_string(kr));}printf("Remote host page size: %d\n", page_size);}return 0;39


MACHIAVELLI DEMO40


Miscellaneous Agent services• Agent must provide initial <strong>Mac</strong>h ports:–host port–task_for_pid() (if pid == 0 => returns kerneltask port)• As <strong>OS</strong> X is a <strong>Mac</strong>h/Unix hybrid, justcontrolling <strong>Mac</strong>h is not enough–i.e. How to list processes?• Instead of implementing Unix functionalityin Agent, inject <strong>Mac</strong>h RPC server code into41


Network Kernel Extensions (NKEs)•NKEs can extend or modify kernelnetworking functionality via:–Socket filters–IP filters–Interface filters–Network interfaces–Protocol plumbers42


MACH IN THE KERNEL43


<strong>Mac</strong> <strong>OS</strong> X Kernel <strong>Rootkits</strong>• Most <strong>Mac</strong> <strong>OS</strong> X Kernel <strong>Rootkits</strong> do traditionalUnix-style syscall filtering• They load as kernel extensions and removethemselves from kmod list– WeaponX, <strong>Mac</strong> Hacker’s Handbook, Phrack 66– Hides the kernel extension and prevents removal• Alternatively, code can be directly loaded intokernel via vm_allocate(), and vm_write()• In both cases, we have an unauthorized <strong>Mac</strong>h-Oobject file in the kernel44


Uncloaking Kernel <strong>Rootkits</strong>• Access to kernel task exposes kernel memory regions mapand gives direct access to kernel memory– get kernel task via task_for_pid(0)• Iterate over allocated regions, examining beginning for<strong>Mac</strong>h-O headers– Avoid reading volatile memory, causes panic• Multiple <strong>Mac</strong>h-O headers will may be found pointing to thesame text and data segments• Compare identified segments to segments loaded bykernel extensions in the kmod list• Suspicious <strong>Mac</strong>h-O objects can be dumped to disk forreverse engineering and analysis45


UNCLOAK DEMO46


Evasive Maneuvers• Unix system call filtering can’t evade<strong>Mac</strong>h kernel RPC (different interface)• There’s no reason why kernel rootkitsneed to be loaded as <strong>Mac</strong>h-O objects–vm_allocate() + thread_create() on kernel task–DKOM, return-oriented rootkits, etc.• Alternatively, filter in-kernel <strong>Mac</strong>h RPCservers47


Interposing on Kernel <strong>Mac</strong>h RPC• <strong>Mac</strong>h system calls allow <strong>Mac</strong>h RPC to in-kernelservers which perform task, thread, and VMoperations• RPC routines are stored in the mig_buckets hashtable by subsystem id + subroutine id• Analogous to sysent table for Unix system calls• Incoming <strong>Mac</strong>h messages sent to a kernel-ownedport are dispatched through mig_buckets• We can interpose on these function calls or injectnew RPC servers by modifying this hash table48


Example: inject_subsystemint inject_subsystem(const struct mig_subsystem * mig){}mach_msg_id_t h, i, r;// Insert each subroutine into mig_buckets hash tablefor (i = mig->start; i < mig->end; i++) {}mig_hash_t* bucket;h = MIG_HASH(i);do { bucket = &mig_buckets[h % MAX_MIG_ENTRIES];} while (mig_buckets[h++ % MAX_MIG_ENTRIES].num != 0 &&if (bucket->num == 0) {}return -1;h < MIG_HASH(i) + MAX_MIG_ENTRIES);r = mig->start - i;// We found a free spotbucket->num = i;bucket->routine = mig->routine[r].stub_routine;if (mig->routine[r].max_reply_msg)elsereturn 0;bucket->size = mig->routine[r].max_reply_msg;bucket->size = mig->maxsize;49


<strong>Mac</strong>h Kernel RPC servers• In-kernel <strong>Mac</strong>h RPC subsystems areenumerated in the mig_e table andinterfaces are in /usr/include/mach/subsystem.defs–mach_vm, mach_port, mach_host, host_priv,host_security, clock, clock_priv, processor,processor_set, is_iokit, memory_object_name,lock_set, ledger, semaphore, task, thread_act,vm_map, UNDReply, default_pager_object,security50


Conclusion• <strong>Mac</strong>h is a whole lot of fun• <strong>Mac</strong>h IPC can be made networktransparent and provides a goodabstraction for remote host control• I wish my desktop <strong>OS</strong> was as secure asiPhone <strong>OS</strong>• For updated slides and tools go to:–http://trailofbits.com/51

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!