Linux Security Module逆向分析实战
Linux Security Module逆向分析實戰
本文記錄了對某發行版Linux中一個安全模塊(LSM)的逆向過程,該LSM對系統中待運行的程序進行安全校驗,數據流穿越內核態與用戶態,涉及系統內核及系統服務。此LSM對系統安全性的增強效果明顯,其設計思路值得防守方研究學習,可于個人終端或服務器安全防護中應用。特此對逆向內容記錄,希望能為讀者在終端防護方面拓寬思路,同時歡迎感興趣的師傅們交流學習。
一. LSM框架簡介
Linux安全模塊(Linux Security Module,LSM)框架是Linux操作系統內核提供的一種安全機制,它通過內核擴展實現hook函數以完成多種安全檢查,通常用于強制訪問控制(Mandatory Access Control)。雖然被稱作“模塊”,但不同于LKM,這些擴展并不是可加載的內核模塊,而是和內核代碼一起編譯在內核文件(vmlinuz)中。可以通過如下命令查看本機啟用的LSM,cat /sys/kernel/security/lsm。常見的LSM包括SELinux、Yama等。
LSM框架的hook點設置于內核訪問關鍵對象前,通過調用LSM中實現的hook函數,判斷是否可以進行訪問。如果有多個LSM,則會根據初始化的順序依次判斷,都允許才能進行訪問。上述關鍵對象包括程序、進程、套接字、文件系統等,可在/usr/src/linux-headers-YOURSYSTEMVERSION/include/linux/lsm_hooks.h中查看詳細的hook說明。
這里以程序啟動過程為例,簡單說明LSM工作的機制。當通過execve系統調用執行一個新程序時,內核最終會執行到__do_execve_file函數完成相關工作,在這里會調用prepare_binprm函數填充struct linux_binprm,填充前會調用security_bprm_set_creds進行安全檢查。security_bprm_set_creds就是LSM框架提供的hook,它會依次調用注冊在這個鉤子上的回調函數,完成安全檢查。此流程上相關代碼以及此鉤子的說明如下。
LSM開發時,通過如下函數定義安全模塊的hook函數,逆向時通過此函數可快速定位具體的LSM以及相關回調函數。
二. 安全模塊逆向分析
2.1 分析準備
本次分析的對象為某發行版Linux,此系統提供了可執行文件的簽名校驗功能,僅有簽名的程序可以被執行,本次逆向的目標就是試圖還原校驗功能的框架和邏輯。由于此安全檢查的存在,提權、后門等程序因為此機制的存在而無法直接運行,從某種程度提高了操作系統的安全性。編譯一個hello world程序,運行,會提示無法通過系統安全校驗目前不能運行。strace跟一下,看到在execve時就被干掉了(如下圖),可以肯定是在內核中完成這個動作的,大概率是通過內核擴展實現。
下面嘗試定位此內核擴展。lsmod看一眼,沒有發現明顯相關的。查看此系統的所有LSM,有一個名為elfverify的模塊,通過此命名可以推斷,就是此模塊完成了程序的校驗功能。
由于LSM是被編譯在內核中的,因此接下來需要獲取到此系統的內核文件。系統的內核文件通常可以在/boot目錄中找到,其中vmlinuz的文件是壓縮后的內核,可以通過extract-vmlinux工具提取未壓縮的內核文件vmlinux進行分析。然而提取后的文件是沒有符號的,符號信息存儲在同目錄下System.map文件中。這里推薦使用vmlinux-to-elf這個工具完成提取與符號修復工作,通過此工具可輸出一個帶符號的ELF文件,方便逆向分析。
2.2 LSM分析
反編譯查看恢復后的內核,在elfverify的初始化函數elfverify_init()中,security_add_hooks()的第二個參數count為5,即此LSM一共注冊了5個hook函數;跟蹤一下第一個參數security_hook_list,可得到所有實現的回調函數,總結如下。
可以看出此LSM還對套接字、設備掛載進行了安全校驗,這里專注于程序運行的校驗,鎖定hook_bprm_set_creds進行進一步分析。
跟進hook_bprm_set_creds,該函數首先對一些參數進行檢查,接著判斷是否開啟了開發者模式(判斷依據是某個文件的內容),如果符合條件則放行(返回0),否則調用access_verify進行進一步判斷。此函數的參數類型是struct linux_binprm, 源碼中此結構體被標記為__randomize_layout,這是Linux內核中的一項防御機制,有此標記的結構體其中的元素將作亂序排列,從而攻擊者難以找到偏移具體對應的元素。因此通過靜態分析,也暫時無法確定傳遞給access_verify的參數。
在access_verify中,會將當前進程通過add_wait_queue掛起等待,并將90-pid-UNKNOWN信息寫入某個設備中,這里的90應該是LSM開發者自定義的一個“魔數”(socket校驗中是91),而第三段的內容由于結構體的隨機化也暫時無法確定(之后分析會知道其實是程序路徑)。之后再從此設備中讀取信息,根據內容選擇是否繼續執行,并從隊列中移除進程。
LSM中關于elf校驗的流程到這個函數基本就結束了,并不包含具體的校驗邏輯,只是將待校驗的進程信息寫入某個設備并等待結果,可見校驗應該是在另一處完成。經過跟蹤分析,此LSM注冊了一個雜項設備(在register_elf_verifier_dev()中),名為elf_verifier。下一步找到了誰從這個設備中讀取信息,大概率就能定位到完成校驗的具體代碼。
然而,在內核中并沒有找到相關的代碼,下一步得去用戶態的程序找找。
2.3 安全校驗邏輯分析
查看一下系統進程,發現一條程序名為*-elf-verify,其ppid為1,看了下是系統服務,推斷這就是處理雜項設備中數據的程序了。為驗證推斷,將此服務停止,運行一個自己編譯的程序,待運行的進程“僵死”,推斷應該是LSM將進程送入等待隊列后,沒有從雜項設備中讀到校驗結果,就造成了一直掛起的局面。這也確認了正是這個程序處理設備數據并給與返回結果,校驗邏輯應當就在其中。
對此系統服務程序進行分析與調試,在進行ELF文件安全校驗時,它會循環的從/dev/elf_verifier這個設備中讀取內容,讀取到的內容包括PID和完整的程序路徑,并依據此信息進行校驗,其主要檢查如下兩點:
判斷此路徑的程序是否在白名單或黑名單中
在ELF文件頭的特殊節中提取簽名(PKCS7),然后進行驗證(證書在系統某路徑中)
上述的黑白名單位于系統/usr目錄下,僅root用戶可編輯。而ELF文件頭中的特殊節在其他普通的ELF文件中不會出現,應當是在對ELF文件進行簽名時加上的,而將簽名信息添加到文件頭中又不會對程序的正常運行造成影響。如果能夠順利讀取到簽名信息,則調用openssl的相關函數進行校驗。校驗完成后,將檢驗結果寫入/dev/elf_verifier,通知內核進行后續動作;同時如果校驗不通過,會通過dbus通知GUI彈出提示告知用戶。
至此,一次校驗完成,整個簽名校驗功能的脈絡基本摸清了。在其中還有一些細節檢查,例如文件格式、ELF文件頭等等,就不一一展開介紹了。
三. 總結
該系統的可執行程序簽名校驗功能,通過安全模塊(LSM)elfverify、系統服務聯合完成,二者通過雜項設備/dev/elf_verifier傳遞數據,完成了用戶態和內核態的交互。在內核中,通過實現LSM的security_bprm_set_creds鉤子在程序運行前獲取到待運行程序的完整路徑,將進程暫時掛起,同時將信息寫入設備中;用戶態程序從設備中讀取到信息后,判斷此路徑程序是否在黑白名單、程序是否是經過簽名的ELF程序,并將判斷結果寫入設備;內核LSM根據返回的結果確定是否允許執行。
整個過程涉及LSM、設備、ELF文件格式、簽名校驗等知識,有深有淺,本文記錄的比較簡單,歡迎感興趣的師傅深入交流。同時,該方式利用LSM框架提供的鉤子,對某些操作進行安全校驗,同時將復雜的校驗邏輯在用戶態完成,通過設備完成數據傳遞,此類模式在終端安全防護上亦可借鑒。
最后
關注私我,獲取【網絡安全學習攻略】
總結
以上是生活随笔為你收集整理的Linux Security Module逆向分析实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【CTF大赛】100步getshell之
- 下一篇: 【网络安全】如何使用keimpx检测网络