设计 Shellcode 会给出不正确的结果

Desiging Shellcode gives incorrect results

我做了这个简单的汇编程序:

.text
    .globl _start
    _start:
        mov %20, %rbx
        mov %1, %rax
        int [=10=]x80

这显然是 64 位 OS (Linux) 上的 运行。然后我编译如下:

as -o ExitShellcode.o ExitShellcode.s
ld -o ExitShellcode ExitShellcode.o

最后在 运行 程序之后,它以状态 20

退出
echo $?
20

使用 objdump 转储文件的 shellcode 给出:

objdump -d ExitShellcode

ExitShellcode:     file format elf64-x86-64


Disassembly of section .text:

0000000000400078 <_start>:
400078: 48 c7 c3 14 00 00 00    mov    [=13=]x14,%rbx
40007f: 48 c7 c0 01 00 00 00    mov    [=13=]x1,%rax
400086: cd 80                   int    [=13=]x80

然而,在将 shellcode 放入该程序后:

#include <stdio.h>

char shellcode[] = "\x48\xc7\xc3\x14\x00\x00\x00"
                   "\x48\xc7\xc0\x01\x00\x00\x00"
                   "\xcd\x80";

int main()
{
    int *ret;

    ret = (int *)&ret +2;

    *ret = (int)shellcode;

}

正在编译:

gcc -g -o Shellcode Shellcode.c
Shellcode.c: In function ‘main’:
Shellcode.c:13:9: warning: cast from pointer to integer of different        size     [-Wpointer-to-int-cast]
*ret = (int)shellcode;

和运行,程序以0状态退出:

echo $?
0

有什么问题吗?它不应该以 20 退出吗?

您的代码错误地假定编译器会将变量 ret 放在堆栈上相对于 main 的 return 地址的特定位置。相反,编译器将它放在其他地方,因为它被允许这样做,所以你的代码什么都不做。您可能正在关注您在 Internet 上找到的设计糟糕的示例。

如果你想在 shellcode 数组中执行 "shellcode" 你可以尝试向它转换一个指向函数的指针然后调用它:

char shellcode[] = "\x48\xc7\xc3\x14\x00\x00\x00"
               "\x48\xc7\xc0\x01\x00\x00\x00"
               "\xcd\x80";

int main()
{
    ((void (*)()) shellcode)();
}

然而,这仍然可能会失败,因为放置 shellcode.data 部分不可执行,因此程序将在 运行 时崩溃。要解决该问题,请在链接您的程序时使用 -zexecstack 选项。例如:

gcc -zexecstack -g -o Shellcode Shellcode.c