作者:
[email protected]
四、保護重要進程
進程是操作系統的動態入口。內核裡有兩個特殊進程,進程ID 0 (swapd) 和進程ID 1(init)。Init進程是在系統啟動的時候所有進程的父進程。
1、不可殺死的進程。
就象你可以看到是否有人要奪得root特權一樣,我們可以很容易的殺死那些該內核發送特別信號的進程。為了殺死一個進程,你必須得到進程的ID,然後用kill命令來殺死它。
系統殺死進程的調用是kill,是在內核裡的sys_kill()命令裡的調用。
讓我們看看LIDS的保護代碼
在/usr/src/Linux/kernel/signal.c裡
asmlinkage int
sys_kill(int pid, int sig)
{
strUCt siginfo info;
#ifdef CONFIG_LIDS_INIT_CHILDREN_LOCK pid_t this_pid;
int i;
#ifdef CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN
if (!(current->flags & PF_KILLINITC))
#endif
if (lids_load && lids_local_load && LIDS_FISSET(lids_flags,LIDS_FLAGS_LOCK_INIT_CHILDREN)) {
this_pid = pid>0?pid:-pid;
for(i=0;i
if( this_pid == lids_protected_pid[i]) {
lids_security_alert("Try to kill pid=%d,sig=%dn",pid,sig);
return -EPERM;
}
}
}
#endif
...
}
你可以在內核裡看到兩個標簽,,CONFIG_LIDS_INIT_CHILDREN_LOCK 和CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN.
在CONFIG_LIDS_INIT_CHILDREN_LOCK的開啟狀態,LIDS能保護初使的運行程序。如,如果你在系統裡運行inetd程序,你可以在隱藏內核前運行它,然後,你還可以殺死它。但是一些人如果telnet到你的機器,inetd就會創造子進程來為用戶服務,這個子進程不會被LIDS保護,因為用戶在任何時候退出和殺死程序。
2、隱藏進程
另外一個保護進程的方法就是隱藏進程。當一個黑客危機你的系統。他會登陸,然後會看看有沒有一些已知的進程在監視它。然後他就殺死它。如果你隱藏了這個功能的進程,黑客就不會知道進程的所有情況並且你可以記錄他在你系統上做的任何事情。
如何隱藏進程
為了隱藏進程,你必須在配置內核的時候提供一個完全的路徑名。
當內核啟動的時候,LIDS會訪問文件結點到一個叫proc_to_hide[]的結構裡。
在include/linux/sched.h裡
#ifdef CONFIG_LIDS_HIDE_PROC
#define PF_HIDDEN 0x04000000 /* Hidden process */
#endif
/* in fs/lids.c */
#ifdef CONFIG_LIDS_HIDE_PROC
struct allowed_ino proc_to_hide[LIDS_MAX_ALLOWED];
int last_hide=0;
#endif
....
/* in fs/lids.c , init_vfs_security(),
fill up the hidden process in proc_to_hide[]
*/
#ifdef CONFIG_LIDS_HIDE_PROC
lids_fill_table(proc_to_hide,&last_hide,LIDS_MAX_ALLOWED,CONFIG_LIDS_HIDDEN_PROC_PATH);
#endif
PF_HIDDEN是否用戶可以用顯示進程的命令(如“ps –a”)來顯示和檢查進程,如果一個進程被LIDS隱藏,當他執行的時候,進程就會得到一個PF_HIDDEN的屬性。然後,當系統輸出系統進程信息到用戶的時候,它就會可以檢查當前輸出進程是否有PF_HIDDEN標志。如果發現了,它就不會輸出這個進程的信息。
在in fs/exec.c
int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
{
...
if (retval >= 0) {
#ifdef CONFIG_LIDS_HIDE_PROC
if (lids_search_proc_to_hide(dentry->d_inode))
current->flags = PF_HIDDEN;
...
因為每一個linux的進程都有一個在/proc文件系統的入口,我們為了隱藏進程也需要修改proc的文件入口。
在fs/proc/root.c
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{
...
inode = NULL;
#ifdef CONFIG_LIDS_HIDE_PROC
if ( pid && p && (! ((p->flags & PF_HIDDEN) && lids_load && lids_local_load)) ) {
#else
if (pid && p) {
#endif
unsigned long ino = (pid >> 16) + PROC_PID_INO;
inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
if (!inode)
return ERR_PTR(-EINVAL);
inode->i_flags=S_IMMUTABLE;
}
...
}
然後如果進程被PF_HIDDEN標記,它
if (!inode)
return ERR_PTR(-EINVAL);
inode->i_flags=S_IMMUTABLE;
}
...
}
然後如果進程被PF_HIDDEN標記,它
right">