序言
在一些黑客組織中, Rootkit (或者backdoor) 是一個非常感興趣的話題。 各種不同的Rootkit被開發並發布在internet上。在這些Rootkit之中, LKM尤其被人關注, 因為它是利用現代操作系統的模塊技術。作為內核的一部分運行,這種Rootkit將會越來越比傳統技術更加強大更加不易被發覺。一旦被安裝運行到目標機器上, 系統就會完全被控制在hacker手中了。甚至系統管理員根本找不到安全隱患的痕跡, 因為他們不能再信任它們的操作系統了。
本文章以及我們開發的一些強大的LKM程序都是基於Linux Kernel 2.2.x版本的。我們的目的是盡可能多的隱藏足跡。
在接下來的一部分, 我們將介紹一下已經存在的後門技術, 然後和LKM技術相比較, 最後討論我麼的LKM程序的設計與實現。
後門程序的目的就是甚至系統管理員企圖彌補系統漏洞的時候也可以給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程序主要是基於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