search

Home  >  Q&A  >  body text

c++ - 探讨主流内存保护机制下的缓冲区溢出攻击可行形式

void foo(char *data){
    char name[10];

    printf("%p\n%p\n%p\n%p\n");//打印当前程序栈内存
    strcpy(name, data);//覆盖返回地址
}

void hack(void){
    puts("another place");
}

int main(){
    char buf[10];
    char buf2[10];

    scanf("%s", buf);
    foo(buf);

    return 0;
}

以上是经典的缓冲区溢出攻击,当buf中输入超过10(16)字节,将会覆盖buf2中的内容;如果写入更多字节数,可以改变寄存器中保存的地址,使得被调用函数执行完成后返回到另一个函数的入口地址。

问题:
当前保护机制下,只能覆盖buf2中内容,但是即便跳过很长的内存保护的区域依然找不到记录被调函数返回地址的位置。1.在linux下不采用任何内存保护方法编译源代码的方法?2.关于现在内存保护机制下缓冲区溢出攻击的可能形式。

PHP中文网PHP中文网2805 days ago634

reply all(1)I'll reply

  • PHP中文网

    PHP中文网2017-04-17 11:18:58

    The implementation of Stack protector is to put a canary random value on the stack. After the function call is completed, check whether the value is intact. If not, it proves that the stack is destroyed.

    There is a problem with your original code. If what you input overflows the buffer, it will overwrite the return address of scanf, then it will not be returned correctly, and foo will not be called.
    I guess what you want is this:

    void foo(char *data){
      scanf("%s", data);
      printf("%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n");
    }
    int main(){
      char buf[10];
      char buf2[10];
      foo(buf);
      return 0;
    }
    
    

    Some common sense needs to be known. It does not mean that the return address will be overwritten if you enter more than 20 characters. The allocation of local variables on the stack is not compact. They are usually aligned and aligned to 16 bytes.

    So, if you enter a lot of characters (more than 64?), you can get segment fault.
    But you have no way to change the correct return address, one is because of ALSR, Address space layout randomization, and the other is because the canary itself is a random value, and you cannot overwrite it correctly, and ultimately you cannot escape the check.

    So, you can only create the effect of segmentfault, but you cannot overwrite the return address and allow the code to continue running normally.

    1. How to compile source code without using any memory protection method under Linux?

    GCC has a -fno-stack-protector parameter. By default, stack-protector is enabled. When GCC detects that the function parameter type is char * and has no limited length, it will put a canary on the stack before the function call.

    Question 2 I don’t want to think too much about it at the moment.

    reply
    0
  • Cancelreply