设计 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
我做了这个简单的汇编程序:
.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