堆栈随机化是一项安全增强,它允许对系统调用发生时,内核使用的堆栈添加一个随机偏移。这给基于stack的攻击增加了难度,因为stack攻击通常要求stack有个固定的layout。现在每次系统调用,stack的layout都变化的话,攻击就无规律可寻了。
首先以系统调用为主线,看一下Linux内核ARM64架构堆栈随机化的实现方式:
在ARM64上,主要在系统调用的链条中增加了invoke_syscall()这个函数来实现堆栈随机化:
linux-5.4.175未增加堆栈随机化的实现:
linux-5.16.4增加堆栈随机化的实现:
我们模仿上面的逻辑,写一个demo来分析其原理:
#include#include #define DBG(fmt, ...) do { printf("%s line %d, "fmt"n", __func__, __LINE__, ##__VA_ARGS__); } while (0) int __attribute__((noinline)) bar(void) { unsigned int abc = 0; DBG("stack var addr %p.", &abc); return 0; } int __attribute__((noinline)) foo(void) { int offset = rand()%256; void *ptr = __builtin_alloca(offset); bar(); return 0; } int main(void) { int i = 0; for(i = 0; i < 10; i ++) { DBG("loop %d.", i); foo(); } return 0; }
去掉随机化之后,和上面对比,你会发现,堆栈地址在每次调用是都保持了不变。
具体的说,在内核实现中,这个机制允许在每个系统调用时,随机选择内核堆栈的偏移量,比如在启动时,通过输入randomize_kstack_offset=on/off控制是否启用这个机制。
得益于在每次系统调用时都分配了随机的内核堆栈偏移量,该功能可在启用后让基于堆栈的攻击变得更加困难。
结束!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)