【问题标题】:What is the order of local variables on the stack?局部变量在栈上的顺序是什么?
【发布时间】:2019-01-22 20:46:09
【问题描述】:

我目前正在尝试对缓冲区溢出漏洞进行一些测试。 这是易受攻击的代码

void win()
  {
      printf("code flow successfully changed\n");
  }

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

      fp = 0;

      gets(buffer);

      if(fp) {
           printf("calling function pointer, jumping to 0x%08x\n", fp);
           fp();
             }
   }

漏洞利用非常简单且非常基本:这里我需要的只是溢出缓冲区并覆盖 fp 值以使其保存 win() 函数的地址。 在尝试调试程序时,我发现 fb 位于缓冲区下方(即内存中的较低地址),因此我无法修改其值。 我认为一旦我们在 y 之前声明了一个局部变量 xx 在内存中会更高(即在堆栈的底部)所以x 可以覆盖 y 如果它超出了它的边界,这里不是这种情况。 我正在用 gcc gcc 版本 5.2.1 编译程序,没有特殊标志(仅测试 -O0)

有什么线索吗?

【问题讨论】:

标签: variables gcc c buffer stack


【解决方案1】:

局部变量在栈上的顺序未指定。

它可能会在不同的编译器、不同的版本或不同的优化选项之间发生变化。它甚至可能取决于变量的名称或其他看似无关的事物。

【讨论】:

    【解决方案2】:

    直到编译/链接(构建)时才定义堆栈上局部变量的顺序。我当然不是专家,但我认为您必须进行某种“十六进制转储”,或者可能在调试器环境中运行代码以找出它的分配位置。而且我还猜测这将是一个相对地址,而不是绝对地址。

    正如@RalfFriedl 在他的回答中指出的那样,该位置可能会在为不同平台调用的任意数量的编译器选项下发生变化,等等。

    但我们确实知道缓冲区溢出是可能的。尽管由于地址空间布局随机化 (ASLR) 等防御措施,您现在听到的关于它们的消息越来越少,但它们仍然存在并为我猜想的某个人支付账单。当然有很多关于这个主题的在线文章;这是一个看起来相当流行的(https://www.synopsys.com/blogs/software-security/detect-prevent-and-mitigate-buffer-overflow-attacks/)。

    祝你好运(你甚至应该对练习缓冲区溢出攻击的人这么说吗?)。无论如何,我希望你能学到一些东西,并好好利用它:)

    【讨论】:

    • 嗨@Seamus,每次运行程序时,ASLR 用于以随机方式更改 libc 中函数的地址,更准确地说,ASRL 用于将所有组件移动一个随机值像栈、堆、文本这样的内存... 作为一种防御机制,它可以防止返回到 libc 和 ROP 攻击。它不会阻止堆栈粉碎(这是堆栈金丝雀的作用)。在我看来,防止溢出的缓冲区改变堆栈上另一个局部变量的值是不可能的。
    • @Ahmed202:感谢您的澄清。我在这里真的超出了我的深度,但是您似乎知识渊博-也许您应该回答?我很想了解更多关于它是如何工作的。我只是在这里,因为这个问题在另一个论坛中被问到,然后被感动了......所以我觉得有点像Dorothy in the Wizard of Oz :)
    • 我猜编译器正在通过重新排序堆栈上的局部变量来执行一种优化。如果我的假设是正确的,通过向 gcc 添加 -O0 标志来强制“非优化”模式将保持程序中预期的顺序,即缓冲区上方的 fp...
    猜你喜欢
    • 2010-11-09
    • 2021-05-21
    • 1970-01-01
    • 2015-01-09
    • 2018-01-15
    • 2019-02-22
    • 2018-03-02
    • 1970-01-01
    相关资源
    最近更新 更多