【问题标题】:Address space layout randomization and structures in CC中的地址空间布局随机化和结构
【发布时间】:2019-03-22 08:32:03
【问题描述】:

我有这个结构:

struct Books {
 char  title[50];
 char  author[50];
};

假设我知道如果我将arg1 传递给程序,在代码的某些部分中,它会在$title+52 方向添加一些字符,因此author 的值被覆盖(缓冲区溢出)。

现在我将 ASLR 添加到我的二进制文件中。这样一来,有些方向是随机的,所以我认为我之前描述的缓冲区溢出是不可能的。

这是真的吗?或者即使我添加了 ASLR 结构成员的方向是在一起的,缓冲区溢出可能是可能的?

【问题讨论】:

  • ASLR 随机化连续虚拟内存块的起始位置。您的变量仍将位于其中一个块内。缓冲区溢出问题不会通过 ASLR 神奇地消失。
  • 这篇文章可能对您有所帮助:stackoverflow.com/questions/3605222/…
  • 请注意,作为问题的“缓冲区溢出”与“缓冲区溢出攻击”之间存在区别。 ALSR 没有将缓冲区溢出问题作为错误来解决。它只是使在攻击中有效地使用这样的错误变得更加困难。更具体地说,它使使用这样的错误来执行诸如窃取信息或获取访问权限之类的事情变得更加困难。攻击使程序崩溃并不会变得更加困难。
  • 嗨!谢谢两位,我会检查它:)

标签: c memory struct buffer-overflow aslr


【解决方案1】:

你提到的具体溢出还是有可能的。

除了位域之外,结构的域在内存中按顺序依次跟随(中间可能有一些填充)。这在C standard 的第 6.7.2.1p15 节中有详细说明:

在结构对象中,非位域成员和 位域所在的单元的地址增加 声明它们的顺序。 指向结构的指针 适当转换的对象指向其初始成员(或 如果该成员是位域,则到它所在的单元 驻留),反之亦然。内部可能有未命名的填充 一个结构对象,但不是在它的开头。

因此,在这种情况下,author 字段将始终跟随 title 字段,无论 struct Books 类型的对象位于哪个特定地址。唯一可能的区别可能是填充量,但除非您在结构中添加或删除字段,否则这可能不会改变。

【讨论】:

  • 感谢您的回答! C 参考非常适合我正在寻找的东西。 :)
【解决方案2】:

ASLR 不会影响编译时的内容。编译器在编译时选择结构的布局,并在生成的目标代码中进行硬编码。

此外,C 标准要求连续的结构成员按照它们在结构定义中出现的顺序排列在内存中(成员之间有未指定的填充,但这在编译时也是固定的)

【讨论】:

  • 感谢您的回答! :)
【解决方案3】:

我认为你误解了 ASLR(地址空间布局随机化)的效果:ASLR 随机排列进程的不同虚拟内存区域(可执行文件、堆栈、堆、数据、库等)的位置,使其在每个执行。它不会改变同一虚拟内存区域中元素的相对位置。


以下面的简单程序为例:

int main(void) {
    struct {
        char a[10];
        char b[10];
    } myvar;

    printf("a: %p\n", &myvar.a);
    printf("b: %p\n", &myvar.b);

    return 0;
}

这是程序在 ASLR 禁用时的虚拟内存:

0x555555554000     0x555555555000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x555555754000     0x555555755000 r--p     1000 0      /home/marco/test/test [read only data]
0x555555755000     0x555555756000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffffffde000     0x7ffffffff000 rw-p    21000 0      [stack] <-- myvar is here

输出(禁用 ASLR):

$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a
$ ./test
a: 0x7ffffffde080
b: 0x7ffffffde08a

这是启用的同一个程序:

0x559fefcbe000     0x559fefcbf000 r-xp     1000 0      /home/marco/test/test [executable segment]
0x559fefebe000     0x559fefebf000 r--p     1000 0      /home/marco/test/test [read only data]
0x559fefebf000     0x559fefec0000 rw-p     1000 1000   /home/marco/test/test [bss (global variables)]
0x7ffe3bb5e000     0x7ffe3bb7f000 rw-p    21000 0      [stack] <-- myvar is here

输出(启用 ASLR):

$ ./test
a: 0x7ffe3bb5e080
b: 0x7ffe3bb5e08a
$ ./test 
a: 0x7ff4abdeea80
b: 0x7ff4abdeea8a
$ ./test 
a: 0x7efa6b8fa080
b: 0x7efa6b8fa08a

您的变量仍将位于某个连续虚拟内存块内,并且字段的相对位置不会改变一点也不。使用 ASLR 时,连续数组仍然是连续的:它们只是从内存中的不同位置开始。

由于struct 字段在内存中按标准是连续的(并遵循它们的声明顺序),这意味着缓冲区溢出仍然是一个潜在问题,即使在使用 ASLR 时也是如此。

【讨论】:

  • 嗨!谢谢你的解释,很清楚!现在一切都搞定了。 :)
猜你喜欢
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
相关资源
最近更新 更多