利用第三方應(yīng)用的各類代碼注入技術(shù)竊取鑰匙串
在macOS上存儲(chǔ)密鑰是一個(gè)巨大的挑戰(zhàn),可以通過(guò)多種不安全的方式來(lái)完成。我在漏洞賞金評(píng)估期間測(cè)試了許多Mac應(yīng)用程序,并觀察到開(kāi)發(fā)人員傾向于將密鑰放在偏好甚至隱藏的平面文件中。這種方法的問(wèn)題在于,以標(biāo)準(zhǔn)權(quán)限運(yùn)行的所有非沙盒應(yīng)用程序都可以訪問(wèn)密鑰數(shù)據(jù)。平面文件(Flat-File),F(xiàn)lat File是一種包含沒(méi)有相對(duì)關(guān)系結(jié)構(gòu)的記錄的文件。這個(gè)類型通常用來(lái)描述文字處理、其他結(jié)構(gòu)字符或標(biāo)記被移除了的文本。
在使用上,有一些模糊點(diǎn),如像換行標(biāo)記是否可以包含于“Flat File(flat file)”中。在任何事件中,許多用戶把保存成“純文本(text only)”類型的Microsoft Word文檔叫做“Flat File(flat file)”。最終文件包含記錄(一定長(zhǎng)度的文本的行數(shù))但沒(méi)有信息,例如,用多長(zhǎng)的行來(lái)定義標(biāo)題或者一個(gè)程序用多大的長(zhǎng)度來(lái)用一個(gè)內(nèi)容表對(duì)該文檔進(jìn)行格式化。
例如,macOS上的Signal在〜/ Library / Application Support / Signal / config.json中存儲(chǔ)了用于加密所有消息數(shù)據(jù)庫(kù)的密鑰。
macOS鑰匙串
根據(jù)蘋(píng)果的說(shuō)法,鑰匙串是存儲(chǔ)例如密碼和加密密鑰這樣的小秘鑰的最好地方,鑰匙串是一種非常強(qiáng)大的機(jī)制,允許開(kāi)發(fā)人員定義訪問(wèn)控制列表(ACL)來(lái)限制對(duì)條目的訪問(wèn)。應(yīng)用程序可以通過(guò)密鑰組權(quán)限進(jìn)行簽名,以便訪問(wèn)其他應(yīng)用程序之間共享的秘鑰。以下Objective-C代碼將在鑰匙串中保存密鑰值:
并且在執(zhí)行后,你應(yīng)該看到條目已成功被添加:
第一種竊取技術(shù)
第一種技術(shù)是驗(yàn)證應(yīng)用程序是否已使用“Hardened Runtime”或“Library Validation”標(biāo)志進(jìn)行了簽名,鑰匙串不能檢測(cè)到代碼注入。因此,只需使用以下命令:
如果標(biāo)記為0x0,并且沒(méi)有__RESTRICT Mach-O段(這個(gè)段非常罕見(jiàn)),則只需將惡意的dylib注入到應(yīng)用程序的主要可執(zhí)行文件中。創(chuàng)建具有以下內(nèi)容的exploit.m文件:
編譯:
并注入:
第二種竊取技術(shù)
如果可執(zhí)行文件已使用Hardened Runtime簽名怎么辦?這個(gè)繞過(guò)技術(shù)類似于我在XPC開(kāi)發(fā)系列中向你展示的內(nèi)容。抓取已分析的二進(jìn)制文件的舊版本,該版本在沒(méi)有強(qiáng)化運(yùn)行時(shí)的情況下簽名,并將dylib注入其中。鑰匙串不會(huì)驗(yàn)證二進(jìn)制文件的版本,而是會(huì)給你展示秘鑰。
針對(duì)開(kāi)發(fā)人員的建議修復(fù)程序,創(chuàng)建“鑰匙串訪問(wèn)組”并將秘鑰移到那里。由于二進(jìn)制文件的舊版本無(wú)法使用該鑰匙串組權(quán)限進(jìn)行簽名,因此無(wú)法獲得該秘鑰,詳情請(qǐng)點(diǎn)此。
第三種竊取技術(shù)
切記如果設(shè)置了“Hardened Runtime”,則com.apple.security.cs.disable-library-validation將允許你注入惡意動(dòng)態(tài)庫(kù)。
第四種竊取技術(shù)
正如Jeff Johnson在他的文章中所證明的那樣,TCC只是從表面上檢查應(yīng)用程序的代碼簽名。鑰匙串中也存在相同的問(wèn)題,即使整個(gè)捆綁包的簽名無(wú)效,鑰匙串也只會(huì)驗(yàn)證主要的可執(zhí)行文件是否未被篡改。讓我們以設(shè)備上安裝的Electron應(yīng)用程序(Microsoft Teams,Signal,Visual Studio Code,Slack,Discord等)之一為例,事實(shí)證明Electron應(yīng)用程序無(wú)法安全地存儲(chǔ)你的秘鑰。Electron是一個(gè)創(chuàng)建原生應(yīng)用程序的框架,基于Node.js和Chromium實(shí)現(xiàn)了通過(guò)JavaScript, HTML 和 CSS 等 Web 技術(shù)構(gòu)建跨平臺(tái)應(yīng)用程序的能力。
其中,Electron還封裝了一些功能,包括自動(dòng)更新、原生的菜單和通知、崩潰報(bào)告、調(diào)試和性能分析等。
即使你使用Hardened Runtime簽署了Electron,惡意應(yīng)用程序也可能會(huì)更改包含實(shí)際代碼的JavaScript文件。讓我們看一下Github Desktop.app,它將用戶的會(huì)話秘鑰存儲(chǔ)在鑰匙串中:
并已有效簽名:
接下來(lái),更改一個(gè)JS文件并驗(yàn)證簽名:
可以看到簽名被破壞了,但是Github會(huì)正常啟動(dòng)并加載保存在鑰匙串中的密鑰:
為了防止修改,Electron實(shí)現(xiàn)了一種稱為asar-integrity的機(jī)制。它計(jì)算一個(gè)SHA512哈希值并將其存儲(chǔ)在Info.plist文件中,問(wèn)題在于它不會(huì)停止注射。如果主要的可執(zhí)行文件尚未使用Hardened Runtime或Kill標(biāo)志簽名,并且不包含受限制的權(quán)限,則只需修改asar文件,計(jì)算新的校驗(yàn)和并更新Info.plist文件即可。如果設(shè)置了這些標(biāo)志或權(quán)限,則始終可以使用ELECTRON_RUN_AS_NODE變量,并再次在主要的可執(zhí)行上下文中執(zhí)行代碼。因此,它可以竊取鑰匙串條目。
總結(jié)
鑰匙串中的安全密鑰存儲(chǔ)確實(shí)很難實(shí)現(xiàn),因?yàn)閷?duì)請(qǐng)求的可執(zhí)行文件的代碼簽名檢查只是一些表面的功夫,因此有多種方法可以繞過(guò)訪問(wèn)控制機(jī)制。
最大的問(wèn)題是在Electron應(yīng)用程序中,這些應(yīng)用程序無(wú)法將密鑰安全地存儲(chǔ)在鑰匙串中。切記,任何將實(shí)際代碼存儲(chǔ)在主要的可執(zhí)行文件之外的框架都可能被誘騙加載惡意代碼。
本文翻譯自:https://wojciechregula.blog/post/stealing-macos-apps-keychain-entries/