熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

LIDS精通與進階(二)

2013-11-13 15:41:51  來源: Oracle 

  四保護重要進程
  
  進程是操作系統的動態入口內核裡有兩個特殊進程進程ID (swapd) 和進程ID (init)Init進程是在系統啟動的時候所有進程的父進程
  
  不可殺死的進程
  
  就象你可以看到是否有人要奪得root特權一樣我們可以很容易的殺死那些該內核發送特別信號的進程為了殺死一個進程你必須得到進程的ID然後用kill命令來殺死它
  
  系統殺死進程的調用是kill是在內核裡的sys_kill()命令裡的調用
  
  讓我們看看LIDS的保護代碼
  
  在/usr/src/linux/kernel/signalc裡
  
  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_flagsLIDS_FLAGS_LOCK_INIT_CHILDREN)) {
  
  this_pid = pid>?pid:pid;
  
  for(i=;i
  if( this_pid == lids_protected_pid[i]) {
  
  lids_security_alert(Try to kill pid=%dsig=%dnpidsig);
  
  return EPERM;
  
  }
  
  }
  
  }
  
  #endif
  
  
  
  }
  
  你可以在內核裡看到兩個標簽CONFIG_LIDS_INIT_CHILDREN_LOCK 和CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN
  
  在CONFIG_LIDS_INIT_CHILDREN_LOCK的開啟狀態LIDS能保護初使的運行程序如果你在系統裡運行inetd程序你可以在隱藏內核前運行它然後你還可以殺死它但是一些人如果telnet到你的機器inetd就會創造子進程來為用戶服務這個子進程不會被LIDS保護因為用戶在任何時候退出和殺死程序
  
  隱藏進程
  
  另外一個保護進程的方法就是隱藏進程當一個黑客危機你的系統他會登陸然後會看看有沒有一些已知的進程在監視它然後他就殺死它如果你隱藏了這個功能的進程黑客就不會知道進程的所有情況並且你可以記錄他在你系統上做的任何事情
  
  如何隱藏進程
  
  為了隱藏進程你必須在配置內核的時候提供一個完全的路徑名
  
  當內核啟動的時候LIDS會訪問文件結點到一個叫proc_to_hide[]的結構裡
  
  在include/linux/schedh裡
  
  #ifdef CONFIG_LIDS_HIDE_PROC
  
  #define PF_HIDDEN x /* Hidden process */
  
  #endif
  
  /* in fs/lidsc */
  
  #ifdef CONFIG_LIDS_HIDE_PROC
  
  struct allowed_ino proc_to_hide[LIDS_MAX_ALLOWED];
  
  int last_hide=;
  
  #endif
  
  
  
  /* in fs/lidsc init_vfs_security()
  
  fill up the hidden process in proc_to_hide[]
  
  */
  
  #ifdef CONFIG_LIDS_HIDE_PROC
  
  lids_fill_table(proc_to_hide&last_hideLIDS_MAX_ALLOWEDCONFIG_LIDS_HIDDEN_PROC_PATH);
  
  #endif
  
  PF_HIDDEN是否用戶可以用顯示進程的命令(如ps –a)來顯示和檢查進程如果一個進程被LIDS隱藏當他執行的時候進程就會得到一個PF_HIDDEN的屬性然後當系統輸出系統進程信息到用戶的時候它就會可以檢查當前輸出進程是否有PF_HIDDEN標志如果發現了它就不會輸出這個進程的信息
  
  在in fs/execc
  
  int do_execve(char * filename char ** argv char ** envp struct pt_regs * regs)
  
  {
  
  
  
  if (retval >= ) {
  
  #ifdef CONFIG_LIDS_HIDE_PROC
  
  if (lids_search_proc_to_hide(dentry>d_inode))
  
  current>flags |= PF_HIDDEN;
  
  
  
  因為每一個linux的進程都有一個在/proc文件系統的入口我們為了隱藏進程也需要修改proc的文件入口
  
  在fs/proc/rootc
  
  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 >> ) + 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標記它就不會在proc文件系統裡顯示
  
  五密封內核
  
  我們需要在系統啟動的時候做一些必要的操作但是我們也需要在系統運行的時候保護它們
  
  例如我們需要象內核裡插入一些需要的模塊但是我們不希望在系統運行的時候插入任何模塊因為那樣會十分危險如何解決這個問題呢?這裡就有一些密封的方法我們可以在系統啟動的時候做我們任何想做的事情然後我們就密封內核然後我們就不能做那些以前在沒有密封的時候可以做的事情用密封的方法我們可以用模塊來解決問題我們可以在密封前向內核裡插入我們想要的模塊在密封後我們就不可以在內核裡插入或是刪除任何模塊
  
  用LIDS密封內核
  
  為了密封內核我們可以用下面的LIDS命令
  
  #lidsadm –I CAP_xxx…
  
  它們可以放到腳本裡讓系統啟動的時候就執行它具體你們可以看我以前在linuxbyte和chinabyte發表的文章LIDS是通過/proc/sys/lids/locks和內核通訊的
  
  當你密封了內核lidsadm是調用lidsadmc的lids_init()的調用
  
  #define LIDS_LOCKS /proc/sys/lids/locks
  
  
  
  void lids_init(int optind int argc char *argv[])
  
  {
  
  
  
  if ((fd=open(LIDS_LOCKSO_RDWR)) == ) {
  
  perror(open);
  
  exit_error ( can open LIDS_LOCKS);
  
  }
  
  if (read(fd&lockssizeof(lids_locks_t))==) {
  
  perror(read);
  
  exit_error ( can read LIDS_LOCKS);
  
  }
  
  lids_set_caps(optindargcargv&locks);
  
  
  locksmagic=LIDS_MAGIC_;
  
  
  
  if (write(fd&lockssizeof(lids_locks_t))==) {
  
  perror(write);
  
  exit_error ( can write LIDS_LOCKS);
  
  }
  
  
  
  }
  
  這個系統調用在LIDS_LOCKS生成新的變量loks內核會通過lids_proc_locks_sysctl()命令來讀取它Lids_proc_locks_sysctl也會從用戶區完全檢查並讀取它然後改變密封的變量lids_first_time為
  
  讓我們看看lids_proc_locks_sysctl()這個函數會在用戶讀寫/proc/sys/lids/locks的時候調用
  
  int lids_proc_locks_sysctl(ctl_table *table int write struct file *filp
  
  void *buffer size_t *lenp int conv int op)
  
  {
  
  
  
  /* first: check the terminal and the program which access the sysctl */
  
  #ifndef CONFIG_LIDS_REMOTE_SWITCH
  
  if (current>tty && (current>tty>drivertype != ) ) {
  
  lids_security_alert(Try to %s locks sysctl (unauthorized terminal)
  
  write ? write : read);
  
  return EPERM;
  
  }
  
  #endif
  
  
  
  /* second: check wether it is not a timeout period after two many failed attempts */
  
  
  
  if (write) {
  
  /* Third : check what is submitted (size magics passwd) */
  
  if (*lenp != sizeof(lids_locks_t)) {
  
  lids_security_alert(Try to feed locks sysctl with garbage);
  
  return EINVAL;
  
  }
  
  if (copy_from_user(&locksbuffersizeof(lids_locks_t)))
  
  return EFAULT;
  
  
  
  if ((lids_first_time) && (!lockspasswd[])) {
  
  
  
  number_failed=;
  
  if (lids_process_flags(locksflags)) {
  
  cap_bset=lockscap_bset;

From:http://tw.wingwit.com/Article/program/Oracle/201311/17154.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.