Linux平台的ASLR机制

简介

ASLR,全称为 Address Space Layout Randomization,地址空间布局随机化。ASLR 技术在 2005 年的 kernel 2.6.12 中被引入到 Linux 系统,它将进程的某些内存空间地址进行随机化来增大入侵者预测目的地址的难度,从而降低进程被成功入侵的风险。当前 Linux、Windows 等主流操作系统都已经采用该项技术。

具体实现

分级

Linux 平台上 ASLR 分为 0,1,2 三级,用户可以通过一个内核参数 randomize_va_space 进行等级控制。它们对应的效果如下:

  • 0:没有随机化。即关闭 ASLR。
  • 1:保留的随机化。共享库、栈、mmap() 以及 VDSO 将被随机化。
  • 2:完全的随机化。在 1 的基础上,通过 brk() 分配的内存空间也将被随机化。

看到这里列出的几项内存空间,很自然有两个地方十分值得注意,第一,代码段以及数据段(data段和bss段)是否被随机化了?第二,堆是否被随机化了?

ASLR 并不负责代码段和数据段的随机化

编写程序进行测试:

#include <stdio.h>

void func();

int uninitialGlobalVar;
int globalVar = 1;

int main(void)
{
    int localVar = 1;

    printf("Address of func() is %p, in text setment\n", func);
    printf("Address of uninitialGlobalVar is %p, in bss segment\n", &uninitialGlobalVar);
    printf("Address of globalVar is %p, in data segment\n", &globalVar);
    printf("Address of localVar is %p, in stack\n", &localVar);

    return 0;
}

void func()
{
    ;
}

开启完全的ASLR机制,即设置 ASLR 为 2,详细的开启关闭命令后文有介绍。使用如下命令:

sudo bash -c "echo 2 > /proc/sys/kernel/randomize_va_space"

运行程序,结果如下:

plus@plus:~/Desktop$ ./addr
Address of func() is 0x400595, in text setment
Address of uninitialGlobalVar is 0x601048, in bss segment
Address of globalVar is 0x601040, in data segment
Address of localVar is 0x7ffc353d218c, in stack
plus@plus:~/Desktop$ 
plus@plus:~/Desktop$ ./addr
Address of func() is 0x400595, in text setment
Address of uninitialGlobalVar is 0x601048, in bss segment
Address of globalVar is 0x601040, in data segment
Address of localVar is 0x7ffc08733eac, in stack

可见栈的地址被随机化了,但是代码段以及数据段的地址均没有发生变化。由此可知,ASLR 并不负责代码段和数据段的随机化工作。

事实上,Linux 平台通过 PIE 机制来负责代码段和数据段的随机化工作,而不是 ASLR。要开启 PIE,在使用 gcc 进行编译链接时添加 -fpie -pie 选项即可:

plus@plus:~/Desktop$ gcc addr.c -fpie -pie -o addr

开启 PIE 后,设置 ASLR 为 2,重新运行程序,结果如下:

plus@plus:~/Desktop$ ./addr
Address of func() is 0x564753ff37ee, in text setment
Address of uninitialGlobalVar is 0x5647541f4050, in bss segment
Address of globalVar is 0x5647541f4048, in data segment
Address of localVar is 0x7ffd61090a2c, 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值