【问题标题】:Turning off stack protection关闭堆栈保护
【发布时间】:2017-08-28 12:31:33
【问题描述】:

我只是想知道,因为我有这个 C 代码:

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

int fillBuffer(int argc, char *argv[]) {
  char bufferA[4] = "aaa";
  char bufferB[4] = "bbb";

  if(argc > 1)
    strcpy(bufferB, argv[1]);

  printf("bufferA: %s\n", bufferA);
  printf("bufferB: %s\n", bufferB);

  return 0;
}

int main(int argc, char *argv[]) {
  fillBuffer(argc, argv);
  return 0;
}

我尝试使用以下命令关闭堆栈保护:-fno-stack-protector

当我尝试通过执行:./program (escape key) 5f 来运行它时,程序输出到:

缓冲区A:f

缓冲区B:fffff

我只是不确定 bufferA 是如何变成 f 的。谁能给我解释一下?

【问题讨论】:

  • 您确定argv[1]3 字符吗?...
  • 未定义的行为,任何事情都可能发生。这只是一种可能性。
  • c代码只是给我们一个例子
  • 我确信bufferAbufferB 的基址可能会说明正在发生的事情,是的,无论如何它都是UB。我想这段代码是作为一个迫在眉睫的缓冲区溢出问题的例子提供的?
  • 我也很怀疑。所以将你的打印更改为printf("bufferA:%p %s\n", (const void*)bufferA, bufferA);bufferB 也是如此)并记下地址。然后做一些数学运算,你应该会发现对bufferB 的破坏溢出到了bufferA 的内存中。或者在你的情况下它会似乎。如前所述,这都是 UB,所以不要指望你发现的任何东西都是福音。

标签: c stack buffer-overflow


【解决方案1】:

本地缓冲区 A 和 B 以相反的顺序存储在您的堆栈中。因此,在内存中,您有 8 个字节的起始缓冲区 B,然后是缓冲区 A。

当你将你的 5 个“f”strcpy 到缓冲区 B 时,前 4 个进入缓冲区 B,最后一个以 '\0' 结尾的字符串进入缓冲区 A。

然后,当您 printf 缓冲区时,缓冲区 A 包含 1 个“f”和字符串终止符。这就是它的来源。

【讨论】:

    【解决方案2】:

    您的 strcpy 调用不安全,如果 argv[1] 包含超过 3 个字符(加上一个用于空终止字符),则会损坏您的堆栈。不要点击逃逸,只需空格和 5f 即可获得正确的输出:

    scott> a.out 5f
    bufferA: aaa
    bufferB: 5f
    

    当您点击转义时,shell 可以向字符串参数添加额外的字符,并且由于您的 strcpy 不安全(不检查长度),它会超出缓冲区的末尾并破坏您的堆栈。您的缓冲区只有 4 个字符长,因此如果输入超过 3 个字符的参数,您的程序将损坏堆栈。

    要修复它,请将缓冲区大小从 4 增加到更合理的值,例如 60,并使用 strncpy 确保在参数过长时不会超出缓冲区:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAX_PARM_LEN  60
    
    int fillBuffer(int argc, char *argv[]) {
      char bufferA[MAX_PARM_LEN] = "aaa";
      char bufferB[MAX_PARM_LEN] = "bbb";
    
      if(argc > 1)
        strncpy(bufferB, argv[1], MAX_PARM_LEN);
    
      printf("bufferA: %s\n", bufferA);
      printf("bufferB: %s\n", bufferB);
    
      return 0;
    }
    
    int main(int argc, char *argv[]) {
      fillBuffer(argc, argv);
      return 0;
    }
    

    最后一点:不要关闭堆栈保护。

    【讨论】:

      猜你喜欢
      • 2011-07-30
      • 2017-06-30
      • 2016-06-30
      • 2020-08-17
      • 2023-04-07
      • 2014-04-16
      • 2014-06-30
      • 2011-06-13
      • 2019-04-19
      相关资源
      最近更新 更多