路人甲 · 2015/01/23 9:52php
某Linux服務器發現異常現象以下圖,肯定被植入Rootkit,但運維人員使用常規Rootkit檢測方法無效,對此狀況咱們還能夠作什麼?html
圖1 被植入Rootkit的Linux服務器linux
全部暗鏈的html文件ls均看不到。數組
使用ls -al 絕對路徑,能看到,但沒法刪除。bash
這些暗鏈的uid和gid都很奇特 分別爲 2511744398:4043361279 。服務器
對任意文件執行chown 2511744398:4043361279 其表現會和暗鏈文件相同。網絡
將硬盤nfs掛載到正常系統上,現象無任何變化。數據結構
通常來講,Rootkit檢測方式有如下幾種:app
1. 可信任Shell——使用靜態編譯的二進制文件:lsof、stat、strace、last、……
2. 檢測工具和腳本:rkhunter, chkrootkit, OSSEC
3. LiveCD——DEFT、Second Look、 Helix
4. 動態分析和調試:使用gdb根據System.map和vmlinuz image分析/proc/kcore
5. 直接調試裸設備:debugFS
複製代碼
在分析這幾種檢測方法的優劣以前,咱們先經過圖2瞭解一下Linux Rootkit的通常實現原理運維
圖2 Linux中系統命令執行的通常流程
在Ring3層(用戶空間)工做的系統命令/應用程序實現某些基礎功能時會調用系統.so文件注1。而這些.so文件實現的基本功能,如文件讀寫則是經過讀取Ring0層(內核空間)的Syscall Table注2(系統調用表)中相應Syscall(系統調用)做用到硬件,最終完成文件讀寫的。
那麼若是中了Rootkit,這個流程會發生什麼變化呢?下面經過圖3來了解一下。
圖3 Rootkit的通常執行流程
Rootkit篡改了Syscall Table中Syscall的內存地址,致使程序讀取修改過的Syscall地址而執行了惡意的函數從而實現其特殊功能和目的。
上圖僅僅是列舉了一種典型的Rootkit工做流程,經過修改程序讀取Syscall的不一樣環節能夠產生不一樣類型的Rootkit,咱們簡單羅列一下。
Rootkit部分實現方式:
1. 攔截中斷-重定向sys_call_table,修改IDT
2. 劫持系統調用-修改sys_call_table
3. inline hook-修改sys_call,插入jmp指令
複製代碼
這部分不是本文的重點,再也不贅述。瞭解了Rootkit實現原理,咱們再回過來對比一下常規Rootkit檢測方式的優劣。
對於使用靜態編譯的二進制文件的檢測方式,若是Rootkit修改了Syscall,那麼這種方法產生的輸出也是不可靠的,咱們沒法看到任何被Rootkit隱藏的東西。
那麼若是使用Rootkit檢測工具呢,咱們簡單分析一下rkhunter的檢測原理。
在rkhunter腳本文件中,scanrootkit函數部分代碼以下:
圖4 rkhunter中的scanrootkit函數
注:其安裝腳本中定義瞭如下兩個變量
#!bash
RKHTMPVAR="${RKHINST_SIG_DIR}"
RKHINST_SIG_DIR="${RKHINST_DB_DIR}/signatures"
複製代碼
圖5 Signatures目錄中的文件列表——Rootkit簽名列表
從上面這段代碼咱們能夠看出rkhunter掃描Rootkit調用了3個重要的變量:SCAN_FILES, SCAN_DIRS,SCAN_KSYMS,用於每種Rootkit的檢查。
下面的四幅圖分別是Adore和KBeast兩個Rootkit檢測的具體代碼。
圖6 rkhunter中經典Rootkit Adore的檢測流程
圖7 rkhunter中檢測Adore的文件和目錄的清單
圖8 rkhunter中Rootkit KBeast的檢測流程
圖9 rkhunter中檢測KBeast的文件和目錄的清單
根據以上分析,咱們能夠看出rkhunter僅僅是檢查已知Rootkit組件默認安裝路徑上是否存在相應文件,並比對文件簽名(signature)。這種檢測方式顯然過於粗糙,對修改過的/新的Rootkit基本無能爲力。
而另外一款流行的Rootkit檢測工具chkrootkit,其LKM Rootkit檢測模塊源文件爲chkproc.c,最後更新日期爲2006.1.11日。檢測原理與rkhunter大體類似,也主要基於簽名檢測並將ps命令的輸出同/proc目錄做比對。在它的FAQ中Q2的回答也印證了咱們的結論。
圖10 chkrootkit的FAQ之Q2
分析了常見的Rootkit檢測工具的實現原理,咱們再看一下使用LiveCD檢測這種方式有哪些侷限性。
使用LiveCD意味着使用一純淨的光盤操做系統掛載原有存儲對可疑文件作靜態分析/逆向,以便了解Rootkit執行邏輯,依賴的so/ko文件有哪些,加載的配置文件是什麼。那麼,若是事先沒有找到一些Rootkit的相關文件,直接對整個文件系統作逐一排查,無疑是一個繁冗的過程。並且,這種方式的使用前提是應急響應人員必須能物理接觸服務器,這對託管在機房的環境很不方便。實際上,使用LiveCD在Rootkit清除或司法取證環節上更爲常見,而不是其前置環節。
根據以上分析,咱們簡單總結一下Rootkit檢測方式的效果,見下表.
Rootkit檢測方式對比
檢測方式 | 侷限/缺陷 |
---|---|
使用靜態編譯的二進制文件 | 工做在用戶空間,對Ring0層的Rootkit無效。 |
工具rkhunter,chkrootkit | 掃描已知Rootkit特徵,比對文件指紋,檢查/proc/modules,效果極爲有限。 |
LiveCD:DEFT | Rootkit活動進程和網絡鏈接等沒法看到,只能靜態分析。 |
GDB動態分析調試 | 調試分析/proc/kcore,門檻略高,較複雜。不適合應急響應。 |
DebugFS裸設備直接讀寫 | 不依賴內核模塊,繁瑣複雜,僅適合實驗室分析。 |
既然常規的Rootkit檢測方法有這樣那樣的缺陷,那有沒有更好的檢測方式呢?
下面咱們詳細介紹一下基於內存分析Rootkit檢測方法。
Rootkit難以被檢測,主要是由於其高度的隱匿特性,通常表如今進程、端口、內核模塊和文件等方面的隱藏。但不管怎樣隱藏,內存中必定有這些方面的蛛絲馬跡,若是咱們能正常dump物理內存,並經過debug symbols.和kernel`s data structure來解析內存文件,那麼就能夠對系統當時的活動狀態有一個真實的「描繪」,再將其和直接在系統執行命令輸出的「虛假」結果作對比,找出可疑的方面。下面簡述一下部分原理。
在Linux系統中查看進程通常執行的是ps –aux命令,其實質是經過讀取/proc/pid/來獲取進程信息的。而在內核的task_struct注3(進程結構體)中,也一樣包含進程pid、 建立時間、映像路徑等信息。也就是說每一個進程的相關信息均可以經過其對應task_struct內存地址獲取。並且,每一個task_struct經過next_task和prev_task串起成爲一個雙向鏈表,可經過for_each_task宏來遍歷進程。基於這個原理咱們能夠先找到PID爲0的init_task symobol(祖先進程)的內存地址,再進行遍歷就能模擬出ps的效果。部分細節可參考下圖。
圖11 內核中的task_struct
此外,Linux內核中有一個東西叫PID Hash Chain,如圖12所示,它是一個指針數組,每一個元素指向一組pid的task_struct鏈表中的元素 ,可以讓內核快速的根據pid找到對應的進程。因此分析pid_hash也能用來檢測隱藏進程和獲取相應進程信息,而且效率更高。
圖12 內核中的PID Hash Chain
在task_struct中,mm_struct注4描述了一個進程的整個虛擬地址空間,進程映射主要存儲在一個vm_area_struct的結構變量mm_rb注5和mmap 中,大體結構以下圖所示
圖13 mm_struct(內存描述符)的結構
每個vm_area_struct節點詳細記錄了VMA(virtual memory area)的相關屬性,好比vm_start(起始地址)、vm_end(結束地址)、vm_flags(訪問權限)以及對應的vm_file(映射文件)。從內存中咱們獲得信息就至關於得到了/proc/
Linux中的lsof(List Open Files)實質是讀取/proc/pid/文件夾中的信息。而這些信息經過task_struct也能獲取。
圖14 內核中的task_struct細節
task_struct的structure(數據結構)中files指向files_struct(文件結構體),用於表示當前進程打開的文件表。其structure中有一個fd_array(文件描述符數組),數組中的每一個元素fd(File Descriptor文件描述符),都表明一個進程打開的文件。而每一個File Descriptor的structure中又包含了目錄項dentry,文件操做f_ops等等。這些足以讓咱們找到每一個進程打開的文件。
另,當某個文件的f_op structure 成員是socket_file_ops 或者其dentry.d_op 爲sockfs_dentry_operations時,則能夠將其轉爲爲相應的inet_sock structure,最終獲得相應的網絡信息。
後滲透測試階段,攻擊者常使用history –c命令來清空未保存進.bash_history文件的命令歷史。而在Rootkit中,經過配置HISTSIZE = 0 或將HISTFILE = /dev/null也是一種常見的隱藏命令歷史的方法。對於後者,因爲bash進程的history也記錄在相應的MMAP中(其對應的宏定義爲 HISTORY_USE_MMAP注6),經過history_list()函數相應的mmap數據也能夠還原其歷史記錄。
圖15 bash 4.0源碼histfile.c文件中history_do_write函數功能圖示.
經過遍歷module list上全部的struct module來檢查Rootkit是一種代替lsmod命令的的方法。可是若是Rootkit把本身的LKM從module list摘除,但仍加載在內存中,這種方法就不起做用了。
圖16 內核中Kernel Module List
不過,Rootkit很難在/sys/module/目錄中隱藏,因此咱們仍可經過遍歷Sysfs文件系統來檢查隱藏的內核模塊。
在2.6.29內核的之前版本,Rootkit能夠將用戶態的進程經過設置其effective user ID和effective group ID爲0(root)進行特權提高。而在後面的版本中,kernel引入了'cred' structure。爲此,Rootkit與時俱進,經過設置同某個root權限進程同樣的'cred' structure 來應對這種改進。因此經過檢查全部進程的'cred' structure 能更好的發現活動的Rootkit。
限於篇幅,本文再也不介紹更多的原理和細節,簡單總結一下這種方法的的大體流程。
1 製做目標Linux服務器的profile
2 Dump完整的物理內存
3 使用profile解析內存映像文件,輸出系統信息
複製代碼
圖17 基於內存分析檢測Rootkit原理示意圖
基於內存分析檢測Rootkit的方法比對常規的檢測方法有較大的優點,但它不是萬能的,若是被Bootkit之類的高級Rootkit干擾,Dump的物理內存不正確或不完整,後面的步驟就是空中閣樓。另外也要確保製做Profile時須要的System.map沒有被篡改或者直接使用同一內核版本號的Linux發行版中的文件來替代。
經過內存分析檢測Rootkit的工具目前不是不少,各有優劣。司法取證領域的開源工具Volatility是這方面的佼佼者,推薦各位同仁使用並貢獻代碼。對內存檢測分析技術感興趣的同窗,歡迎和我交流討論。EOF
注1:Linux中的so(shared object)文件近似於Windows下的dll(dynamic link library)文件,均用來提供函數和資源。
注2:Syscall Table通常能夠經過查看/boot/System.map文件來獲取其內容
注3: Process Descriptor:To manage processes, the kernel must have a clear picture of what each process is doing. It must know, for instance, the process's priority, whether it is running on a CPU or blocked on an event, what address space has been assigned to it, which files it is allowed to address, and so on. This is the role of the process descriptor — a task_struct type structure whose fields contain all the information related to a single process.
注4:mm_struct概要了相應程序所使用的內存信息,好比全部段(segment)、各個主要段的始末位置、使用常駐內存的總大小等等,通常稱之爲memory descriptor(內存描述符)
注5:mm_rb:Red black tree of mappings.
注6:HISTORY_USE_MMAP定義見bash-4.0-src/lib/readline/histfile.c 475行,具體可參見http://sourcecodebrowser.com/bash/4.0/histfile_8c_source.html.
複製代碼
http://www.rootkitanalytics.com/kernelland/linux-kernel-rootkit.php https://media.blackhat.com/bh-us-11/Case/BH_US_11_Case_Linux_Slides.pdf https://www.safaribooksonline.com/library/view/understanding-the-linux/0596005652/ch03s02.html http://www.wowotech.net/linux/19.html http://www.lenky.info/archives/2012/04/1424 http://code.google.com/p/volatility/