針對Linux系統(tǒng)全盤加密的啟動攻擊

攻擊
由于市面上沒有現(xiàn)成的工具能夠執(zhí)行這種攻擊,所以我們自己制作了工具,并把它命名為EvilAbigail。Evil maid攻擊可以針對任何操作系統(tǒng)。此次的研究我們針對的是使用LUKS全盤加密的Linux系統(tǒng)。
一般來說,當(dāng)Linux系統(tǒng)使用了全盤加密后,會由一小塊分區(qū)還是沒有加密,這個區(qū)域就是用來解密和引導(dǎo)加密磁盤的。這個分區(qū)會掛載在/boot,并且包含內(nèi)核和初始RAM磁盤(initrd)。雖然攻擊內(nèi)核或者bootloader也是可行的,但是我們還是針對initrd進(jìn)行了攻擊。
initrd是指一個臨時文件系統(tǒng),它在啟動階段被Linux內(nèi)核調(diào)用。initrd主要用于當(dāng)root文件系統(tǒng)被掛載之前,進(jìn)行準(zhǔn)備工作。initrd 中包含了是解密和掛載root文件系統(tǒng)所需要的目錄和可執(zhí)行程序的最小集合。一旦initrd任務(wù)完成,它就會執(zhí)行pivot_root,從而將initrd根文件系統(tǒng)卸載掉,并掛載真正的根文件系統(tǒng)。
一般來說,initrd是一個通過gzip壓縮的cpio鏡像。我們測試的基于Debian的操作系統(tǒng)是這樣,但基于RedHat的操作系統(tǒng) (Fedora, RHEL, CentOS)現(xiàn)在使用的是dracut,包含一個未壓縮的cpio鏡像?;贒ebian的initrds 會用ash shell腳本執(zhí)行啟動,而dracut則會用systemd和它所關(guān)聯(lián)的配置方法。
為了執(zhí)行我們的攻擊,我們選擇使用一個基于LD_PRELOAD的bootkit,但是其實(shí)也可以注入惡意的內(nèi)核或可執(zhí)行文件中。我們使用LD_PRELOAD的主要目標(biāo)是對剛剛解密完成的root文件系統(tǒng)中的第一個可執(zhí)行文件注入一個共享對象。第一個可執(zhí)行文件通常是/sbin/init,PID一般會是1。進(jìn)行攻擊最簡單的方法就是修改init腳本,導(dǎo)出這個環(huán)境變量,這樣執(zhí)行pivot_root的時候環(huán)境變量就設(shè)置好了。因?yàn)楫?dāng)文件系統(tǒng)更改的時候還得在合適的時候(解密之后)把共享對象復(fù)制到新系統(tǒng)中。把以下這兩行放入initrd的init腳本中,插在切換文件系統(tǒng)之前:
cp /hack.so /${rootmnt}/hack.so
export LD_PRELOAD=/hack.so
之所以這樣可行是因?yàn)檎嬲膔oot文件系統(tǒng)是在臨時root文件系統(tǒng)下解密掛載的,這先于pivot,并且rootmnt變量是用掛載點(diǎn)位置填充的。但是,在這之前需要把目標(biāo)文件系統(tǒng)重新掛載成讀寫,因?yàn)槟J(rèn)是只讀的。在我們的例子中我們對init腳本進(jìn)行了修改,修改了腳本分析內(nèi)核命令行的地方,因此無論提供的參數(shù)是什么,root文件系統(tǒng)都是讀寫方式掛載。另一種方法是在注入的命令中添加mount -o remount,rw /${rootmnt}。
不過基于dracut的initrds中不存在注入點(diǎn),因?yàn)閕nit的可執(zhí)行文件是個二進(jìn)制文件而非shell腳本。這就給我們帶來了三個問題,只有克服了這三個問題我們才能夠注入到pid 1進(jìn)程中。
三個問題
第一個問題是有關(guān)復(fù)制我們的二進(jìn)制文件到解密的root文件系統(tǒng)中。這個問題是三個問題中最好解決的一個。我們可以加兩個ExecPre指令到負(fù)責(zé)pivote文件系統(tǒng)的systemd服務(wù)文件中。這基本就相當(dāng)于前面提到的插入腳本的方法。第一個命令會以讀寫方式重新掛載root文件系統(tǒng),第二個執(zhí)行復(fù)制操作。
第二個問題有關(guān)LD_PRELOAD。因?yàn)槲覀儾皇窃谛薷膕hell腳本,我們不能把環(huán)境變量傳遞給這個進(jìn)程(因?yàn)樗怯蓛?nèi)核調(diào)用的),因此加載我們的共享對象就有點(diǎn)棘手了。最簡單的辦法就是,先把init二進(jìn)制文件移動到另一個位置,然后在它原來的位置插入我們自己的shell腳本,最后再執(zhí)行原來的二進(jìn)制文件。我們只需要兩行代碼,第一行導(dǎo)出LD_PRELOAD,第二行執(zhí)行原來的systemd二進(jìn)制文件。請注意,這樣注入的是initrd中的pid 1進(jìn)程,而不是最終root文件系統(tǒng)的pid 1。
第三個問題就是,在調(diào)用switch-root命令之前,systemd會用clearenv()函數(shù)清除所有環(huán)境變量。因?yàn)檫@個函數(shù)是標(biāo)準(zhǔn)庫的一部分,我們就可以重寫這個函數(shù),讓被注入的進(jìn)程會調(diào)用我們的函數(shù)而不是原來的函數(shù)。我們不關(guān)心真正清除環(huán)境變量,我們寫的clearenv()函數(shù)會清除所有環(huán)境變量,然后把我們的LD_PRELOAD變量注入到環(huán)境中。由于clearenv()只會被調(diào)用一次,我們的修改不會導(dǎo)致任何副作用。
解決了以上這三個問題之后,我們的共享對新就會被復(fù)制到加密的root文件系統(tǒng)中,我們的LD_PRELOAD會被注入到目標(biāo)文件系統(tǒng)的pid 1進(jìn)程中。接下來我們就可以獲取用于解密的用戶密碼。
對于Debian的initrds,可執(zhí)行文件會要求用戶輸入密碼,然后解密、掛載root文件系統(tǒng)。我們可以把我們的腳本注入到pipeline進(jìn)程中從而獲取密碼。
至于systemd,它會通過Unix domain sockets使用一種更復(fù)雜的進(jìn)程間通信。我們選擇攻擊文件系統(tǒng)的掛載,而非這個進(jìn)程。這又是一個庫函數(shù),它在動態(tài)加載庫中,從systemd里調(diào)用,所以我們可以hook這個函數(shù)。解密硬盤的函數(shù)叫做crypt_activate_by_passphrase。這個函數(shù)會把密碼作為char數(shù)組。通過hook這個函數(shù),我們可以獲取到密碼。我們要包裹這個原來的函數(shù),所以我們用dlsym打開真正的函數(shù),并且調(diào)用它。不過在此之前我們會保存密碼以便以后取回。
為了“保存”密碼,我們簡單地把密碼加到我們之后要復(fù)制到root文件系統(tǒng)的共享對象中。之所以選擇這種方法是因?yàn)槲覀円呀?jīng)知道這個文件存在,并且會被復(fù)制過去。采用這種方法還會減少我們接觸到的磁盤文件的數(shù)量。為了獲取密碼,我們之后會讀取我們自己文件末尾(通過LD_PRELOAD變量定位),然后把它設(shè)置為我們的反彈shell中PASSWORD環(huán)境變量的值,因此(以meterpreter為例)通過‘getenv PASSWORD’命令可以獲取用于解密磁盤的密碼。由于我們所有的目標(biāo)主機(jī)都默認(rèn)安裝了python,所以我們就使用了python meterpreter反彈shell。
解決方案
解決這種問題有很多方法。但是即使使用了這些解決方法,如果攻擊者能夠物理接觸計(jì)算機(jī),并且有足夠的時間重刷BIOS/UEFI,那也是防不住的。
第一種方法是把bootloader、內(nèi)核和initrd放在外置的U盤上,然后從U盤上啟動從而替代/boot分區(qū)。但對用戶來說這個方法很糟糕,因?yàn)樗麄冸x開筆記本的時候要記得拔掉U盤,如果沒有卸載的話還要安全卸載/boot分區(qū)。更新的時候也很麻煩,要插上U盤才能更新initrd/內(nèi)核。
另一種方案則是徹底關(guān)閉從外置媒體啟動系統(tǒng)。這樣就不存在自動化攻擊的可能性了,但是某些情況下,如對于包含shell的Debian initrds,還是可以從initrd人工掛載和修改initrd的。這可以通過自動鍵盤式設(shè)備完成,這樣就繞過了無法通過外置媒體啟動系統(tǒng)的限制。
另外,還可以開啟BIOS啟動密碼,這樣沒有密碼的人就無法啟動計(jì)算機(jī)了。
不過如果攻擊者有足夠的時間把硬盤拆下,然后用他們自己的筆記本啟動硬盤的話,后兩種方案也不管用了。
最后,最安全的方案就是將SecureBoot拓展到initrd。SecureBoot可以驗(yàn)證bootloader和內(nèi)核,如果能夠驗(yàn)證經(jīng)過簽名的initrd的話,要不留痕跡地在/boot分區(qū)修改任何東西都會很困難。但是如果攻擊者可以通過刷BIOS/UEFI關(guān)閉secureboot的話,這種方案也沒用了。
防止這類攻擊最好的方法就是不要讓你的設(shè)備落入攻擊者們的手中,我們的PoC攻擊可以在2分鐘內(nèi)攻陷所有的目標(biāo)主機(jī),但在現(xiàn)實(shí)世界中,攻擊者也可以做出攻擊特定目標(biāo)的payload,這樣的payload只用幾秒就可以攻擊設(shè)備。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
輕松實(shí)現(xiàn)Linux數(shù)據(jù)加密的三種方法
數(shù)據(jù)加密是一種非??煽康陌踩胧?防范措施,擁有個人數(shù)據(jù)或重要數(shù)據(jù)的人都應(yīng)該進(jìn)行加密。本文介紹了可以替我們加密數(shù)據(jù)的最易于使用的幾款工具2015-12-14在Linux 中產(chǎn)生和加密解密隨機(jī)密碼的教程
這篇文章主要介紹了 在Linux 中產(chǎn)生和加密解密隨機(jī)密碼的教程,都是利用Linux自帶的工具在命令行下進(jìn)行使用,需要的朋友可以參考下2015-05-27- 網(wǎng)絡(luò)越來越不安全,很多人會選擇加密以防泄露,那么電子郵件要如何加密呢?下面就與大家分享下Linux系統(tǒng)下加密電子郵件的方法,有加密意識的朋友可以看看2014-12-09
- 如果你一直在考慮如何加密電子郵件,那么在眾多的郵件服務(wù)和郵件客戶端中挑來挑去一定是件頭痛的事情.可以考慮兩種加密方法:SSL或TLS加密會保護(hù)發(fā)送到郵件服務(wù)器的登錄名2014-10-31
- 當(dāng)我們用紅帽Kickstart腳本或useradd或其他方式寫東西的時候,經(jīng)常會需要用到crypt命令加密生成的密碼格式。那么,有沒有其他方式可以生成這種格式的密碼?事實(shí)上,方法有很2011-11-05
- 我們時不時地能看到這樣的頭條新聞:“某公司損失了3千萬客戶的個人社會安全碼,以及其他個人敏感信息還有財務(wù)數(shù)據(jù)!我們不該憤怒嗎?”通常都是“承包商&rd2008-10-08
- 1、用grub-md5-crypt成生GRUB的md5密碼; 通過grub-md5-crypt對GRUB的密碼進(jìn)行加密碼運(yùn)算,比如我們想設(shè)置grub的密碼是123456,所以我們先要用md5進(jìn)行對123456這個密2008-09-08