为什么我的 shellcode 可以在 gdb 中运行,而不能在命令行中运行

逆向工程 数据库
2021-06-17 17:57:38

所以我刚开始逆向工程,遇到了一些问题,直到我最近注意到一些奇怪的事情。我编写了一个非常简单的 shellcode(退出系统调用)用于练习,并在 gdb 中使用它。我使用以下代码来创建我的有效负载:

$(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')

我针对以下程序运行此有效负载:

#include <string.h>

int main(int argc, char **argv)
{
  char buffer[500];
  strcpy(buffer, argv[1]);
}

我编译了程序:

tcc -m32 -mtune=i386 -g vuln.c -fno-stack-protector

现在,这是我的问题。当我像这样在 gdb 中针对程序运行有效负载时,它运行良好。

(gdb) r $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Starting program: /root/exploiting/a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
[Inferior 1 (process 2573) exited normally]
(gdb

但是,如果我在命令行上运行它:

root@kali:~/exploiting# ./a.out $(python -c 'print "\x90" * 498 + "\x31\xdb\xb0\x01\xcd\x80" + "\x2c\xd1\xff\xff"')
Segmentation fault

为什么会发生这种情况?这是应该发生的吗?

2个回答

它只是不同的填充大小:

看,这是我的解决方案,对我来说效果很好,您为 c 代码添加了两行,以检查 esp 是否与您在 gdb 中找到的 esp 相同:

$ vi esp.c
    #include <string.h>
    #include <stdio.h>
    void main(int argc, char *argv[]) {
            char buffer[100];
            strcpy(buffer, argv[1]);
            register int i asm("esp"); //add this line 
            printf("$esp = %#010x\n", i); // and this line will print esp
            printf("Done!\n");
    }

保存文件后用 gcc 编译它并防止所有安全级别:

$ gcc esp.c -o esp -fno-stack-protector -no-pie -z norelro -z execstack

您更改填充长度,直到找到从 gdb 获得的相同 esp:

./esp $(python -c "print 'gdb_eip'+96*'A'")

现在在 gdb 中找到很好的漏洞利用之后,去更改有效负载,直到 esp = gdb esp 更改填充,直到找到相同的 esp

gdb 会干扰您的环境变量,并可能禁用 ASLR。最有可能的是,在抛出 shellcode 之前启动 gdb 并运行 'unset env LINES' 和 'unset env COLUMNS' 将使输出与 gdb 之外的执行保持一致。:)