ASLR大家都会听说过,但是Linux平台下应用程序的ASLR的情况是怎么样的呢?我在这里将ASLR分为几个小的部分来阐述,包括了栈的随机化,堆的随机化,mmap的随机化,以及pie程序运行时的主模块随机化。目的是为了知道随机化了哪些比特,随机了多少比特。

我在这里以Linux 4.11.4进行分析,以x64为代表,分析通过静态观察内核的源代码和动态调试内核源代码结合。在这里分析的是用户态程序的ASLR,由于用户态程序的ASLR是在程序加载执行过程中完成的,所以分析的起点应该是程序的加载执行。程序的加载执行从execve系统调用开始,到do_execve,到do_exeveat_common[1],因此就沿着这条主线一直走下去。

按照这个主线看下去,第一个见到的随机化是mmap的随机化[2],mmap有两种方式,早期是从低地址空间向高地址空间分配,如今是从高地址空间向低地址空间分配。mmap随机的位数由mmap_rnd_bits表示,在64位下是28比特,经过计算在64位平台下mmap的基地址是:page_align(0x7ffbf8000000-rand),而其中的rand在是28比特的数字左移12位。当mmap的基地址确定后,在各个系统中,程序运行起来时各个模块(不包括pie程序的主模块、但包括各个动态链接库)与mmap的基地址的偏移是固定的,因此这些模块加载地址的随机化也在28比特。

紧接着是栈的随机化,栈的随机化在3个地方有涉及。第一是[3],在这里将STACK_TOP进行了随机化。没随机化前的STACK_TOP的值是0x00007ffffffff000L,栈的随机化的位数由STACK_RND_MASK决定,STACK_RND_MASK在x64下是0x3fffff,也就是说栈的随机位数是22比特,经过计算,这里将STACK_TOP的值随机化为page_align(0x00007ffffffff000L-rand),而其中rand是22比特的随机数左移12位(即0到0x3fffff个页大小)。第二是[4],这里将STACK_TOP减去0或者1个页大小。第三个是[5],将栈内存高地址随机减去了0到8192,并进行了16字节对齐[5]。下图是一个程序运行中栈布局的图,1和2分别是两处随机化。

如果程序是pie的,那么程序主模块也会被随机化,见[8],这里主模块基地址被随机化为ELF_PAGESTART(0x555555554aaa+rand),rand由arch_mmap_rnd生成,和mmap随机化的位数是一样的,都是28比特。

下面是堆的随机化,堆空间的位置由start_brk和brk确定[6],程序运行最初start_brk和brk指向同一个位置,即data/bss段的下一个页面。堆的随机化的实现在[7],start_brk被随机化为[old_start_brk, old_start_brk+0x02000000)中页面对齐的值。

调试内核使用的是qemu,关于如何调试Linux内核网上有很多的文章。前期的准备就是一个编译好的Linux kernel、一个已经安装了Linux系统的硬盘镜像和一个gdb调试器。关于编译Linux kernel,尽可能少的编译优化对于调试会有不少帮助,但是Linux kernel并不能整体在-O0下编译,但是可以对单个源码文件或者单个函数以-O0形式进行编译,我们针对性地选择哪些不要优化[9][10]。关于准备安装了Linux系统的硬盘镜像,一种是自己手动创建硬盘并进行安装系统[12],例外一种就是使用网上已经存在的硬盘镜像,我用的是网上已经存在的Ubuntu Cloud Images[11]。关于gdb调试器,依赖于guest系统是什么系统,如果guest系统是ARM Linux,那么就需要一个ARM平台下的GDB。一种方法是手动的交叉编译,另外一种就是安装gdb-multiarch,它支持多种平台下的GDB。

附一下我用的命令行:qemu-system-x86_64 -s -S -hda xenial-server-cloudimg-amd64.img -initrd initrd.img-4.4.0-78-generic -kernel arch/x86/boot/bzImage -drive file=fat:rw:/media/sf_E_DRIVE/tools/mykey/ -redir tcp:5555::22 -append 'root=/dev/sda rw init=/usr/lib/cloud-init/uncloud-init ds=nocloud mem=1024M'

 

[1] http://elixir.free-electrons.com/linux/v4.11.4/source/fs/exec.c#L1660

[2] http://elixir.free-electrons.com/linux/v4.11.4/source/arch/x86/mm/mmap.c#L101

[3] http://elixir.free-electrons.com/linux/v4.11.4/source/fs/binfmt_elf.c#L875

[4] http://elixir.free-electrons.com/linux/v4.11.4/source/fs/exec.c#L696

[5] https://lwn.net/Articles/631631/

[6] https://sploitfun.wordpress.com/2015/02/11/syscalls-used-by-malloc/

[7] http://elixir.free-electrons.com/linux/v4.11.4/source/fs/binfmt_elf.c#L1078

[8] http://elixir.free-electrons.com/linux/v4.11.4/source/fs/binfmt_elf.c#L939

[9] http://www.alterawiki.com/wiki/Debug_Kernel

[10] https://stackoverflow.com/questions/29151235/how-to-de-optimize-the-linux-kernel-to-and-compile-it-with-o0

[11] http://cloud-images.ubuntu.com/

[12] https://stackoverflow.com/questions/29151235/how-to-de-optimize-the-linux-kernel-to-and-compile-it-with-o0

Linux ASLR的实现的更多相关文章

  1. 利用Volatility对Linux内存取证分析-常用命令翻译

    命令翻译 linux_apihooks - 检查用户名apihooks linux_arp - 打印ARP表 linux_aslr_shift - 自动检测Linux aslr改变 linux_ban ...

  2. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  3. Linux下的ASLR(PIE)内存保护机制

    1.1    Linux下的ASLR内存保护机制 1.1.1    Linux下的ASLR工作原理 工作原理与window下的aslr类似 1.1.2 Linux下利用内存地址泄露绕过ASLR ⑴.  ...

  4. Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)

    转:https://bbs.pediy.com/thread-217390.htm 前提条件: 经典的基于堆栈的缓冲区溢出 虚拟机安装:Ubuntu 12.04(x86) 在以前的帖子中,我们看到了攻 ...

  5. linux关闭地址空间随机化(ASLR)

    转:http://www.xuebuyuan.com/1571079.html 确认ASLR是否已经被打开,"2"表示已经打开 shanks@shanks-ubuntu:/home ...

  6. Linux (x86) Exploit 开发系列教程之七 绕过 ASLR -- 第二部分

    (1)原理: 使用爆破技巧,来绕过共享库地址随机化.爆破:攻击者选择特定的 Libc 基址,并持续攻击程序直到成功.这个技巧是用于绕过 ASLR 的最简单的技巧. (2)漏洞代码 //vuln.c # ...

  7. Linux Exploit系列之六 绕过ASLR - 第一部分

    绕过ASLR - 第一部分 什么是 ASLR? 地址空间布局随机化(ASLR)是随机化的利用缓解技术: 堆栈地址 堆地址 共享库地址 一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过 ...

  8. 如何判断当前LINUX系统启用了ASLR

    内核参数randomize_va_space用于控制系统级ASLR 0 关闭ASLR 1 mmap base.stack.vdso page将随机化.这意味着.so文件将被加载到随机地址.链接时指定了 ...

  9. Linux Exploit系列之七 绕过 ASLR -- 第二部分

    原文地址:https://github.com/wizardforcel/sploitfun-linux-x86-exp-tut-zh/blob/master/7.md 这一节是简单暴力的一节,作者讲 ...

随机推荐

  1. Spring + MyBatis中常用的数据库连接池配置总结

    Spring在第三方依赖包中包含了两个数据源的实现类包,其一是Apache的DBCP,其二是 C3P0.可以在Spring配置文件中利用这两者中任何一个配置数据源. DBCP数据源 DBCP类包位于  ...

  2. [Domino]从嵌入另一个数据库嵌入的Embedded View无法正常显示,提示unable to lauch

    发现问题 1. 项目中需要在一个数据库中插入另一个数据库的Embedded View,使用起来十分费劲,在选择数据库的下拉菜单中经常会找不到目标数据库: 2. 在做日文版的时候,从workbench导 ...

  3. Python全栈day17(文件处理)

    一,文件处理流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 二,文件打开模式 r只读 (默认打开模式是只读) w只写 a追加 三,文件操作实例 1.r读 read读取文 ...

  4. 字符串与图片的Base64编码转换操作

    //图片 转为 base64编码的文本 private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = ne ...

  5. Spark源码分析 – Shuffle

    参考详细探究Spark的shuffle实现, 写的很清楚, 当前设计的来龙去脉 Hadoop Hadoop的思路是, 在mapper端每次当memory buffer中的数据快满的时候, 先将memo ...

  6. d3.js 之增加感染力:使用转场效果

    转场/transition 图形比数据有感染力,动起来的图形比静态的图形更有感染力. 转场是一种过渡,提供两个稳定状态间的一种动态渐进的变化.转场的概念来源于电影. 电影中存在不同场景之间的切换,比如 ...

  7. Gunner II--hdu5233(map&vector/二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5233 题意:有n颗树,第 i 棵树的高度为 h[i],树上有鸟,现在这个人要打m次枪,每次打的高度是 ...

  8. replace未全局替换的坑

    今天是名副其实的周六.悠闲了一早上(太阳). 真是人在家中坐,BUG自天上来.哈哈其实也不是自天上来,还是自己之前埋下的雷. 所以修复完线上的bug,我脑中立刻浮现出两件还需要做的事情: 一,就是我现 ...

  9. Linux命令(基础2)

    1.命令概要介绍: 查看目录内容:ls 切换目录命令:cd 创建与删除目录:touch(创建文件).rm(移除文件与目录).mkdir(创建目录) 拷贝与移动命令:cp(拷贝).mv(移动) 查看文件 ...

  10. Elasticsearch.js 发布 —— 在Node.js和浏览器中调用Elasticsearch

    继PHP.Ruby.Python和Perl之后,Elasticsearch最近发布了Elasticsearch.js,Elasticsearch的JavaScript客户端库.可以在Node.js和浏 ...