如何利用缓冲区溢出来执行堆栈上的指令
How to exploit a buffer overflow to execute instructions on the stack
我开始修补缓冲区溢出,并编写了以下程序:
#include <unistd.h>
void g() {
execve("/bin/sh", NULL, NULL);
}
void f() {
long *return_address;
char instructions[] = "\xb8\x01\x00\x00\x00\xcd\x80"; // exit(1)
return_address = (long*) (&return_address + 2);
*return_address = (long)&g; // or (long)instructions
}
int main() {
f();
}
它做了我期望它做的事情:return_address
用 g
的地址覆盖 f
的 return 地址,这会打开一个 shell.但是,如果我将 return 地址设置为 instructions
,则会出现段错误,并且会执行 instructions
中指令的 none。
我用 GCC 编译,使用 -fno-stack-protector
。
如何防止发生此分段错误?
至少有一个问题与缓冲区溢出无关。
execve("/bin/sh", NULL, NULL);
第一个 NULL 成为您正在启动的进程的 argv。 argv 必须是 终止 且带有 NULL 的字符串数组。因此,当 /bin/sh
启动、尝试读取 argv[0]
并取消引用 NULL 时,可能会发生段错误。
void g(void) {
char *argv[] = { "/bin/sh", NULL };
execve(argv[0], argv, NULL);
}
您还可以将 -z execstack
添加到 gcc 命令行,这将告诉链接器允许可执行堆栈。如果您是从某处的教程中获得的,您还应该验证您所拥有的说明是否是 exit(1)
在您的系统上编译的内容。
我开始修补缓冲区溢出,并编写了以下程序:
#include <unistd.h>
void g() {
execve("/bin/sh", NULL, NULL);
}
void f() {
long *return_address;
char instructions[] = "\xb8\x01\x00\x00\x00\xcd\x80"; // exit(1)
return_address = (long*) (&return_address + 2);
*return_address = (long)&g; // or (long)instructions
}
int main() {
f();
}
它做了我期望它做的事情:return_address
用 g
的地址覆盖 f
的 return 地址,这会打开一个 shell.但是,如果我将 return 地址设置为 instructions
,则会出现段错误,并且会执行 instructions
中指令的 none。
我用 GCC 编译,使用 -fno-stack-protector
。
如何防止发生此分段错误?
至少有一个问题与缓冲区溢出无关。
execve("/bin/sh", NULL, NULL);
第一个 NULL 成为您正在启动的进程的 argv。 argv 必须是 终止 且带有 NULL 的字符串数组。因此,当 /bin/sh
启动、尝试读取 argv[0]
并取消引用 NULL 时,可能会发生段错误。
void g(void) {
char *argv[] = { "/bin/sh", NULL };
execve(argv[0], argv, NULL);
}
您还可以将 -z execstack
添加到 gcc 命令行,这将告诉链接器允许可执行堆栈。如果您是从某处的教程中获得的,您还应该验证您所拥有的说明是否是 exit(1)
在您的系统上编译的内容。