一、背景

近期,我一直專注于macOS持久化領(lǐng)域,特別選擇了一些較低級別用戶可以修改的文件,而這些文件可能會影響用戶交互。我發(fā)現(xiàn),終端用戶經(jīng)常進(jìn)行交互的一個位置是Dock。
通過研究,我發(fā)現(xiàn)有一個plist負(fù)責(zé)控制Apple Dock應(yīng)用程序的可視化呈現(xiàn)。在這里沒有太多突破性內(nèi)容,因?yàn)榻K端用戶經(jīng)常會通過圖形化界面(GUI)來修改這一plist。在查看了plist中的值之后,我想探究是否可以更改這些值,從而使用運(yùn)行自定義代碼的惡意應(yīng)用程序來替換合法的應(yīng)用程序。
這項(xiàng)研究中的一個突破是DockPersist.js,我將其納入到PersistentJXA項(xiàng)目之中。在我的實(shí)現(xiàn)中,將使用惡意應(yīng)用程序替換Safari或Chrome。我主要研究Safari和Chrome,因?yàn)槎吆芸赡軙霈F(xiàn)在用戶的Dock中。但是,這一理論實(shí)際上適用于任何應(yīng)用程序。終端用戶在單擊Safari或Chrome圖標(biāo)后,就會運(yùn)行我們的惡意應(yīng)用程序。這種持久化方式類似于Windows上的快捷方式(.LNK)文件持久化,因?yàn)樵趍acOS中,Dock圖標(biāo)通常會作為實(shí)際應(yīng)用程序的快捷方式。
這種持久化方法需要將我們的惡意應(yīng)用程序上傳到目標(biāo)計(jì)算機(jī)。我傾向于在Mythic代理中使用上傳功能,將應(yīng)用程序保存到目標(biāo)上。
在修改plist之后,我們就可以立即重新加載Dock。但是,這會導(dǎo)致終端用戶的屏幕出現(xiàn)短暫的閃爍?;蛘撸覀円部梢缘却脩糁匦聠雍?,再讓虛假的應(yīng)用程序出現(xiàn)在Dock中,因?yàn)樾薷暮蟮膒list會在重新啟動后保持不變。
二、攻擊方式
2.1 部署
前面已經(jīng)說過,這種持久化方式需要將惡意應(yīng)用程序上傳到目標(biāo)。在此過程中,有多種方法可以繞過Gatekeeper保護(hù),允許我們將惡意應(yīng)用程序上傳到目標(biāo)。這些方法包括:
1、壓縮應(yīng)用程序包,在Mythic代理(Apfell或Poseidon)中使用上傳命令,然后在目標(biāo)計(jì)算機(jī)中解壓縮。
2、壓縮應(yīng)用程序包,在某個位置托管,使用curl下載到目標(biāo),然后在目標(biāo)計(jì)算機(jī)中解壓縮。
3、壓縮應(yīng)用程序包,進(jìn)行Base64編碼,在進(jìn)行Base64解碼后保存到目標(biāo)上,然后在目標(biāo)計(jì)算機(jī)中解壓縮。
作為概念驗(yàn)證(PoC),我僅僅是在“自動操作”(Automator)中創(chuàng)建了一個應(yīng)用程序。PoC應(yīng)用程序會打開Safari瀏覽器,這樣就避免了終端用戶沒有感知的情況。然后,它將運(yùn)行我們的Apfell Payload。
在PoC應(yīng)用程序中,JXA打開Safari并執(zhí)行Apfell Payload:

為了不讓終端用戶發(fā)覺,我將默認(rèn)的“自動操作”圖標(biāo)替換為Safari瀏覽器。當(dāng)然,如果使用Xcode,還可以創(chuàng)建更復(fù)雜的應(yīng)用程序。
帶有Safari瀏覽器圖標(biāo)的PoC應(yīng)用程序,我們將其命名為Safari:

接下來,我壓縮應(yīng)用程序包,并將其上傳到目標(biāo)。在解壓縮到/Users/Shared/之后,我們可以集中精力,在滿足前提條件的情況下調(diào)用持久化方法。
注意:由于plist的二進(jìn)制格式,自動實(shí)現(xiàn)要求將虛假的應(yīng)用程序命名為“Google Chrome”或“Safari”,并且位于/Users/Shared/中。我們可以修改Safari64和Chrome64變量,以更改此位置。
2.2 調(diào)用持久化
將腳本導(dǎo)入Mythic中的Apfell代理:

調(diào)用DockPersist函數(shù)。該函數(shù)接受三個參數(shù):應(yīng)用程序名稱(Safari或Google Chrome)、Bundle ID、是否立即重新加載Dock的選項(xiàng)。
注意:Bundle ID位于Info.plist中,可以使用以下命令來獲?。?/p>
- /usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' ~/FakeApp/Safari.app/Contents/Info.plist
在Apfell代理中調(diào)用DockPersist函數(shù),指定Safari、Bundle ID和是否重新加載Dock的選項(xiàng):

三、檢測方法
Crescendo是一個能在主機(jī)上迅速捕獲事件的絕佳工具。Crescendo可以作為macOS的實(shí)時事件查看器,它的一項(xiàng)出色功能就是利用了Apple的終端安全框架(ESF)。ESF可以監(jiān)視系統(tǒng)事件中是否存在潛在的惡意活動,實(shí)際上它是系統(tǒng)擴(kuò)展框架中的一個API。與Windows相比較,可以將其理解為macOS上一個功能有限的事件追蹤(ETW)。
通過Crescendo,我們可以輕松地查看由持久化執(zhí)行創(chuàng)建的文件和進(jìn)程事件。
對于不太了解ESF的讀者,大家需要了解下面的一些事件會同步到Crescendo:
- ES_EVENT_TYPE_AUTH_EXEC = process::exec
- ES_EVENT_TYPE_NOTIFY_EXIT = process::exit
- ES_EVENT_TYPE_NOTIFY_CREATE = file::create
- ES_EVENT_TYPE_NOTIFY_KEXTLOAD = process:kext::load
- ES_EVENT_TYPE_NOTIFY_MOUNT = file::mount
- ES_EVENT_TYPE_NOTIFY_UNLINK = file::unlink
- ES_EVENT_TYPE_NOTIFY_RENAME = file::rename
- ES_EVENT_TYPE_NOTIFY_UIPC_CONNECT = network::ipcconnect
- ES_EVENT_TYPE_NOTIFY_FORK = process::fork
盡管目前Crescendo不會捕獲ES_EVENT_TYPE_NOTIFY_MMAP、ES_EVENT_TYPE_NOTIFY_WRITE和ES_EVENT_TYPE_NOTIFY_EXEC,但它已經(jīng)捕獲到了這種持久化方式對應(yīng)的足夠多的事件。如果要應(yīng)對其他惡意活動,我強(qiáng)烈建議使用Xorrior的Appmon。
下面重點(diǎn)介紹了持久化方法的執(zhí)行,根據(jù)不同攻擊者使用的具體方法,實(shí)際的惡意應(yīng)用程序所對應(yīng)的事件可能會有所不同。
首先,plutil將Dock plist轉(zhuǎn)換為XML。XML格式更加易于操作。
Plutil將當(dāng)前com.apple.dock.plist轉(zhuǎn)換為XML格式:

隨后,記錄了temp9876文件創(chuàng)建和進(jìn)程創(chuàng)建。
DockPersist.js在/private/tmp/下創(chuàng)建一個隨機(jī)命名的文件。該腳本會修改plist的XML版本,并將其以隨機(jī)文件名保存。在這里,temp0wsn4p包含XML格式的惡意plist,因此我們用正確加載Dock所需的二進(jìn)制格式版本覆蓋了此文件。
Plutil將修改后的plist轉(zhuǎn)換回二進(jìn)制格式:

接下來,DockPersist.js在~/Library/Preferences/com.apple.dock.plist中刪除現(xiàn)有的plist。
刪除當(dāng)前的com.apple.dock.plist:

ESF捕獲到這一動作,并將新的惡意plist以二進(jìn)制格式保存到~/Library/Preferences/com.apple.dock.plist。
保存修改后的com.apple.dock.plist:

最后,由于我們在函數(shù)調(diào)用中制定了重新加載Dock,因此將調(diào)用killall。
重新加載Dock:

要建立檢測方式,這些事件就是我們的起點(diǎn)。這里的關(guān)鍵是檢測到了plutil和killall。此外,文件創(chuàng)建、刪除和修改事件也同樣可以用于檢測。在攻擊者進(jìn)行持久化之前,還可以針對將惡意應(yīng)用程序上傳到目標(biāo)計(jì)算機(jī)的這個動作來進(jìn)行檢測。
3.1 正常執(zhí)行
大家可能會有一個疑問,現(xiàn)在我們了解了ESF是如何捕獲已知惡意行為的,那么ESF會如何區(qū)分正常執(zhí)行呢?
在正常執(zhí)行的情況下,cfprefsd(Core Foundation Preferences Daemon)將會在com.apple.dock.plist上觸發(fā)file::rename事件(文件覆蓋)。當(dāng)用戶通過GUI手動對Dock進(jìn)行更改時,也會觸發(fā)這些事件。
com.apple.dock.plist的正常修改:

3.2 嘗試逃避檢測
攻擊者可以在另一臺主機(jī)上修改plist,然后將修改后的plist上傳到目標(biāo)計(jì)算機(jī)的對應(yīng)位置,這樣就能減少潛在指標(biāo)的數(shù)量。但是,這樣做仍然會觸發(fā)file::rename事件,而這一事件不會使用在正常執(zhí)行情況下的cfprefsd進(jìn)程。由此看來,識別非cfprefsd進(jìn)程對plist的修改動作,可能是檢測惡意行為的一個較好的判斷標(biāo)準(zhǔn)。
借助Apfell代理覆蓋替換com.apple.dock.plist:

3.3 可視化指標(biāo)
如果執(zhí)行PoC應(yīng)用程序,將會導(dǎo)致Dock中出現(xiàn)兩個Safari實(shí)例。
惡意Safari應(yīng)用程序與合法Safari應(yīng)用程序:

第一個Safari是惡意的應(yīng)用程序,位于plist的“persistent-apps”部分中,而第二個才是真實(shí)的Safari,它位于plist的“recent-apps”部分中。
四、其他指標(biāo)
在瀏覽ESF日志之后,我注意到了其中包含了寫入SQLite數(shù)據(jù)庫的一些內(nèi)容。如果攻擊者利用了osascript,則需要注意的一點(diǎn)是,osascript在~/Library/Caches/com.apple.osascript/Cache.db的位置有一個緩存數(shù)據(jù)庫。
注:上述緩存數(shù)據(jù)庫的創(chuàng)建僅適用于攻擊者使用osascript二進(jìn)制的情況下。除此之外,我還深入研究了如果使用OSAKit替代osascript的情況。為了進(jìn)行測試,我使用Sublime Text Plugin加載了JXA dylib。與osascript緩存數(shù)據(jù)庫的位置不同,在這種情況下的C2條目被記錄在~/Library/Caches/com.sublimetext.3/Cache.db之中。
使用SQLite對應(yīng)的數(shù)據(jù)庫瀏覽器查看該數(shù)據(jù)庫后,我注意到其中的cfurl_cache_response表中包含Mythic服務(wù)器的IP地址,以及Mythic中用于命令和控制(C2)通信的GET請求的簡短日志。這個緩存內(nèi)容為應(yīng)急排查提供了寶貴的來源。
通過數(shù)據(jù)庫瀏覽器,在SQLite數(shù)據(jù)庫中查看到C2通信的證據(jù):

使用sqlite3命令行工具也可以查看到這些條目:

五、總結(jié)
在本文中,我們展示了macOS中類似于Windows .LNK文件的持久化攻擊方法。更重要的是,我希望本文中分析的持久化指標(biāo)可以幫助正在開發(fā)檢測方式的研究人員。如果大家發(fā)現(xiàn)針對這一持久化方式還有其他檢測指標(biāo),歡迎與我探討。
六、參考資源
[1] https://posts.specterops.io/detection-engineering-using-apples-endpoint-security-framework-affdbcb18b02
[2] https://medium.com/red-teaming-with-a-blue-team-mentaility/taking-the-macos-endpoint-security-framework-for-a-quick-spin-802a462dba06
[3] https://attack.mitre.org/techniques/T1547/009/
[4] https://developer.apple.com/documentation/endpointsecurity?language=objc
[5] https://github.com/SuprHackerSteve/Crescendo
[6] https://bitbucket.org/xorrior/appmon/src/master/
[7] https://sqlitebrowser.org/
[8] https://eclecticlight.co/2017/07/06/sticky-preferences-why-trashing-or-editing-them-may-not-change-anything/
本文翻譯自:https://posts.specterops.io/are-you-docking-kidding-me-9aa79c24bdc1如若轉(zhuǎn)載,請注明原文地址:
【編輯推薦】