利用C-Linux setuid和系统命令

时间:2018-11-22 12:12:17

标签: c linux security buffer-overflow

我将以下代码作为可执行文件,希望将其用作课程,以生成具有提升特权的shell。我是levelX的用户,可执行文件的setgid为levelX + 1。我不允许更改任何代码。 由于我没有root权限,因此setguid(0)失败。我无法更改函数或主函数的返回地址。谁能指出正确的方向?

int main (int argc, char** argv)
{
  if (exec(argv[1]) != 0)
    {
      fprintf(stderr, "Cannot execute your command\n");
      return -1;
    }
  return 0;
}

int exec(char *command)
{
  FILE *f = NULL;
  char entry[64];
  char line[256];

  f = fopen("log", "a");
  if (f == NULL)
    {
      fprintf(stderr, "Can't open file\n");
      return -1;
    }
  snprintf(entry, 64, "%d: %s\n", getuid(), command);

  fprintf(f, entry, NULL);
  fclose(f);

  f = fopen("sudoers", "r");
  if (f == NULL)
    {
      fprintf(stderr, "Can't open\n");
      return -1;
    }

  while(fgets(line, 256, f) != NULL)
    {
      if (atoi(line) == getuid())
        {
          if (setuid(0) == 0) {
            system(command);
          } else {
            fprintf(stderr, "check permissions\n");
          }

          fclose(f);
          return 0;
        }
    }
  fprintf(stderr, "Error\n");
  fclose(f);
  return -1;
}

2 个答案:

答案 0 :(得分:1)

从您发布的代码来看,似乎应该将自己的sudoers文件写入具有写访问权限的任何目录,然后在该目录中运行该程序,以便读取文件。

因此,只需将您自己的UID写入此伪造的sudoers文件,然后提供命令参数,例如bash即可获得外壳。无需进行任何缓冲区溢出利用。

大概是真正的可利用程序在文件许可权中设置了suid位,因此它可以执行setuid(0)调用。我猜想该练习的目的是演示在处理suid程序时需要如何清除所有输入内容,包括像其他用户一样的相对路径(有效地将当前工作目录作为输入)之类的东西。 -提供的路径和其他输入。


但是,由于该程序仅具有setgid位(如注释中所述),因此您需要找到仅使用组ID进行的操作。可能是该日志文件写入了。您可以使用文件名log创建一个符号链接,指向要添加到该文件组具有写权限的任何文件。同样,该文件需要具有这样的格式,即日志行格式不会使文件损坏。请记住,您可以在命令行参数中添加换行符!

答案 1 :(得分:0)

毕竟,这是fprintf(f, entry, NULL);int exec(char *command)上的一种格式字符串利用,您在其中用%n格式覆盖了返回地址。