Mac OS Rootkits Nanika & TT http://exploitspace.blogspot.com
Nov 11, 2014
Mac OS RootkitsNanika & TT
http://exploitspace.blogspot.com
About Us
Taiwan
Nanika Pan
Trend Micro Staff Research Engineer Core Tech Department
Speech Black Hat USA 2011 / 2012 Syscan Singapore/Taipei/Hong Kong 08/10 Hacks in Taiwan Conference 05/06/07/09/10/12
Research Vulnerability discovery and analysis Exploit techniques Malware detection Mobile security
Sung-ting Tsai (TT)
Trend Micro Leader of an advanced threat research team. Core Tech Department
Research New security technology Malicious document Malware auto-analyzing system (sandbox technologies) Malware detection System vulnerability and protection Mobile security
Speech Black Hat USA 2011 / 2012 Codegate 2012 Syscan 10’ / 12’ HITCon 08’
warm-up
defaults write com.apple.Finder AppleShowAllFiles 1
Mac OS Activity Monitor (Utilities)
plist file
/etc/rc.*
/etc/profile
/etc/bashrc
~/.bashrc
~/.profile
~/.login
/etc/inetd.conf
/etc/xinetd.d/
/etc/crontab
/etc/mach_init_per_user.d/
/etc/mach_init.d
XPCServices
/System/Library/LaunchAgents/
~/Library/LaunchAgents/
/System/Library/LaunchDaemons
~/Library/LaunchDaemons
~/Library/Preferences/com.apple.loginitems.plist
~/Library/StartupItems
/System/Library/StartupItems
http://blog.mktime.com/archive/365.html
sudo defaults write com.apple.loginwindow LoginHook /path/to/login.sh
sudo defaults write com.apple.loginwindow LogoutHook /path/to/logout.sh
http://www.malicious-streams.com/Downloads/Downloads.html
http://osxbook.com/book/bonus/ancient/whatismacosx/arch_startup.html
http://computer-forensics.sans.org/summit-archives/2012/when-macs-get-hacked.pdf
get root
sudo
AuthorizationExecuteWithPrivileges
http://www.michaelvobrien.com/blog/2009/07/authorizationexecutewithprivileges-a-simple-example/
Xcode build the file location
Debug Argv
gcc -framework CoreServices
AuthorizationExecuteWithPrivileges
• let's go crazy hacking
• Mac file format
• Lion vs Mountain Lion
• usermode aslr
• kernel aslr
• user rootkit
• user mode hook
• kernel rootkit
• syscall hook
• machtrap hook
• DKOM find process hide
• DKOM Advance process hide
• Anti Dtrace
macho
• otool
• macho_view http://sourceforge.net/projects/machoview/
• hopper Disassembler http://www.hopperapp.com/
Header
Entry Point
LINKEDIT
LC_DYLD_INFO
_la_symbol_ptr Section Header
_la_symbol_ptr
How to find Export Function Address
• SYMTable Address=LINKEDIT imagebase+(SYMTable Address-LINKEDIT FILEOffest)
• ex:string table->0x8fe5e000(0x3a344-0x35000)
ASLR
• mach-o ASLR MH_PIE
• http://www.0xcafebabe.it/2011/10/15/on-macos-10-7-dyld-randomization/
GDB attach
GDB open
• NO ASLR
• http://reverse.put.as/2011/08/11/how-gdb-disables-aslr-in-mac-os-x-lion/
ASLR usermode
• 10.7.x X64 mode main thread stack leak dyld image base
• 10.8.x random
osx10.7.x
Kernel ASLR
• mach_kernel 10.7.x no aslr
• File Function Addr = Mem Function Addr
• mach_kernel 10.8.x aslr
Get ASLR Kernel base
• __asm__ volatile ("sidt %0": "=m" (idtr));
• idt table function address is always in kernel function address
• search MACHO Magic to find kernel base
User mode hook
• DYLD_INSERT_LIBRARIES
• dynamic inject
• LD_PRELOAD=./gethostname.dylib FAKE_HOSTNAME=foo hostname foo
• DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=lib_overrides.dylib overrides_test
FILE * (*original_fopen) (const char *, const char *) =NULL;
FILE * fopen(const char * filename, const char * mode){ if (!original_fopen) original_fopen = dlsym(RTLD_NEXT, "fopen");
printf("== fopen: {%s,%s} ==\n", filename, mode); FILE* f = original_fopen(filename, mode); return f;}
gcc -Wall -o lib_overrides.dylib -dynamiclib lib_overrides.c
int main(int argc, char const *argv[])
{ char hello[] = "hello world"; FILE *fp = fopen("hello.txt", "w"); if (fp) { fwrite(hello, 1, strlen(hello), fp); fclose(fp); }
return 0;}
gcc -Wall -o overrides_test overrides_test.c
• if you do not see any event, don’t be surprised. Because this hook only changed the _la_symbol_ptr.
• http://tlrobinson.net/blog/category/gcc/
• mach_port_t!remoteTask = 0;
• pid_t!targetProcess;
• task_for_pid( mach_task_self(), targetProcess, &remoteTask );
Dynamic inject
• kern_return_t vm_read
(vm_task_t target_task,
vm_address_t address,
vm_size_t size,
size data_out,
target_task data_count);
• kern_return_t vm_write
(vm_task_t target_task,
vm_address_t address,
pointer_t data,
mach_msg_type_number_t data_count);
• kern_return_t vm_protect
(vm_task_t target_task,
vm_address_t address,
vm_size_t size,
boolean_t set_maximum,
vm_prot_t new_protection);
• kern_return_t thread_create_running
(" task_t parent_task," thread_state_flavor_t flavor," thread_state_t new_state," mach_msg_type_number_t new_stateCnt," thread_act_t *child_act);http://cansecwest.com/csw09/csw09-daizovi-miller.pdf
why vmmap piduse task_for_pid to
attach another task (no root) ? Because it needs Apple Code Signature
IDT with syscall
• idt[0x80] _idt64_unix_scall:ffffff80002d7480
• idt[0x81] _idt64_mach_scall:ffffff80002d74a0
• idt[0x82] _idt64_mdep_scall:ffffff80002d74c0
• idt[0x83] _idt64_diag_scall:ffffff80002d74e0
syscall
• "_nsysent"
• 10.7.x no aslr
• 10.8.x _nsysent + offset 0x1c028
mach trap
• “_mach_trap_table”
• 10.7.x = 10.8.x
• 10.8 add some new functions
Dtrace
• base on dtrace
• execsnoop
• iosnoop
• opensnoop
• rwsnoop
Dtrace User Guide
• sudo dtrace -s demo.d
• http://docs.oracle.com/cd/E18752_01/html/819-5488/gcfah.html
• https://www.blackhat.com/presentations/bh-usa-08/Beauchamp_Weston/BH_US_08_Beauchamp-Weston_DTrace.pdf
How Dtrace (FBT) provider work
• IDT
• _hndl_alltraps
• _kernel_trap
• http://opensource.apple.com/source/xnu/xnu-1699.22.73/osfmk/i386/trap.c
Modify
• change one byte code
• 55 push rbp
• 48 89 e5 mov rbp,rsp
• 55 push rbp
• 0f 89 e5 lock mov rbp,rsp
Handle Exception
• if (FBT_EXCEPTION_CODE == trapno && !IS_USER_TRAP(saved_state)) {
• _fbt_perfCallback
• _dtrace_invop
• http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/dev/i386/fbt_x86.c
Anti Dtrace (FBT)
• Load kext
• find symbol _tempDTraceTrapHook
• tempDTraceTrapHook->fbt_perfCallback
• tempDTraceTrapHook->your function
• handle exception
• fix any dtrace modified byte code
Process Hiding
• rubilyn rootkit
• http://www.nullsecurity.net/tools/backdoor/rubilyn-0.0.1.tar.gz
• Current DKOM => unlink p_list
• http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/sys/proc_internal.h
How to find hided process
• listing task can find hided process’ task
• http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/osfmk/kern/task.h
Usermode list task for finding rubilyn rootkit
DKOM unlink Task list
• this works on 10.7.x or 10.8.x
• demo
• install truehide.kext
• sudo kextload /System/Library/Extensions/truehide.kext
• sysctl -w debug.truehide.pid=?
How to find unlinked Task list?
• In usermode, you can still find something interesting.
• Demo
Defense
• check if any kext is loaded
• check if any task is attaching to another task
• http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/libkern/kxld/kxld.c
• http://opensource.apple.com/source/xnu/xnu-1504.7.4/libkern/c++/OSKext.cpp
• OSKext::loadExecutable()
• kxld_link_file(KXLDContext *context,u_char *file,u_long size,const char *name,void *callback_data,u_char **deps,u_int ndeps,u_char **_linked_object,kxld_addr_t *kmod_info_kern,u_char **_link_state,u_long *_link_state_size,u_char **_symbol_file __unused,u_long *_symbol_file_size __unused)
monitor task_for_pid
Summary• mach-o file format
• 10.7.x vs 10.8.x ASLR
• static inject | dynamic inject
• Dtrace and AntiDtrace
• detecting rootkit with proc struct unlink and advanced task unlink
• How to detect kext loading
• Q&A