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

Leveraging Apple’s Game Engine to Detect Threats

Leveraging Apple’s Game Engine to Detect Threats

To detect new Mac malware, a behavior-based approach is needed. This talk will discuss our open-source monitoring framework which passively collects system events, and will then detail our rule-based system that leverages Apple’s game engine to quickly and efficiently apply rules against these collected events. End result? A comprehensive, extensible detection, response and threat hunting platform.

Patrick Wardle

March 05, 2019
Tweet

More Decks by Patrick Wardle

Other Decks in Technology

Transcript

  1. #RSAC
    SESSION ID: HTA-T08
    What’s Your Game Plan? 

    Leveraging Apple’s Game Engine to Detect Threats
    Co-Founder, Digita Security
    Patrick Wardle

    View Slide

  2. #RSAC
    WHOIS
    @patrickwardle
    +
    JOSH STEIN JON MALM
    }
    research
    (free!) tools

    View Slide

  3. #RSAC
    Outline
    Threats
    (malware & bugs)
    Monitoring 

    ("MonitorKit")
    Detection

    ("GamePlan")

    View Slide

  4. (Recent) Mac Malware
    Threats

    View Slide

  5. #RSAC
    The Reality
    Macs are no more resistant to malware,
    than their (modern) Windows counterparts.
    93%
    7%
    "ok, then why not more
    mac malware!?"
    7.1% of personal computer
    market (Q2 2018, Gartner)
    ...what makes
    the most money?

    View Slide

  6. #RSAC
    Macs vs. Malware
    "Mac-specific malware increased by 270% in 2017 compared
    with 2016, and four new Mac threats were detected in the
    first two months of 2018" -Malwarebytes
    2017/2018
    malware/adware
    continues to proliferate

    View Slide

  7. #RSAC
    OSX.FruitFly (2017)
    spying on victims (children) for over a decade
    $ cat fpsaud
    #!/usr/bin/perl use strict;use warnings;use IO::Socket;use
    IPC::Open2;my$l;sub G{die if!defined syswrite$l,$_[0]}sub J{my($U,
    $A)=('','');while($_[0]>length$U){die if!sysread$l,$A,$_[0]-......
    "For more than 13 years, Phillip Durachinsky allegedly infected
    with malware the computers of 1000s of Americans and stole their
    most personal data and communications" -Assistant Attorney General
    backdoor (obfuscated perl)

    View Slide

  8. #RSAC
    OSX.MaMi (2018)
    a dns hijacker…ported from Windows?
    installs (root) certificate
    modifies DNS server settings
    Mac port of 'Win32.DNSUnlocker'?
    'same' malicious DNS servers
    identical certificate thumbprint

    View Slide

  9. #RSAC
    OSX.AppleJeus (2018)
    lazarus group's (n. korea) first macOS implant
    updater
    (malicious)
    +
    Celas Trade Pro,
    from "Celas Limited"
    fake company!

    View Slide

  10. #RSAC
    OSX.WindShift (2018)
    file exfiltration implant , with a unique infection vector
    yan {
    [self yoop:@"BouCfWujdfbAUfCos/iIOg=="];
    [self yoop:@"Bk0WPpt0IFFT30CP6ci9jg=="];
    [self yoop:@"RYfzGQY52uA9SnTjDWCugw=="];
    [self yoop:@"XCrcQ4M8lnb1sJJo7zuLmQ=="];

    Read: "Analyzing WindShift's Implant:
    OSX.WindTail (part 1 & 2)" -digitasecurity.com
    encrypted file extensions
    persistence
    doc, docx,
    xls, xlsx,
    ppt, pdf, db,
    txt, rtf, pptx
    infection
    }

    View Slide

  11. #RSAC
    OSX.CreativeUpdate (2018)
    cryptominer distributed via 'macupdate.com'
    not mozilla!
    $ cat ~/Library/LaunchAgents/MacOS.plist
    ProgramArguments

    sh
    -c

    ~/Library/mdworker/mdworker 

    -user [email protected] -xmr


    ...
    persistent cryptominer
    (xmr)
    macupdate.com
    security alert
    ...previously at RSA

    View Slide

  12. #RSAC
    The Mac Malware of 2018
    digitasecurity.com/
    blog/2019/01/01/malware2018/
    infection vector
    persistence mechanism
    capabilities / payload
    samples (for download)
    a comprehensive report on infection, persistence, and capabilities

    View Slide

  13. (Recent) Mac Vulnerabilities
    Threats

    View Slide

  14. #RSAC
    The Reality
    Macs are just as susceptible to vulnerabilities
    as their (modern) Windows counterparts
    ...if not more so!
    market rates for 0days
    (2019)
    wise words from
    @thegrugq
    <

    View Slide

  15. #RSAC
    CVE-2017-7149: Password Exposure
    for encrypted volumes: hint == password!? (@martiano_)
    [SKHelperClient addChildVolumeToAPFSContainer: ...password: passwordHint: ...]
    //save password
    if(password != nil)
    [infoDictionary setObject:password forKey:@"kSKAPFSDiskPasswordOption"];
    //save password hint
    if(passwordHint != nil)
    [infoDictionary setObject:password forKey:@"kSKAPFSDiskPasswordHintOption"];
    password value stored in 'hint' key
    create encrypted
    AFPS volume
    set (any)
    password hint
    later:'Show Hint' 

    ...reveals password!
    cut & paste fail?
    }

    View Slide

  16. #RSAC
    CVE-2017-13872: #iamroot
    click twice, get root...no really!
    0day on Apple's forums!?
    proof of concept
    //verify
    int match = kODErrorCredentialsInvalid;
    if(kODErrorSuccess != od_verify_crypt_password(accountHash, providedPassword, &match, ...){
    //error
    goto bail;
    }
    //ok happy!
    // allow authentication/login
    'match' variable never checked
    never checked!

    View Slide

  17. #RSAC
    CVE-2018-4407: pure remote ring-0!?
    heap-overflow in (kernel) packet handling (@kevin_backhouse)
    "Kernel RCE caused by buffer overflow in Apple's ICMP packet
    handling code (CVE-2018-4407)" -https://lgtm.com/blog/
    }
    remote
    ring-0
    no-user
    interaction

    View Slide

  18. #RSAC
    CVE-2019-6223: #FacePalm
    audio/video streamed before the call is confirmed
    streamed,
    before call is answered :(
    0day on Twitter …in the New York Times
    patch (callservicesd)

    View Slide

  19. #RSAC
    0day: 'KeySteal'
    dump all things from the keychain (@linushenze)
    private keys
    passwords
    dump the macOS keychain

    View Slide

  20. #RSAC
    The Mac App Store
    ...unfortunately, not safe either!
    "The safest place to download apps for your Mac is the Mac
    App Store. Apple reviews each app before it’s accepted"
    "Adware Doctor" #4
    @privacyis1st
    -apple.com
    "Adware Doctor"
    to .CN?

    View Slide

  21. an open-source macOS monitoring framework
    Monitoring (MonitorKit)

    View Slide

  22. #RSAC
    An Overview
    MonitorKit
    process
    file
    monitor all things (events)
    download
    screen capture
    usb
    synthetic-click
    keylogging
    webcam/mic
    login
    standardized
    events

    View Slide

  23. #RSAC
    Process Monitoring
    via OpenBSM auditing
    "[applications can] tap into the audit stream...the kernel
    provides a character device: /dev/auditpipe" -j. levin
    connect to: 

    /dev/auditpipe
    set 'events' of interest:
    AUDIT_CLASS_EXEC

    AUDIT_CLASS_PROCESS
    read & tokenize
    header
    body
    trailer
    struct tokenstr {
    u_char id; 

    u_char *data;
    size_t len;
    union {} tt;
    }
    }
    au_header au_subject
    au_path_t au_execarg_t

    View Slide

  24. #RSAC
    Process Monitoring
    via OpenBSM auditing
    //events of interest (process events!)
    let mask: u_int = AuditConstants.AUDIT_CLASS_PROCESS | AuditConstants.AUDIT_CLASS_EXEC
    //but only start/stop events
    let filter: [UInt16] = [
    UInt16(AUE_EXEC), UInt16(AUE_EXIT),
    UInt16(AUE_FORK), UInt16(AUE_EXECVE), UInt16(AUE_POSIX_SPAWN)
    ]
    //init monitor
    // tokenize and print
    if let monitor = try? BSMMonitor(mask, recordFilter: filter) {
    monitor.start { (record: BSMRecord) in
    for token in record.tokens {
    print("Token \(token.tokenString()):\n \(token.stringValue())")
    }
    }
    }
    raw OpenBSM process
    monitoring //start process monitor
    // monitor for process start/end events
    if let monitor = try? ProcessMonitor() {
    monitor.start { (event: ProcessEvent) in

    if event.type == .CREATE {
    print("Process with pid \(event.pid) created")
    } else if event.type == .EXIT {
    print("Process with pid \(event.pid) exited")
    }
    }
    }
    abstracts OpenBSM:
    reading,
    tokenization, etc...
    ProcessMonitor
    fully abstracts OpenBSM
    'ProcessEvent': create
    'ProcessEvent': exit

    View Slide

  25. #RSAC
    File Monitoring
    via FSEvents
    connect to:
    /dev/fsevents
    set 'events' of interest:
    FSE_CREATE_FILE

    FSE_DELETE
    read & tokenize events
    file create
    file delete
    etc...
    let monitor = FileMonitorFSE()
    public static let filter = [
    FSEventTypes.CREATE_FILE.rawValue,
    FSEventTypes.DELETE.rawValue,
    ...
    ]
    monitor.start(eventFilterInclude: filter)
    { event in
    print("\(event.pid) \(event.type.string) \
    (event.path)")
    }
    Apple's FSEvents API: no pid
    for the file i/o event :(
    FileMonitor
    abstracts fsevents internals

    View Slide

  26. #RSAC
    Download Monitoring
    via Spotlight Notifications
    "NSMetadataQueryDidUpdate"
    Spotlight
    //register for NSMetadataQueryDidUpdate
    // item of interest: NSMetadataItemWhereFromsKey
    public class DownloadMonitor: BaseSpotlightMonitor {
    public init() {
    super.init(predicate:
    NSPredicate(format: "%K like ‘*'", NSMetadataItemWhereFromsKey),
    forNotification: NSNotification.Name.NSMetadataQueryDidUpdate)
    }
    }
    new file downloaded
    DownloadMonitor
    //init/start monitoring
    DownloadMonitor().start() { event in
    print("Downloaded File \(event.path)")
    }

    View Slide

  27. #RSAC
    Keylogger Monitoring
    via Core Graphics Event Notifications
    "kCGNotifyEventTapAdded"
    //register for kCGNotifyEventTapAdded
    public class EventTapsMonitor: NSObject {
    public func start(eventHandler: @escaping EventTapsHandler) {


    //register for notification
    notify_register_dispatch(kCGNotifyEventTapAdded, &self.notifyToken,
    DispatchQueue.global()) { [weak self] event in

    //report any new taps!
    for newTap in newTaps.keys where nil == strongSelf.previousTaps[newTap] {
    if let tap = newTaps[newTap] {
    eventHandler(EventTapsEvent(tap: tap))
    }
    }

    EventTapsMonitor
    new event tap (keylogger)
    //init/start monitoring
    EventTapsMonitor().start() { event in
    print("new keyboard event tap \(event.source)")
    }

    View Slide

  28. #RSAC
    Synthetic Click Monitoring
    via a (passive) Core Graphics event tap
    allow
    access keychain?
    "synthetic click"
    ...in the news
    source pid
    "state"

    (0x1 if synthetic)

    View Slide

  29. #RSAC
    Cam/Mic Monitoring
    via AVFoundation notification(s)
    OSX.Crisis
    OSX.Eleanor
    OSX.Mokes
    OSX.FruitFly
    public class AudioVideoMonitor: NSObject {
    public func start(eventHandler: @escaping AudioVideoHandler) {
    var property = CMIOObjectPropertyAddress(
    mSelector: kAudioDevicePropertyDeviceIsRunningSomewhere,
    mScope: kAudioObjectPropertyScopeGlobal,
    mElement: kAudioObjectPropertyElementMaster)
    CMIOObjectAddPropertyListener(camID, &property, camCallback,
    Unmanaged.passUnretained(self).toOpaque())
    AudioVideoMonitor.start() { event in
    print("NEW A/V EVENT")
    print("type: ", event.type)
    print("name: ", event.name)
    print("state: ", event.state)
    }
    $ ./monitorAV
    NEW A/V EVENT
    type: mic
    name: Built-in Microphone
    state: 1 (On)
    NEW A/V EVENT
    type: cam
    name: FaceTime HD Camera
    state: 1 (On)
    AudioVideoMonitor
    }

    View Slide

  30. #RSAC
    MonitorKit
    monitor all things
    iokit notifications
    openbsm monitoring
    fs events
    core graphic events
    spotlight notifications
    core graphic taps
    av foundation notifications
    MonitorKit
    standardized
    events
    100% user-mode
    open-source

    View Slide

  31. ...by leveraging apple's game logic engine
    Detection (GamePlan)

    View Slide

  32. #RSAC
    So far...
    mac threats
    monitor all things
    [MonitorKit]
    }
    malware exploits
    detect (all?) things
    efficiently:

    many events, complex rules
    contextually:
    structured output, w/ history
    flexibly:
    modify/add detections w/o code

    View Slide

  33. #RSAC
    Game (Logic) Engine
    sensor(s) modeled events state
    actuators
    logic controller
    (Σ logic blocks)
    src:docs.blender.org
    play!
    pieces of the puzzle

    View Slide

  34. #RSAC
    Game (Logic) Engine: (re)Applied
    cache
    MonitorKit
    analytics
    actions
    (alert, log, etc)
    missing piece

    View Slide

  35. #RSAC
    Apple's "GameplayKit"
    State Machines
    Components
    Randomization
    Strategists
    Goals, Behaviors Pathfinding Rule Systems
    Rule Systems 

    (GKRuleSystem):
    "allows a list of [logic
    blocks], together with context
    for evaluating them and
    interpreting results, for use
    in constructing data-driven
    logic or fuzzy logic systems"
    Apple's Game Engine Framework
    "separates game design from
    executable code"
    ...this "Rule System" is really a
    logic controller (applicable to
    analytics)!?
    "GameplayKit"

    View Slide

  36. #RSAC
    GKRuleSystem Class
    pac-man's ghosts, as an example
    define & load ghost logic
    (re)evaluate game logic
    respond to output of engine evaluation
    //init logic system
    let sys = SimpleLogicSystem()
    sys.update(powerPellet: true)


    //later
    sys.update(powerPellet: false)
    "run, Forest, run!"
    "lets go hunting"
    (abridged) ghost logic
    "chase" mode:
    ...hunt pacman
    "frightened" mode:
    ...run!

    View Slide

  37. #RSAC
    GKRuleSystem Class
    "allows a list of [logic blocks], together with context for
    evaluating them and interpreting results, for use in constructing
    data-driven logic or fuzzy logic systems"
    "allows a list of [logic blocks]"
    rules, (or in Apple parlance: NSPredicates)
    "context for evaluating them
    and interpreting results"
    "for use in constructing
    data-driven logic...systems"
    regex, etc.

    View Slide

  38. #RSAC
    "Game Plans"
    defining predicates (rules) across the Mitre ATT&CK Framework
    Initial Access Execution Persistence
    Privilege Escalation Defense Evasion Credential Access
    Discovery Lateral Movement Collection
    Exfiltration Command & Control
    LuLu
    KnockKnock BlockBlock ReiKey
    }

    View Slide

  39. #RSAC
    $event.isNewDirectory == 1 AND (
    $event.path MATCHES[cd] "/System/Library/Extensions/[^/]*" OR
    $event.path MATCHES[cd] "/Library/Extensions/[^/]*"
    ) -> Persist, Kext
    Developing "Game Plans"
    detecting methods of persistence
    Objective-See's BlockBlock
    ... -> Persist, Kext
    ... -> Persist, Launch
    ... -> Persist, EventMonitor
    ... -> Persist, AppLoginItem
    ... -> Persist, LoginItem
    ... -> Persist, CronJob
    ... -> Persist, StartupItem
    ... -> Persist, LoginHook
    ... -> Persist, SpotlightImporter
    ... -> Persist, SecurityAgentPlugin
    ... -> Persist, DYLDInsert(App)
    ... & "Launch" -> Persist, DYLDInsert(LaunchD)
    malware persistence techniques
    Kext Persistence
    Logic block: NSPredicate over data model
    file events
    (MonitorKit) labeled
    (by logic block)

    View Slide

  40. #RSAC
    Chaining Logic Blocks
    ...for more accurate and actionable detection
    label:
    persisted
    "how am I supposed to
    know I should click 'block'"
    logic block: 

    code signing
    logic block: 

    persist && 

    (!Apple && !AppStore)
    alert!
    + label: 

    signing info

    View Slide

  41. #RSAC
    Advanced Behavioral Detections
    towards generic ransomware detection
    file modification 

    (i.e. in /Users/*)
    process is non-Apple
    file contents encrypted
    multiple encrypted files
    ransomware detection algorithm
    (objective-see.com/blog/blog_0x0F.html)
    }
    $event.isModified == TRUE AND
    $event.path MATCHES[cd] "/Users/*" AND
    !$event.process.labels.contains("AppleSigned", "AppStore") AND
    $event.contents.encrypted == TRUE
    untrusted encryption
    $event.labels.contains("UntrustedEncrypt") AND
    @SUBQUERY(cache, $e, $e.date > (X sec ago) AND
    $e.process.pid == $event.process.pid)[email protected] > 3 -> Ransomware
    multiple encryption
    previous tag/label
    ransomware

    View Slide

  42. #RSAC
    $event.isNew == 1 AND
    $event.file.onRemovableMedia == 0 AND
    $event.path MATCHES[cd] \"/Volumes/.*\"
    Profiles/Rule "Flavors"
    an example: detect malicious insiders
    Goal:
    detect "insider threat"
    USB writes
    $event.path == "/usr/bin/sudo"
    'sudo' usage
    screen captures after-hours activity
    suspicious insider
    }
    alert !

    View Slide

  43. #RSAC
    Detect (All?) Things
    hail the power of the predicate!
    ($event.isModified == 1 OR $event.isNew == 1) AND 

    ($event.path BEGINSWITH[cd] '/System/' OR $event.path BEGINSWITH[cd] '/usr/' OR
    $event.path BEGINSWITH[cd] '/bin/' OR $event.path BEGINSWITH[cd] '/sbin/') AND NOT
    ($event.path BEGINSWITH[cd] '/usr/local/') AND
    event.file.isExecutable AND

    $event.file.signingInfo.signerType != Apple
    $event.type == file.delete AND
    $event.process.path == $event.path
    self-deletion

    (malware)
    $event.type == file.create AND
    $event.path MATCHES[cd] "/Users/.*/
    Library/Logs/DiagnosticReports/*"
    crash reports
    (anti-exploitation)
    SIP bypasses
    (anti-exploitation)

    View Slide

  44. #RSAC
    Threat Hunting
    collect, hunt, mitigate ...repeat
    stream events
    }
    deploy (new) rule
    hunt!

    View Slide

  45. #RSAC
    GamePlan
    ...detect all things?
    alerts

    View Slide

  46. #RSAC
    GamePlan
    create, edit, manage analytics (rules)
    analytic (rules) interface
    edit analytic

    View Slide

  47. #RSAC
    GamePlan
    real-time audit/compliance insights
    CIS Security Benchmark

    View Slide

  48. ...mac malware / exploits!
    GamePlan vs.

    View Slide

  49. #RSAC
    Known Mac Malware
    rules (predicates) to detect known threats
    OSX.iWorm
    "LaunchD" IN $tags AND
    $context.Name.value == "com.javaw.plist"
    OSX.Eleanor
    "LaunchD" IN $tags AND
    $context.Name.value in {
    "com.getdropbox.dropbox.timegrabber.plist",
    "com.getdropbox.dropbox.usercontent.plist"}

    View Slide

  50. #RSAC
    OSX.FruitFly
    building a better trap (install time)
    ($event.path MATCHES[cd] "/Library/LaunchAgents/.*.plist" OR
    $event.path MATCHES[cd] "/Users/.*/Library/LaunchAgents/.*.plist") AND
    $event.isNewFile == 1
    !$event.file.contentsAsDict.ProgramArguments[0].signingInfo("AppleSigned")
    launch agent
    persistence
    $ cat ~/Library/LaunchAgents/
    com.client.client.plist
    ...



    ProgramArguments

    ~/.client

    ...
    "LaunchD" IN $tags AND
    $event.file.contentsAsDict.ProgramArguments[0].
    lastPathComponent.startsWith(".")
    launch item persistence
    not signed by apple
    'hidden' binary
    alert !

    View Slide

  51. #RSAC
    OSX.FruitFly
    building a better trap (runtime time)
    $event.process.path.lastPathComponent.startsWith(".")
    $event.process.path.startsWith("/tmp")
    $event.process.labels.contains("Unsigned")
    +
    webcam synthetic clicks
    +
    +
    ...other generic
    detection predicates!?
    hidden process
    dropper payload in /tmp
    unsigned process
    +

    View Slide

  52. #RSAC
    OSX.WindShift
    detecting initial exploitation vector $ cat Final_Presentation.app/Contents/Info.plist


    ...
    CFBundleURLTypes


    CFBundleURLSchemes

    openurl2622007



    $event.isNewDirectory == 1 AND
    $event.file.isAppBundle == 1 AND
    $event.file.bundle.infoDictionary.CFBundleURLTypes != nil
    $event.isNewDirectory == 1 AND
    $event.process.name == 'Safari'
    Safari 'auto-open' 'auto' URL handler registration
    Safari created dir app with custom URL handler

    View Slide

  53. #RSAC
    OSX.MaMi (2018)
    detecting dns hijacking (and self-deletion)
    hijacked DNS settings
    modified DNS alert
    self-deletion alert
    alert !

    View Slide

  54. #RSAC
    *.Adware
    ...our favorite generic detector!
    $event.process.path.contains("Adobe") OR
    $event.process.path.contains("Flash")
    contains "Adobe" or "Flash"
    !($event.process.sigtype == Dev AND
    $event.process.signer != "Adobe Systems, Inc.")
    ...but is not signed by Adobe
    alert !

    View Slide

  55. Conclusions

    View Slide

  56. #RSAC
    Apply!
    Yes, Macs are hackable and rather
    susceptible to malware...
    Peruse the MonitorKit source code
    [ to be posted shortly on GitHub ]
    Deploy a product such as GamePlan to detect:
    mac exploitation
    malicious insiders
    mac malware (known & unknown)
    }

    View Slide

  57. #RSAC
    Finale
    @patrickwardle
    Digita Security
    cybersecurity solutions for the mac enterprise
    CleanMyMac X
    Guardian
    Mobile Firewall
    On a personal note:
    Mahalo to the: "Friends of Objective-See"

    View Slide

  58. #RSAC
    One more thing...
    Announcing OBTS 2.0: the world's only mac security conference
    June 1-2 Monaco ObjectiveByTheSea.com
    Free

    View Slide

  59. #RSAC
    Question & Answers
    JOSH STEIN JON MALM
    PATRICK WARDLE
    JON
    JOSH
    PATRICK
    FOUNDER/CEO FOUNDER/CTO
    FOUNDER/CRO
    @DIGITASECURITY.COM
    }
    Digita Security

    View Slide