Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MacOS security, hardening and forensics 101 workshop

Bea Hughes
October 19, 2017

MacOS security, hardening and forensics 101 workshop

Workshop slides for #DevSecCon 2017 in London

Bea Hughes

October 19, 2017
Tweet

More Decks by Bea Hughes

Other Decks in Technology

Transcript

  1. Who's this clown? ̣ — Security Engineer at Stripe —

    Infrastructure security at Etsy — Operations monkey at Puppet Labs — Was once retweeted by William Gibson! — basically, kind of a big deal ̣ https://twitter.com/skullmandible/status/411281851131523072 @benjammingh for DevSecCon 2017 2
  2. Agenda — Intro (we're crushing this already) — Mac OS

    history and sadness — Malware reversing and how — 5 minute break — Discovering problems in the first place — Hardening? — Fin @benjammingh for DevSecCon 2017 3
  3. Intro This is workshop, not an amzing slide deck, please

    throw any and all questions my way. PLEASE experiment, as hard as you can. This is not exhaustive, thankfully. @benjammingh for DevSecCon 2017 4
  4. The VM It's nasty. It has no network adaptor on

    it, so can only harm itself. Requires VMware Fusion on a Mac, due to licensing (the trial is on the drive too) @benjammingh for DevSecCon 2017 5
  5. So what Ben? — NeXTSTEP originally released in 1989. —

    The Mach Kernel project ran from 1985 to 1994. (somewhat hyperbolic, but you see what I'm saying) @benjammingh for DevSecCon 2017 12
  6. How scary? /* XXX this is _not_ designed to be

    fast */ /* wordexp is also rife with security "challenges", unless you pass it WRDE_NOCMD it *must* support subshell expansion, and even if you don't beause it has to support so much of the standard shell (all the odd little variable expansion options for example) it is hard to do without a subshell). It is probbably just plan a Bad Idea to call in anything setuid, or executing remotely. */ int wordexp(const char *__restrict__ words, wordexp_t *__restrict__ pwe, int flags) { /* cbuf_l's inital value needs to be big enough for 'cmd' plus about 20 chars */ size_t cbuf_l = 1024; char *cbuf = NULL; /* Put a NUL byte between each word, and at the end */ char *cmd = "/usr/bin/perl -e 'print join(chr(0), @ARGV), chr(0)' -- "; libc/gen/wordexp.c from the Apple FOSS mirror on github @benjammingh for DevSecCon 2017 13
  7. So macs are not as secure as their marketing makes

    out. @benjammingh for DevSecCon 2017 14
  8. [durazac:malware]% hdiutil attach -readonly -noautoopen MacKeeper.dmg /dev/disk2 /Volumes/MacKeeper Installer [durazac:malware]%

    cd /Volumes/MacKeeper\ Installer [durazac:MacKeeper Installer]% ls MacKeeper.pkg @benjammingh for DevSecCon 2017 18
  9. [durazac:malware]% mkdir mc ; cd mc [durazac:malware]% file /Volumes/MacKeeper\ Installer/MacKeeper.pkg

    /Volumes/MacKeeper Installer/MacKeeper.pkg: xar archive version 1, SHA-1 checksum [durazac:mc]% xar -x -f /Volumes/MacKeeper\ Installer/MacKeeper.pkg xar - eXtensible ARchiver @benjammingh for DevSecCon 2017 19
  10. Moar packages! [durazac:mc]% ls -l total 16 -rw-r--r-- 1 ben

    staff 6344 Oct 4 20:43 Distribution drwxr-xr-x 6 ben staff 192 Oct 4 20:43 LaunchOffer.pkg drwxr-xr-x 7 ben staff 224 Oct 4 20:43 MacKeeper.pkg drwxr-xr-x 23 ben staff 736 Oct 4 20:43 Resources drwxr-xr-x 7 ben staff 224 Oct 4 20:43 comzeobitmackeeper.pkg @benjammingh for DevSecCon 2017 20
  11. Extract the pre/post install scripts [durazac:comzeobitmackeeper.pkg]% mkdir installscripts [durazac:comzeobitmackeeper.pkg]% cd

    installscripts [durazac:installscripts]% tar zxvf ../Scripts x postinstall @benjammingh for DevSecCon 2017 22
  12. Extract the payload [durazac:comzeobitmackeeper.pkg]% mkdir paidload [durazac:comzeobitmackeeper.pkg]% cd paidload [durazac:paidload]%

    tar zxvf ../Payload x . [durazac:paidload]% ls -la ../Payload -rw-r--r-- 1 ben staff 82 Oct 5 04:43 ../Payload Wait, there's no payload? @benjammingh for DevSecCon 2017 23
  13. [durazac:~]% for ((i=0; i<=4; i++)) { echo \ 'LkdrJsYk22BjaHVOE3GOnE1VLCrnV/sTam3BaGjNOJp8O4fjMrBjekTT 94idx4n5A3EtUzi/lRtLoJvx2zhu3HG7PP/HsJnExsrj6UK4/CVsCCi/4

    l0JcFGW1RPAzyHmqIEpi3cQ5RbYt3qXv8XVGtHvLNFCTYJk4z3F4J+2qf wZSS9mYVMkz9RgADO6WT4pQlqQoyHFXi5guCzIuZEYn5IHDLANtlqqnzD 7z1Nvl328SDp9nT9ZfQPd5EGt5veFncPM8qObrXqdUr1Ib8zIWt4FjYjH N6rtIk+S3QXluOMA8v8/SaUxj8zFZNjJy/3dKNzByl70ePGKKnJ16JIZo 1BOFG5Ate3x/87ECj7fTgVjR1TRuPHbvUtgeSMdmVNtmI+rOKFehPUSjb HXQiw/RNyCIE7WlcSczl/0P04HOZmeTaFdxetWvKwI8kIiD0dQbFQBalN cS8qgtG1gAllMqKFnjYD6wWXeQTBaWuBBo8FfCEuXKiFvrBoBiZlFxeQK' \ | base64 -D \ | dd bs=128 count=1 skip=$i 2>/dev/null \ | openssl rsautl -verify -pubin -inkey somekey 2>/dev/null \ } | python -mjson.tool @benjammingh for DevSecCon 2017 25
  14. Which outputs { "affid": "358.20580063.1507174981.32.mzb", "arePopupsAggressive": false, "bundleId": "29_317511156", "enableAnalytics":

    true, "extendedStatisticIntervalInDays": 30, "ga_cid": "805354281.1507174983", "systemScanHasSignupStep": true, "trialDays": 0, "trtId": "FF2B241D-9456-4D5E-A4D5-50B67C3F0715", "trtVersion": 11 } @benjammingh for DevSecCon 2017 26
  15. 38 MAC_ADDRESS=$(networksetup -getmacaddress en0 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}') 39

    if [ -z "$MAC_ADDRESS" ]; then 40 ▸ MAC_ADDRESS=$(networksetup -getmacaddress en1 | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}') 41 fi 42 43 SERIAL_NUMBER=$(ioreg -c IOPlatformExpertDevice -d 2 | awk -F\" '/IOPlatformSerialNumber/{print $(NF-1)}') 44 45 DEVICE_ID=$(echo "${SERIAL_NUMBER}|${MAC_ADDRESS}" | sed -e 's/:/%3A/g;s/|/%7C/g') ... 53 ▸ ▸ REINSTALL_DATA="step=MKInstallEvents&affid=${AFFID}&bundleId=${BUNDLEID}&prodID=${MK_PRODUCT_ID}&version=${SOURCE_VERSION}&device_id=${DEVICE_ID}.... ... 57 ▸ ▸ curl -q -f --silent --data "$REINSTALL_DATA" "http://event.mackeeper.com/event.php" it's sending my MAC address where now!? @benjammingh for DevSecCon 2017 27
  16. [durazac:comzeobitmackeeper.pkg]% <Payload gunzip -cd| tar vtf - drwxrwxr-t 2 0

    80 0 May 12 02:42 . [durazac:comzeobitmackeeper.pkg]% lsbom Bom . 41775 0/80 Wait, so there is no payload, it just runs that super sketch script!?!? @benjammingh for DevSecCon 2017 28
  17. MacKeeperOffers.pkg Now we just do the same for MacKeeperOffers until

    we find something interesting [durazac:MacKeeperOffers]% strings -a checkinstall | tail -12 JustCloud MegaBackup YahooSearch Appswell YoutubeConverter /Applications/MegaBackup.app /Applications/JustCloud.app com.apple.Safari HomePage hspart=iry /Applications/Appswell.app /Applications/Softorino YouTube Converter X.app @benjammingh for DevSecCon 2017 29
  18. Looking at the Offers.pkg/Scripts/MegaBackup line 55 [durazac:~]% TID=1 [durazac:~]% URL='http://land.megabackup.com/'

    [durazac:~]% URL+='paramss=phexafefced9b4b5c9ac9297a0af999' [durazac:~]% URL+='cd2e8cb90b1b5cecfc1e2c8cad5cdd9ddcec49d' [durazac:~]% URL+='aadcd2d5a9a490e3e5c0d1c3ded5cdd0cfdbce9' [durazac:~]% URL+="496dfded99c&trt=51_72&tid_ext=${TID}" [durazac:~]% [durazac:~]% curl -q -f -L --max-redirs 150 \ --output some.file "$URL" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 100 40238 100 40238 0 0 29387 0 0:00:01 0:00:01 --:--:-- 51455 [durazac:~]% file some.file some.file: xar archive - version 1 @benjammingh for DevSecCon 2017 31
  19. go all the way back to the first dir [durazac:mc]%

    egrep -Riha -o 'https?://[-\.a-z0-9_]+/' . | sort -u http://cdn.mackeeper.com/ http://event.mackeeper.com/ http://land.megabackup.com/ http://ldrapi1.megabackup.com/ http://mackeeperapp.mackeeper.com/ http://www.apple.com/ @benjammingh for DevSecCon 2017 32
  20. Blocking domains — If you run your own resolvers, then

    my talk on sinkholing from 2014 — If you use OpenDNS * and you should! read here — on the cheap * obviously doesn't scale cat <<EOF | sudo tee -a /etc/hosts && pkill -HUP mDNSResponder 127.0.0.1 cdn.mackeeper.com event.mackeeper.com mackeeperapp.mackeeper.com EOF @benjammingh for DevSecCon 2017 33
  21. xa!r Extended attributes! [durazac:Downloads]% ls -l Hopper-4.1.4-demo.dmg -rw-r--r--@ 1 barn

    staff 28746615 Apr 28 14:51 Hopper-4.1.4-demo.dmg [durazac:Downloads]% ls -l@ Hopper-4.1.4-demo.dmg -rw-r--r--@ 1 barn staff 28746615 Apr 28 14:51 Hopper-4.1.4-demo.dmg com.apple.diskimages.fsck 20 com.apple.diskimages.recentcksum 80 com.apple.metadata:kMDItemWhereFroms 151 com.apple.quarantine 71 @benjammingh for DevSecCon 2017 34
  22. Xprotect from /System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.plist <plist version="1.0"> <array> <dict> <key>Description</key> <string>OSX.AceInstaller.B.2</string> <key>LaunchServices</key>

    <dict> <key>LSItemContentType</key> <string>com.apple.application-bundle</string> </dict> <key>Matches</key> <array> <dict> <key>MatchFile</key> <dict> <key>NSURLTypeIdentifierKey</key> <string>public.unix-executable</string> </dict> <key>MatchType</key> <string>Match</string> <key>Pattern</key> <string>7365744F66666572734C6162656C</string> </dict> @benjammingh for DevSecCon 2017 36
  23. and com.apple.metadata:kMDItemWhereFroms bash-3.2# mdls -name kMDItemWhereFroms Hopper-4.2.21-demo.dmg kMDItemWhereFroms = (

    "https://d2ap6ypl1xbe4k.cloudfront.net/Hopper-4.2.21-demo.dmg", "https://www.hopperapp.com/download.html" ) @benjammingh for DevSecCon 2017 37
  24. Host based IDS — MIDAS - Intrusion Detection for Macs(super

    dead now) — OSSEC - Open Source HIDS SECurity Threaty threats paid things — Carbon Black Response — Clown Strike - Falcon — Red Canary @benjammingh for DevSecCon 2017 40
  25. Gui version of knock knock By the same author, Patrick

    Wardle. objective-see.com/products/knockknock.html @benjammingh for DevSecCon 2017 42
  26. OSXcollector Written in python by Yelp More of a forensics

    tool. Little more invasive say, my default dumps browser history. /usr/bin/python osxcollector.py spits out a tarball, inside that are system logs and a JSON report. @benjammingh for DevSecCon 2017 43
  27. bash-3.2# cat osxcollect-2017_10_18-09_23_37.json \ | while read line ; \

    do echo "$line" | python -mjson.tool || break ; \ done \ | less -R { "osxcollector_incident_id": "osxcollect-2017_10_18-09_23_37", "osxcollector_section": "version", "osxcollector_version": "1.9" } { "fde": false, "machine": "x86_64", "nodename": "dsc.local", "osxcollector_incident_id": "osxcollect-2017_10_18-09_23_37", "osxcollector_section": "system_info", "release": "17.0.0", "sysname": "Darwin", "version": "Darwin Kernel Version 17.0.0: Thu Aug 24 21:48:19 PDT 2017; root:xnu-4570.1.46~2/RELEASE_X86_64" } @benjammingh for DevSecCon 2017 44
  28. OSquery — built at Facebook (it scales) — cross platform

    (plan9, TOS, Xenix) — open source https://github.com/facebook/osquery/ — has a logo that makes you think of Gravatar @benjammingh for DevSecCon 2017 45
  29. OSquery cont. — Kolide - Beautiful osquery management tool. —

    Doorman - Doorman, OSS tool for doing the same. — Envdb - Looks pretty nice (but I've not used it yet) These are for fleet deployments, as osquery is just a SQL REPL for your system. @benjammingh for DevSecCon 2017 46
  30. But let's play with it! [durazac:~]% osqueryi Using a virtual

    database. Need help, type '.help' osquery> .mode line osquery> select * from osquery_info; pid = 1068 uuid = 564D335B-A20C-A42B-AB3B-9FCFCA4C07E7 instance_id = 9e14be42-d47a-4f88-b226-26366c20c67c version = 2.9.0 config_hash = df8743dd7fe17219a15ac0860d61c26d868ebc73 config_valid = 1 extensions = active build_platform = darwin build_distro = 10.12 start_time = 1508341272 watcher = -1 @benjammingh for DevSecCon 2017 47
  31. osquery> .tables => acpi_tables => ad_config => alf => alf_exceptions

    => alf_explicit_auths => alf_services => app_schemes => apps => arp_cache => asl or, more readably, osquery table schema docs @benjammingh for DevSecCon 2017 48
  32. fun osquery examples osquery> SELECT * From file ...> where

    path like "/Users/%/Library/LaunchAgents/com.%.MacKeeper.Helper.plist" ...> OR path like "/Users/%/Documents/MacKeeper Backups" ...> OR path = "/Applications/MacKeeper.app" ; osquery> select distinct( user ) from logged_in_users; more fun on a server osquery> select * from kernel_extensions where name not like 'com.apple.%'; not amaze on the VM, but good on my laptop @benjammingh for DevSecCon 2017 49
  33. Step 1 Manage your macs! — Fleetsmith - Fantastic new

    MaaS offering — Chef/Puppet - needs no introduction — Munki - manage software installs, rather than just have them — Simian - Simian is an enterprise-class Mac OS X software deployment solution, buuuut it's Google — JSS Jamf - Is another alternative, I guess @benjammingh for DevSecCon 2017 51
  34. Step 2 Just use Chrome — Pwn 2 Own's pricing

    scale — BrowserScope says so — Zerodium will pay you $150k for an exploit for Chrome, vs $80k for FreedomFox @benjammingh for DevSecCon 2017 52
  35. Step 3 — Make sure Gatekeeper is set to "app

    store" or "app store & signed" only (now the default) @benjammingh for DevSecCon 2017 53
  36. Step 3.5 — this doesn't solve homebrew, where you can

    just install whatever you wish [durazac~]% brew install sqlmap 1 ==> Downloading https://github.com/sqlmapproject/sqlmap/archive/1.1.10.tar.gz ==> Downloading from https://codeload.github.com/sqlmapproject/sqlmap/tar.gz/1.1.10 ######################################################################## 100.0% ! /usr/local/Cellar/sqlmap/1.1.10: 543 files, 10.3MB, built in 17 seconds @benjammingh for DevSecCon 2017 54
  37. Step 4 More restrictions — Santa! - Santa is a

    binary whitelisting/blacklisting system for macOS @benjammingh for DevSecCon 2017 55
  38. Hardening vs. reality You could make everyone in your company

    run OpenBSD on their laptop. You would go out of business very quickly. There's no good easy answer. ): @benjammingh for DevSecCon 2017 56
  39. Would you like to know more? — Reverse Engineering Mac

    Malware - Sarah Edwards — When Macs Get Hacked -Sarah Edwards — Hipster DFIR on OSX - Scott J. Roberts — Syscall Auditing at scale - Ryan Huber — Tracking a stolen code-signing certificate with osquery - Mike Myers — Methods of Malware Persistence - Patrick Wardle @benjammingh for DevSecCon 2017 57