1. 程式人生 > >Linux可載入核心模組(LKM)

Linux可載入核心模組(LKM)

轉載自http://blog.csdn.net/zhaqiwen/article/details/8288472

I.基礎知識

1.什麼是LKM 
2.什麼是系統呼叫
3.什麼是核心符號表
4.如何進行核心與使用者空間記憶體資料的交換
5.使用使用者空間的各種函式方法
6.常用核心空間函式列表
7.什麼是核心後臺程序
8.建立自己的裝置
II.深入探討
1.如何截獲系統呼叫
2.哪些系統呼叫應被截獲
2.1 尋找重要的系統呼叫(strace命令方法)
3.迷惑核心系統表
4.針對檔案系統的黑客方法
4.1 如何隱藏檔案
4.2 如何隱藏檔案內容(總體說明)
4.3 如何隱藏檔案的特定部分(源語示例)

4.4 如何監視重定向檔案操作
4.5 如何避免某一檔案的屬主問題
4.6 如何使黑客工具目錄不可訪問
4.7 如何改變CHROOT環境
5.針對程序的黑客方法
5.1如何隱藏某一程序
5.2如何重定向檔案的執行
6.針對網路(Socket)的黑客方法
6.1 如何控制Socket操作
7.終端(TTY)的擷取方法
8.用LKM編寫病毒
8.1 LKM病毒是如何感染檔案的(不僅感染模組;源語示例)
8.2 LKM病毒如何協助入侵的
9.使LKM不可見、不可刪除
10.其它濫用核心後臺程序的方法
11.如何檢測自己編寫的當前LKM 
III.解決辦法(用於系統管理員)

1.LKM檢測程式的原理與思路
1.1 檢測程式示例
1.2 密碼保護的creat_module()函式型別程式的例項
2.反LKM傳染程式的編寫思路 
3.使自己的程式不可跟蹤(原理)
4.用LKM加固Linux核心
4.1 為何給予仲裁程式執行權?(用LKM實現的Phrack的Route的思路)
4.2 鏈路修補(用LKM實現的Phrack 的Solar Designer的思路)
4.3 /proc 許可權修補(用LKM實現的Phrack的Route的思路)
4.4 securelevel修補(用LKM實現的Phrack的Route的思路)
底層磁碟修補
IV.一些更好的思路(用於黑客)

1.反擊管理員的LKM的技巧
2.修補整個核心—或建立黑客作業系統
2.1如何在/dev/kmem下尋找核心符號
2.2無需核心支援的新insmod命令
3.最後幾句
內容提要 
V.最新特性:核心2.2 
1.對LKM編寫者來說主要的不同點
VI.後話
1.LKM的背景或如何使系統外掛與入侵相容
2.到其它資源的連結
致謝
附錄
A –原始碼
a) LKM Infection by Stealthf0rk/SVAT 
b) Heroin - the classic one by Runar Jensen 
c) LKM Hider / Socket Backdoor by plaguez 
d) LKM TTY hijacking by halflife 
e) AFHRM - the monitor tool by Michal Zalewski 
f) CHROOT module trick by FLoW/HISPAHACK 
g) Kernel Memory Patching by ? 
h) Module insertion without native support by Silvio Cesare 
導 言
用Linux構造伺服器環境越來越流行,所以入侵Linux也日益增多。攻擊Linux的最高技術
之一就是使用核心程式碼。這種核心程式碼可據其特性稱為可載入核心模組(LKM),是一段
執行在核心空間的程式碼,這就允許我們訪問作業系統最敏感的部分。以前也有一些非常出色
的介紹LKM入侵的文獻(例如Phrack),他們介紹新的思路、新的方法並完成一個黑客夢
寐以求的功能的LKM,並且1998年一些公開的討論(新聞組、郵件列表)也是非常熱門的。
為什麼我又寫一遍關於LKM的文字呢,有幾個原因: 
以前的文獻對核心初學者沒有給出好的解釋;本文有比較大的篇幅幫助初學者去理解概念。
我見過很多利用漏洞或竊聽程式卻對這些東西如何工作一無所知的人。我在文中包括了大量
加了詳細註釋的原始碼,主要也是為了幫助那些知道網路入侵遠遠不同於網路破壞的初學者。
所有公開的文獻都是關於某個主題的,沒有專門為黑客寫的關於LKM的完備的指導。本文
將涵蓋核心濫用的幾乎所有方面(甚至關於病毒)
本文是從黑客和病毒程式編寫者的角度出發的,但對系統管理員和一般核心開發人員改進工
作也有幫助。
早期的文獻向我們提供了LKM濫用的主要優點和方法,但沒有什麼是大家沒聽說過的。本
文將提供一些新的思路。(沒有完全都是新的東西,但有些東西會對我們有所幫助)
本文將提供一些概念,用簡單的方法防止LKM攻擊。
本文還將說明如何運用一些方法打破LKM保護,如實時程式碼修補。
請記住,新思路的實現是用源語模組實現的(只用於演示),如果要實際使用就須改寫。
本文的寫作動機是給大家一篇涵蓋LKM所有問題的文章。在附錄A給出了一些已有的LKM
外掛和它們工作的簡單描述以及如何使用它們。
整個文章(第五部分除外)是基於Linux2.0.x機器的(x86)。本人測試了所有程式和程式碼
段。為了使用本文的大部分程式例子,Linux系統必須支援LKM。只有第四部分提供的源
程式碼無須本地LKM支援。本文中的大部分思路在2.2.x版本的系統上也能用(也許需要一
些輕微改動);但想到2.2.x核心剛剛釋出(1/99)並且大部分發行商一直使用2.0.x
(Redhat,SuSE,Caldera,...)。要到四月一些發行商如SuSE才會發行它們的2.2.x版核心,所
以目前還無須知道如何入侵2.2.x核心。好的系統管理員為了更穩定的2.2.x核心也等了好幾
個月了。[注:好多系統不需要2.2.x核心所以還會沿用2.0.x] 
本文有專門一節幫助系統管理員針對LKM提高系統安全。讀者(黑客)也要閱讀此節,你
必須懂得系統管理員懂的所有知識,甚至比他懂的更多。你從此節也會獲得一些思路,幫助
自己編寫更高階的‘黑客—LKM’。請通讀全文。
請記住:本文僅用於教育目的。如利用本文的知識從事非法活動,後果自負。
第一部分 基礎知識
1、什麼是LKM 
LKM是Linux核心為了擴充套件其功能所使用的可載入核心模組。LKM的優點:動態載入,無
須重新實現整個核心。基於此特性,LKM常被用作特殊裝置的驅動程式(或檔案系統),
如音效卡的驅動程式等等。
所有的LKM包含兩個最基本的函式(最小):
int init_module(void) /*用於初始化所有成員*/ 

... 

void cleanup_module(void) /*用於退出清理*/ 

... 

載入一個模組使用如下命令,一般只有root有此許可權:
#insomod module.o 
此命令強制系統如下工作:
載入目標檔案(此處為module.o)
呼叫create_module系統呼叫(關於系統呼叫見I.2)重新分配記憶體
核心符號用系統呼叫get_kernel_syms解析尚未解析的引用
然後系統呼叫init_module初始化LKMà 即執行int init_module(void)函式
核心符號將在I.3中解釋(核心符號表)。
下面我們寫出第一個小LKM展示一下它的基本工作原理:
#define MODULE 
#include < LINUX module.h > 
int init_module(void) 

printk("<1>Hello World\n"); 
return 0; 

void cleanup_module(void) 

printk("<1>Bye, Bye"); 

你可能想知道為什麼用printk(...)而不是用printf(...),是的,核心程式設計大體上是不同於使用者空
間程式設計的。你只有一個有限的命令集(見I.6)。用這些命令你不能做太多事,所以你將學
到如何利用你所知的使用者空間應用的大量函式去幫助你攻擊核心。耐心一點,我們不得不做
一些以前(沒聽過,沒做過...)的一些事。
上例如下編譯:
#gcc –c –O3 helloworld.c 
#insmod helloworld.o 
好,我們的模組被載入了,並顯示了最著名的文字。現在你可以用一些命令來告訴你你的
LKM確實存在於核心空間了。
#lsmod 
Module Pages Used by 
helloworld 1 0 
此命令從/proc/modules下讀取資訊,顯示當前哪些模組被載入。’Pages’是記憶體資訊(此模組
用了多少頁);’Used by’欄目告之此模組被系統用了多少次(引用次數)。只有此欄目數值
為0時,才能刪除模組;檢查此數值後,可用如下命令刪除模組:
#rmmod helloworld 
好,這是我們朝著濫用LKM走的第一小步(非常小)。本人經常把LKM同以前DOS下內
存駐留程式進行對比(我知道,它們有很多不同),它們都是我們駐留在記憶體中截獲每個我
們想要的中斷的一個門戶。微軟的Win9x有種程式叫VxD的,也同LKM相似(當然也有
很多不同)。這些駐留程式最令人感興趣的部分是具有掛起系統函式的功能,這些系統函式
在Linux世界裡稱為系統呼叫。
2、什麼是系統呼叫
我希望你能明白,每個作業系統都有一些嵌在核心中的函式,這些函式可以被系統的每個操
作使用。
這些Linux使用的函式稱為系統呼叫。它們對應使用者和核心之間的轉換。在使用者空間開啟一
個檔案對應核心空間的sys_open系統呼叫。要得到自己系統的完全的系統呼叫列表可以看
/usr/include/sys/syscall.h檔案。下面是我機器上的syscall.h列表:
#ifndef _SYS_SYSCALL_H 
#define _SYS_SYSCALL_H 
#define SYS_setup 0 /* 只用於初始化,使系統執行 。*/ 
#define SYS_exit 1 
#define SYS_fork 2 
#define SYS_read 3 
#define SYS_write 4 
#define SYS_open 5 
#define SYS_close 6 
#define SYS_waitpid 7 
#define SYS_creat 8 
#define SYS_link 9 
#define SYS_unlink 10 
#define SYS_execve 11 
#define SYS_chdir 12 
#define SYS_time 13 
#define SYS_prev_mknod 14 
#define SYS_chmod 15 
#define SYS_chown 16 
#define SYS_break 17 
#define SYS_oldstat 18 
#define SYS_lseek 19 
#define SYS_getpid 20 
#define SYS_mount 21 
#define SYS_umount 22 
#define SYS_setuid 23 
#define SYS_getuid 24 
#define SYS_stime 25 
#define SYS_ptrace 26 
#define SYS_alarm 27 
#define SYS_oldfstat 28 
#define SYS_pause 29 
#define SYS_utime 30 
#define SYS_stty 31 
#define SYS_gtty 32 
#define SYS_access 33 
#define SYS_nice 34 
#define SYS_ftime 35 
#define SYS_sync 36 
#define SYS_kill 37 
#define SYS_rename 38 
#define SYS_mkdir 39 
#define SYS_rmdir 40 
#define SYS_dup 41 
#define SYS_pipe 42 
#define SYS_times 43 
#define SYS_prof 44 
#define SYS_brk 45 
#define SYS_setgid 46 
#define SYS_getgid 47 
#define SYS_signal 48 
#define SYS_geteuid 49 
#define SYS_getegid 50 
#define SYS_acct 51 
#define SYS_phys 52 
#define SYS_lock 53 
#define SYS_ioctl 54 
#define SYS_fcntl 55 
#define SYS_mpx 56 
#define SYS_setpgid 57 
#define SYS_ulimit 58 
#define SYS_oldolduname 59 
#define SYS_umask 60 
#define SYS_chroot 61 
#define SYS_prev_ustat 62 
#define SYS_dup2 63 
#define SYS_getppid 64 
#define SYS_getpgrp 65 
#define SYS_setsid 66 
#define SYS_sigaction 67 
#define SYS_siggetmask 68 
#define SYS_sigsetmask 69 
#define SYS_setreuid 70 
#define SYS_setregid 71 
#define SYS_sigsuspend 72 
#define SYS_sigpending 73 
#define SYS_sethostname 74 
#define SYS_setrlimit 75 
#define SYS_getrlimit 76 
#define SYS_getrusage 77 
#define SYS_gettimeofday 78 
#define SYS_settimeofday 79 
#define SYS_getgroups 80 
#define SYS_setgroups 81 
#define SYS_select 82 
#define SYS_symlink 83 
#define SYS_oldlstat 84 
#define SYS_readlink 85 
#define SYS_uselib 86 
#define SYS_swapon 87 
#define SYS_reboot 88 
#define SYS_readdir 89 
#define SYS_mmap 90 
#define SYS_munmap 91 
#define SYS_truncate 92 
#define SYS_ftruncate 93 
#define SYS_fchmod 94 
#define SYS_fchown 95 
#define SYS_getpriority 96 
#define SYS_setpriority 97 
#define SYS_profil 98 
#define SYS_statfs 99 
#define SYS_fstatfs 100 
#define SYS_ioperm 101 
#define SYS_socketcall 102 
#define SYS_klog 103 
#define SYS_setitimer 104 
#define SYS_getitimer 105 
#define SYS_prev_stat 106 
#define SYS_prev_lstat 107 
#define SYS_prev_fstat 108 
#define SYS_olduname 109 
#define SYS_iopl 110 
#define SYS_vhangup 111 
#define SYS_idle 112 
#define SYS_vm86old 113 
#define SYS_wait4 114 
#define SYS_swapoff 115 
#define SYS_sysinfo 116 
#define SYS_ipc 117 
#define SYS_fsync 118 
#define SYS_sigreturn 119 
#define SYS_clone 120 
#define SYS_setdomainname 121 
#define SYS_uname 122 
#define SYS_modify_ldt 123 
#define SYS_adjtimex 124 
#define SYS_mprotect 125 
#define SYS_sigprocmask 126 
#define SYS_create_module 127 
#define SYS_init_module 128 
#define SYS_delete_module 129 
#define SYS_get_kernel_syms 130