为什么我会收到此[管道损坏]错误?

为什么我会收到此[管道损坏]错误?

我使用的是 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而不是SegFaults?

澄清:我要求的不是“如何进行缓冲区溢出攻击?”,而是“为什么我会收到错误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)。

相关内容