需要一些有关BOF的高级说明

时间:2019-06-01 07:17:25

标签: security buffer-overflow

因此,我使用以下代码遵循tutorial关于缓冲区溢出的信息:

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

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

 modified = 0;
  gets(buffer);

  if(modified != 0) {
      printf("you have changed the 'modified' variable\n");
  } else {
      printf("Try again?\n");
  }
}

然后我用gcc对其进行编译,并事先运行sudo sysctl -w kernel.randomize_va_space=0以防止出现随机内存并允许堆栈粉碎(缓冲区溢出)漏洞利用

gcc protostar.c -g -z execstack -fno-stack-protector -o protostar

-g允许在gdb('list main')中进行调试
-z execstack -fno-stack-protector删除堆栈保护

然后执行它:

python -c 'print "A"*76' | ./protostar

再试一次?

python -c 'print "A"*77' | ./protostar

您已更改“修改”变量

所以我不明白为什么缓冲区溢出会在77应该是65的情况下以77发生,所以它会产生12位的差异(3个字节)。我想知道为什么有人能给出清楚的解释吗?

从77到87仍然如此:

python -c 'print "A"*87' | ./protostar
you have changed the 'modified' variable

从88开始,它增加了段错误:

python -c 'print "A"*88' | ./protostar
you have changed the 'modified' variable
Segmentation fault (core dumped)

致谢

1 个答案:

答案 0 :(得分:1)

要完全了解正在发生的事情,首先要注意程序是如何布局内存的。

根据您的评论,对于此特定运行,buffer的存储从0x7fffffffdf10开始,然后modified的存储从0x7fffffffdf5c开始(尽管randomize_va_space可能会在每次运行中保持一致,但我不确定)。

所以你有这样的东西:

0x7fffffffdf10            0x7fffffffdf50      0x7fffffffdf5c
↓                         ↓                   ↓
(64 byte buffer)..........(some 12 bytes).....(modified)....

基本上,您有64个字符的缓冲区,然后在结束时,有12个字节用于其他堆栈变量(可能是4个字节argc和8个字节用于argv),然后修改后,缓冲区开始后精确地开始64 + 12 = 76个字节。

因此,当您在65到76个字符之间写入64字节缓冲区时,它会越过并开始写入缓冲区和modified之间的那12个字节。当您开始编写第77个字符时,它将开始覆盖modified中的内容,这会导致您看到“ you have changed the 'modified' variable”消息。

您还问“如果我升至87,然后在88时出现段错误,为什么会起作用?答案是因为这是未定义的行为,因此,一旦您开始写入无效的内存并且内核能够识别它,它就会会立即终止您的进程,因为您尝试读取/写入您无权访问的内存。

请注意,在实践中几乎应该永远不要使用gets,这是一个很大的原因,因为您不知道要读取多少字节,因此有机会覆盖。还要注意,您看到的行为与运行机器时在计算机上看到的行为不同。这是正常现象,因为这是未定义的行为。无法保证运行时会发生什么。在我的计算机上,modified实际上在内存中buffer之前,因此我从未见过modified变量被覆盖。我认为这是一个很好的学习示例,可以理解为什么这样的未定义行为是如此不可预测。