歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux資訊 >> 更多Linux

後門技術和Linux LKM Rootkit

摘要:在這篇文章裡, 我們將看到各種不同的後門技術,特別是Linux的可裝載內核模塊(LKM)。 我們將會發現lkm後門比傳統的後門程序更加復雜,更加強大,更不易於被發現。知道這些之後,我們可以制造我們自己的基於lkm的rootkit程序, 主要體現在tcp/ip層, 因為我們相信這是在系統管理員面前最好的隱藏後門的地方。   翻譯:e4gle(大鷹)       Backdoor and Linux LKM Rootkit - smashing the kernel at your own risk       來源:CS290I Project Report       譯:alert7,el8 from m4in security teams.       CS290I Project Report       Backdoor and Linux LKM Rootkit - smashing the kernel at your own risk       by: Jingyu Zhou and Lin Qiao       簡介: 在這篇文章裡, 我們將看到各種不同的後門技術,特別是linux的可裝載內核模塊(LKM)。 我們將會發現lkm後門比傳統的後門程序更加復雜,更加強大,更不易於被發現。知道這些之後,我們可以制造我們自己的基於lkm的rootkit程序, 主要體現在tcp/ip層, 因為我們相信這是在系統管理員面前最好的隱藏後門的地方。     序言。       在一些黑客組織中, rootkit (或者backdoor) 是一個非常感興趣的話題。 各種不同的rootkit被開發並發布在internet上。在這些rootkit之中, LKM尤其被人關注, 因為它是利用現代操作系統的模塊技術。作為內核的一部分運行,這種rootkit將會越來越比傳統技術更加強大更加不易被發覺。一旦被安裝運行到目標機器上, 系統就會完全被控制在hacker手中了。甚至系統管理員根本找不到安全隱患的痕跡, 因為他們不能再信任它們的操作系統了。       本文章以及我們開發的一些強大的lkm程序都是基於linux kernel 2.2.x版本的。我們的目的是盡可能多的隱藏足跡。       在接下來的一部分, 我們將介紹一下已經存在的後門技術, 然後和lkm技術相比較, 最後討論我麼的lkm程序的設計與實現。     已存在的後門技術 - 系統管理員的悲慘世界。~0~       後門程序的目的就是甚至系統管理員企圖彌補系統漏洞的時候也可以給hacker系統的訪問權限。       後門程序使本地用戶取得root權限可以這樣做: 設置uid程序, 系統木馬程序, cron後門。       1. 設置uid程序。 黑客在一些文件系統理放一些設置uid腳本程序。無論何時它們只要執行這個程序它們就會成為root。       2. 系統木馬程序。黑客替換一些系統程序,       如"login"程序。因此, 只要滿足一定的條件,那些程序就會給黑客最高權限。       3. Cron 後門。黑客在cron增加或修改一些任務,       在某個特定的時間程序運行,他們就可以獲得最高權限。       後門程序給遠程用戶以最高訪問權限可以這樣做: ".rhost" 文件, ssh認證密鑰, bind shell, 木馬服務程序。       1. ".rhosts" 文件。一旦 "+ +"被加入某個用戶的.rhosts文件裡, 任何人在任何地方都可以用這個賬號來登陸進來而不需要密碼。       2. ssh 認證密鑰。黑客把他自己的公共密鑰放到目標機器的ssh配置文件"authorized_keys"裡, 他可以用該賬號來訪問機器而不需要密碼。       3. Bind shell。黑客綁定一個shell到一個特定的tcp端口。任何人telnet這個端口都可以獲得交互的shell。更多精巧的這種方式的後門可以基於udp,或者未連接的tcp, 甚至icmp協議。       4. Trojaned服務程序。任何打開的服務都可以成為木馬來為遠程用戶提供訪問權限。例如, 利用inetd服務在一個特定的端口來創建一個bind shell,或者通過ssh守護進程提供訪問途徑。       在入侵者植入和運行後門程序之後, 他會找一些方法和系統管理員開一些善意的玩笑。這主要涉及到兩個方面問題: 如何來隱藏他的文件且如何來隱藏他的進程。       為了隱藏文件, 入侵者需要做如下事情: 替換一些系統常用命令如"ls", "du", "fsck"。在底層方面, 他們通過把硬盤裡的一些區域標記為壞塊並把它的文件放在那裡。或者如果他足夠瘋狂,他會把一些文件放入引導塊裡。       為了隱藏進程, 他可以替換 "ps"程序, 或者通過修改argv[]來使程序看起來象一個合法的服務程序。有趣的是把一個程序改成中斷驅動的話,它就不會出現在進程表裡了。     LKM - 還有比這個更臭屁的麼?       我們已經看到過一些常規的技術。現在的問題是: 系統管理員可以找出它們麼?實際上, 一個好的系統管理員可以很輕易的找出它們中的%99。 問題是入侵者必須修改或者創建一些重要文件。 如果系統管理員保存一份"tripwire"數據庫, 通過這些可以確定安全隱患的存在。通過浏覽文件系統可以去掉suid程序, ".rhosts" 文件, 等。       相反, 利用lkm我們可有效的突破這些限制。首先,我們在重要的系統目錄裡不必修改或創建任何文件。我們可以把lkm程序放在/tmp或/var/tmp目錄下, 一般系統管理員是不會監視這些目錄的。 其次, 我們可以隱藏我們想要的任何東西, 象文件, 進程, 和網絡連接。 因為要得到這些信息, 用戶必須依賴系統調用。       因此我們可以修改內核結構, 我們可以用我們自己的函數來替換原系統調用。最後,我們甚至可以攻擊或修改tcp/ip協議棧並且去愚弄系統內核!       以下部分,我們將介紹如何利用這些機制以及實現方法。     我們的LKM - "Kicking Kernel Ass From Left to Right" [3]       我們的lkm程序主要是基於linux kernel 2.2.x及tcp/ip上的實現, 因為一個優秀的後門程序一定會給遠程用戶訪問該系統的權限。在目標機器上打開一個端口,運行一個服務是非常容易暴露的。我們需要盡可能的隱藏自己。       第一個想法是我們在目標機器上不運行任何進程來等待連接,我們在tcp/ip協議棧裡來創建一個函數來替代它。 無論何時一個特殊的udp或tcp包被接受,內核將會檢查這個包來確定是否是指定的特殊包。假如是的話, 內核將派生一個進程來執行命令。我們可以使用任何內核可以支持的協議包。       現在我們來實現它。在內核裡, 每個協議在*inet_protocol_base和*inet_protos[MAX_INET_PROTOS]       hash注冊自己。 當系統初始化時, 所有支持的協議會再inet_protocol_base注冊。他們被加到inet_protos的哈希表裡。不管什麼時候一個IP包達到時, 內核將檢查這個哈希表,找相應的處理函數和系統調用。我們就在這個點上進行hack。我們將用我們的處理函數來替換原始的協議的處理函數。因此,我們可以截獲數據包並且分析它。假如它是我們需要的, 我們將執行我們的命令。 假如不是,僅僅只需要調用原來的函數。       我們同時處理TCP和UDP的原因是假如那裡有一些防火牆的話,UDP可能不能穿過。因此,我們只需要發一個源地址被偽造的數據包到目的機子。此外,對於TCP的數據包,它也不需要使用SYN位。事實上,現在我們的客戶程序使用的是ACK的包。       第二個想法更使人感興趣。 如果一台目標的機子上有個WEB的服務並且安了一個只允許WEB通信的防火牆,那麼我們如何來穿過它呢? 我們能否得到一個交互的shell呢?答案是肯定的。方法如下:   ____________ _________________________    攻擊者 web server    80 <=======> 53333   __________ _______________________         ____________________________________   1025 ==> 80 or 1025 <== 80       假設我們在web服務器上已經綁定了一個bind shell後門並且監聽53333端口(可以利用第一個方法來完成)       現在我們需要把攻擊者到web服務器上的流量從80端口重定向到53333端口, 從53333端口到攻擊者的流量必須被改成80端口。       實現部分。改變接收的包是很容易的, 我們可以借用第一個lkm的思路- 無論何時我們都檢查到來的tcp包如果必要我們修改它的目的端口。為了改變發出的包, 這就有點困難了。 因為tcp/ip協議棧的實現涉及到linux內核的一些底層的靜態函數。它不太容易被置換(但是是可能的, 細節參見附錄)。 我們利用的是大部分發布時就被編譯進內核中的防火牆。每個到來的包,轉發的包, 或發出的包必須通過防火牆。並且防火牆函數是可以被動態地加載到內核裡的!我們利用系統導出函數register_firewall() 在系統防火牆規則之前插入我們自己的規則。假如我們發現一些來自於53333端口的包, 我們可以自動改變它到80。       關於此實現的另外的細節是無論何時我們改變數據包, 我們必須去重新計算校驗和。 更有趣的事情是我們可以在web服務器和其他一些機器上監聽網絡流量,我們可以看到他們的不同之處。 在其他機器上的sniffer看起來象普通的web流量, 但是在web服務器上的sniffer是一些無用的流量紀錄。具體細節參見附錄。       現在我們談一下如何來截獲系統調用。為了隱藏入侵者的足跡, 文件, 進程,網絡連接必須隱藏起來。 因為這些信息都是可以從特殊的系統調用裡面獲得的, 我們可以接獲一些感興趣的系統調用。       1. 隱藏文件。象這些命令如"ls", "du" 使用sys_getdents() 來獲得目錄信息。 所以lkm程序必須過濾這些輸出來達到隱藏文件的目的。       2. 隱藏進程。在linux的實現中,進程的信息被映射到/proc文件系統去了。我們的工作仍舊是捕獲sys_getdents()調用在進程鏈表中標記為不可見。通常的手法是設置任務的信號標志位為一些未用的信號量,比如31就是一個例子。       3. 隱藏網絡連接。 和隱藏進程相似, 在這個例子中我們是這去隱藏一些包括/proc/net/tcp和/proc/net/udp的文件。所以我們改變sys_read()。 無論何時讀包含匹配字符串的這兩個文件的時候, 系統調用將不會聲明在使用它。       4. 重定向可執行文件。 有時候, 入侵者可能會需要替換系統的二進制文件, 象"login", 但不想改變原文件。他可以截獲sys_execve()。因此, 無論何時系統嘗試去執行"login"程序的時候, 它都會被重定向到入侵者給定的其他程序。       5. 隱藏sniffer。這兒我們指隱藏網絡接口的雜撥模式。在這裡我們要替換的是sys_ioctl()。       6. 和lkm通信。 黑客已經很好的安裝了他的lkm。現在他需要告訴內核來隱藏其他文件。他該怎麼做呢?我們知道從用戶態切換到和心態通常是通過系統調用來進行的, 所以我們必須修改一些系統調用。       例如, 我們將截獲sys_settimeofday()。當一個指定的參數被傳遞, 我們的系統調用將會為我們做一些適當的事情。       7. 隱藏lkm本身。一個優秀的lkm程序必須很好地隱藏它自己。系統裡的lkm是用單向鏈表連接起來的, 為了隱藏lkm本身我們必須把它從鏈表中移走以至於lsmod這樣的命令不能把它顯示出來。       8. 隱藏符號表。通常的lkm中的函數將會被導出以至於其他模塊可以使用它。因為我們是入侵者, 所以隱藏這些符號是必須的。幸運的是, 有一個宏可以供我們使用:"EXPORT_NO_SYMBOLS"。 把這個宏放在lkm的最後可以防止任何符號的輸出。     經驗和結論。       做個lkm程序是一個非常有趣而又非常危險的事情。有趣的是你可以在系統內核中作你想做的事情。 但這也是非常危險的, 它可以使你的服務陷入混亂, 破壞你的數據, 並且可以在你的系統裡做任何怪異的事情。 我們的經驗有: 在安裝了lkm程序幾天後我們的網絡層不工作了, 只工作五分鐘就要重起一次; 無論何時發送數據包, 象這些應用程序 telnet, netscape, pine都將會產生core dump; 在安裝lkm程序後立馬重起。所以, 就象標題所說的那樣,後果自負!       值得一提的是寫一個lkm程序你可以更好地了解到系統是如何工作的。例如, /proc文件系統有很好的特性。因為lkm程序工作在內核空間, 調試lkm程序就變得比一般程序要困難。 使用"printk"函數可以解決一些問題。但這不是最好的解決方法。通過注冊在/proc文件系統裡的我們的文件和目錄的數據結構, 我們可以訪問到任何時間的內核空間的信息。我們甚至可以通過寫這個文件來修改內存, 盡管一般不建議這樣做。     結束語      從經驗來看, 很明顯的lkm程序可以在linux上安裝,一旦系統被攻破並且被安裝了lkm的rootkit程序, 這就變的很難被發現了。因為甚至操作系統都不能信任了。如果機器不允許關機,唯一的發現入侵者的方法是通過分析在網絡其他機器上的sniffer結果。 或者, 利用其他的操作系統來監測硬盤。所有這兩個方法都很難去做, 因為你不知道你要找什麼。       所以,所以最好的安全措施就是防止被攻擊者入侵系統。     參考資料。       1. Bypassing Integrity Checking Systems. http://phrack.infonexus.com/search.pHtml?view&article=p51-9       2. Weakening the Linux Kernel. http://phrack.infonexus.com/search.phtml?view&article=p52-18       3. Building Into The Linux Network Layer. http://phrack.infonexus.com/search.phtml?view&article=p55-12       4. (nearly) Complete Linux Loadable Kernel Modules. http://packetstorm.securify.com/groups/thc/LKM_HACKING.html       5. Backdoors. http://www.dataguard.no/bugtraq/1997_3/0310.html       6. Runtime Kernel Kmem Patching. http://www.big.net.au/~silvio/runtime-kernel-kmem-patching.txt     附錄       1. 替換協議例程來改變發送數據包。       在linux內核中,每個BSD socket 在內核結構中實際上是一對socket/sock。發送數據包的例程是利用sock結構中的tcp_opt*成員來實現的, 輪流使用af_specific成員。有意思的是這裡所有的ipv4都使用相同的地址, 例如, 所有的af_specific 將指向同樣的內核地址, 這個結構地址保存了一個例程集合。我們怎麼在"tcp_func"這個實力中修改函數地址呢?       方法很簡單, 但實現起來卻不那麼容易。因為沒有一個很簡單的方法去得到那個結構的地址。一個可能的方法是:       從進程鏈表(任務結構鏈表)中找出它打開的文件; 然後從這些文件中找出實際指向socket的地址; 從socket可以得到sock結構地址; 最後獲得"ipv4_specific"的地址。       我們來理順以下上面所說的流程: task -> files_strUCt     -> file -> inode -> socket ->  sock -> tcp_opt -> tcp_func.       其他的方法就更加困難和危險了。這個靈感是來自於[6]。我們可以通過搜索內核內存來找到我們要的明確的函數地址。然後修改內核內存。首先我們跳轉到我們代碼的地址然後跳回常規例程。       2. 從web服務器和從網絡工作站上的流量監聽。       在這段中, mamet是一個裝了我們的後門的服務器且leone是一個攻擊者。       開始的tcpdump輸出紀錄了除了mamet之外的一些網絡工作站的流量。我們可以煩先這時正常的。leone的2603端口 和mamet的80端口的通信:     14:16:27.214888 eth0 > leone.cs.ucsb.edu.2603 > mamet.cs.ucsb.edu.www: S   3840116896:3840116896(0) win 32120  



Copyright © Linux教程網 All Rights Reserved