我使用的是 Ubuntu 18.04。我正在尝试进行缓冲区溢出攻击。
这是我编写并试图攻击的 C 程序:
// test.c
#include <stdio.h>
void f();
int main(int argc, char *argv[])
{
printf("argc : %d\n", argc);
for(int i = 0; i < argc; i++)
{
printf("argv[%d] : %s\n", i, argv[i]);
}
printf("End of program\n");
return 0;
}
void f()
{
printf("You got to the hidden function!\n");
}
...编译为:
gcc test.c -o test
这是我的 Python3 注入脚本:
# inject.py
push = "A" * 1000
print(push)
inject.py
我尝试了 3 种方法将to的输出通过管道传输test
:
# attempt 1
$ ./test <(python3 inject.py)
argc : 2
argv[0] : ./test
argv[1] : /dev/fd/63
End of program
$ Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
^C
^ 在这里,它实际上在没有我输入的情况下进行了第二次,并且在它冻结后$
我不得不退出ctrl+C
# attempt 2
$ python3 inject.py | ./test
argc : 1
argv[0] : ./test
End of program
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
# attempt 3
$ ./test <(python3 -c "print(\"A\"*1000)")
argc : 2
argv[0] : ./test
argv[1] : /dev/fd/63
End of program
$ Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
^C
^ 这与尝试 1 类似
我相信我所做的与我在 YouTube 上看到的许多缓冲区溢出类似。我原以为会出现错误SegFault
,但结果却出现了Broken pipe
错误。
我究竟做错了什么?为什么我得到Broken pipe
而不是SegFault
s?
澄清:我要求的不是“如何进行缓冲区溢出攻击?”,而是“为什么我会收到错误Broken pipe
以及如何修复它?”。由于这是 *nix 命令行的问题,我相信这在这个社区的范围内。
答案1
由于您没有读取 Python 程序输出的数据,因此您会在 Python 程序中收到“损坏的管道”错误。您的 C 程序完全忽略其标准输入流,并且该流在终止时关闭test
,从而使 Python 程序尝试写入无人监听的管道。
bash
当您在( )中使用进程替换时,也会使用管道<(...)
,这就是您在那里遇到相同问题的原因。在这些示例中,数据不是通过标准输入到达的,而是来自命令的第一个命令行参数指示的文件。你永远不会打开这个文件。
要解决此问题,请确保 C 程序使用来自标准输入或命令第一个参数指示的路径名的所有输入。
您当前的代码不会导致 C 代码中的缓冲区溢出、分段错误或任何其他错误。
我假设您想以某种方式导致 C 代码中的缓冲区溢出。例如,您可以通过将数据从 Python 代码读取到太小的缓冲区中来实现这一点。
顺便说一句,Python 代码不需要是 Python,它可以是一个生成大量数据的简单 shell 命令,例如yes
实用程序(可能通过管道传输head -n 1000
或类似的,如 中yes A | head -n 1000
)。