我试图在一个示例程序上做一个简单的缓冲区溢出攻击,以便更好地理解二进制利用。目标是简单地在堆栈上编写外壳代码并执行它。然而,尽管有所有的在线资源,我仍然遇到一些奇怪的问题,我无法找到解决的办法。我希望有人能为我澄清几件事:)
以下程序是目标应用程序:
#include <string.h>
#include <stdio.h>
int main (int argc, char** argv)
{
char buffer[8];
if (argv[1] == NULL) return 0;
strcpy(buffer, argv[1]);
printf("Text: %s\n", buffer);
return 0;
}为了保持简单,我禁用了几种保护机制。二进制文件的编译方式如下:gcc app.c -o app -z execstack -fno-stack-protector -m32。此外,ASLR目前是禁用的:(/proc/sys/kernel/randomize_va_space == 0)。
此外,我使用gdb,因为据我所知,在执行二进制开发时,使用gdb会更好一些。
现在,我遇到了以下问题:
不管输入字符串有多长,我似乎不能覆盖EIP:

注意EIP是如何总是指向main的返回地址的?为什么,它应该被覆盖。增加A的数量并不能改变任何事情。而且,更奇怪的是ESP从来没有被A完全填满,它总是以0x4141413d ('=AAA')结束。
因为我似乎不能正确地覆盖EIP,所以我真的不能继续。
有人知道为什么会这样吗?我能做些什么?
发布于 2022-01-24 05:59:53
您正在分段错误,因为您已经溢出缓冲区,并在这样做时设法破坏ESP。如果你看一下错误,它说:Could not read memory at 0x4141413d,这是ESP的值。因此,当它试图执行ret时,堆栈指向未初始化的内存,从而导致分段错误。它之所以是0x3d而不是0x41,是因为它在尝试从ESP读取值之前将ESP减少了4。您可以尝试使用更短的A字符串,看看是否能够保持ESP不变。
main()中的Bufferoverflow往往更加混乱和不可靠,因为它们只在程序完成(主要返回)之后才触发,而不是在程序运行时触发。为了学习,您通常希望触发函数中的溢出,以便在返回时触发溢出,如下所示:
#include <string.h>
#include <stdio.h>
void hello(char* name) {
char buffer[8];
strcpy(buffer, name);
printf("Hello %s\n", buffer);
}
int main (int argc, char** argv)
{
if (argv[1] == NULL) return 0;
hello(argv[1]);
return 0;
}祝好运!
https://security.stackexchange.com/questions/246452
复制相似问题