gpt4 book ai didi

c - 缓冲区溢出向后流动?

转载 作者:太空狗 更新时间:2023-10-29 17:26:19 27 4
gpt4 key购买 nike

我在读“黑客:剥削的艺术”这本书,我偶然发现了这本书的一部分,其中显示了通过重新排列内存中的变量来防止缓冲区溢出漏洞的假设。我试过了这个程序仍然容易受到缓冲区溢出的影响。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int check_authentication(char *password) {
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
char password_buffer[16];
int auth_flag = 0;
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

strcpy(password_buffer, password);

if (strcmp(password_buffer, "password1") == 0)
auth_flag = 1;
if (strcmp(password_buffer, "password2") == 0)
auth_flag = 0;

return auth_flag;
}


int main(int argc, char *argv[]) {
if (check_authentication(argv[1])) {
printf("ACCESS GRANTED");
} else {
printf("ACCESS DENIED");
}
}

这个程序,简而言之,检查第二个命令行参数提供的身份验证 key ,并告诉用户访问是否被授予。主要关注点是带星号的注释所概述的变量。从理论上讲,这种变量安排应该可以防止由于 FILO 数据结构而导致的缓冲区溢出攻击,这意味着密码缓冲区应该位于 auth_flag 变量之后,因此应该可以防止密码缓冲区成为缓冲区溢出的执行点。下面是 GDB 中执行流程的检查:

(gdb) break 9
Breakpoint 1 at 0x1188: file auth_overflow2.c, line 9.
(gdb) break 16
Breakpoint 2 at 0x11d7: file auth_overflow2.c, line 16.

检查程序的第一步是在第 9 行(执行 strcpy 函数的地方,密码验证之前)和第 16 行(返回 auth_flag,然后进行密码验证的地方)设置断点。然后,我们可以运行程序并检查断点 1 处的内存。

(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/user/Hacking/a.out aaaaaaaaaaaaaaaaaaaaaaaaaaaa

Breakpoint 1, check_authentication (password=0x7fffffffe484 'a' <repeats 29 times>) at auth_overflow2.c:9
9 strcpy(password_buffer, password);
(gdb) x/s password_buffer
0x7fffffffe060: ""
(gdb) x/x &auth_flag
0x7fffffffe07c: 0x00
(gdb)x/16xw &auth_flag
0x7fffffffe07c: 0x00000000 0xffffe0a0 0x00007fff 0x55555229
0x7fffffffe08c: 0x00005555 0xffffe188 0x00007fff 0x00000000
0x7fffffffe09c: 0x00000002 0x55555270 0x00005555 0xf7e0609b
0x7fffffffe0ac: 0x00007fff 0x00000000 0x00000000 0xffffe188

正如我们从上面的输出中看到的,auth_flag 是正确的 0,密码缓冲区是空的。上面输出中的最后一个命令还表明 auth_flag 变量正确位于密码缓冲区之前,因此理论上缓冲区溢出不应该以任何方式影响 auth_flag 变量。现在让我们继续程序并在身份验证检查后检查内存。

(gdb) cont
Continuing.

Breakpoint 2, check_authentication (password=0x7fffffffe484 'a' <repeats 29 times>) at auth_overflow2.c:16
16 return auth_flag;
(gdb) x/s password_buffer
0x7fffffffe060: 'a' <repeats 29 times>
(gdb) x/x &auth_flag
0x7fffffffe07c: 0x61
(gdb) x/16xw &auth_flag
0x7fffffffe07c: 0x00000061 0xffffe0a0 0x00007fff 0x55555229
0x7fffffffe08c: 0x00005555 0xffffe188 0x00007fff 0x00000000
0x7fffffffe09c: 0x00000002 0x55555270 0x00005555 0xf7e0609b
0x7fffffffe0ac: 0x00007fff 0x00000000 0x00000000 0xffffe188

正如您从上面的输出中看到的,即使密码缓冲区位于 auth_flag 变量之后,auth_flag 变量也以某种方式更改为非零值。

那么,考虑到所有这些信息,缓冲区溢出怎么可能在内存中向后流动而不是向前流动?

最佳答案

一些编译器重新排列栈上数组,如果栈帧中有其他变量或溢出槽,它们将不与返回地址相邻,希望有限的几个字节的溢出不再能够到达返回地址,从而重定向执行。如果这些变量与返回地址一样对安全性同样重要,那么这种启发式方法就会出错,在您的假设示例中,情况似乎就是这样。

关于c - 缓冲区溢出向后流动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57139896/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com