Linux ASLR的实现
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
[11] http://cloud-images.ubuntu.com/
Linux ASLR的实现的更多相关文章
- 利用Volatility对Linux内存取证分析-常用命令翻译
		命令翻译 linux_apihooks - 检查用户名apihooks linux_arp - 打印ARP表 linux_aslr_shift - 自动检测Linux aslr改变 linux_ban ... 
- Linux 驱动开发
		linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ... 
- Linux下的ASLR(PIE)内存保护机制
		1.1 Linux下的ASLR内存保护机制 1.1.1 Linux下的ASLR工作原理 工作原理与window下的aslr类似 1.1.2 Linux下利用内存地址泄露绕过ASLR ⑴. ... 
- Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)
		转:https://bbs.pediy.com/thread-217390.htm 前提条件: 经典的基于堆栈的缓冲区溢出 虚拟机安装:Ubuntu 12.04(x86) 在以前的帖子中,我们看到了攻 ... 
- linux关闭地址空间随机化(ASLR)
		转:http://www.xuebuyuan.com/1571079.html 确认ASLR是否已经被打开,"2"表示已经打开 shanks@shanks-ubuntu:/home ... 
- Linux (x86) Exploit 开发系列教程之七 绕过 ASLR -- 第二部分
		(1)原理: 使用爆破技巧,来绕过共享库地址随机化.爆破:攻击者选择特定的 Libc 基址,并持续攻击程序直到成功.这个技巧是用于绕过 ASLR 的最简单的技巧. (2)漏洞代码 //vuln.c # ... 
- Linux Exploit系列之六 绕过ASLR - 第一部分
		绕过ASLR - 第一部分 什么是 ASLR? 地址空间布局随机化(ASLR)是随机化的利用缓解技术: 堆栈地址 堆地址 共享库地址 一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过 ... 
- 如何判断当前LINUX系统启用了ASLR
		内核参数randomize_va_space用于控制系统级ASLR 0 关闭ASLR 1 mmap base.stack.vdso page将随机化.这意味着.so文件将被加载到随机地址.链接时指定了 ... 
- Linux Exploit系列之七 绕过 ASLR -- 第二部分
		原文地址:https://github.com/wizardforcel/sploitfun-linux-x86-exp-tut-zh/blob/master/7.md 这一节是简单暴力的一节,作者讲 ... 
随机推荐
- vue mixins的使用
			官网传送 刚开始接触vue的时候,官网关于mixins的例子看了好几遍,发现还是不会用,包括vuex也是后来慢慢理解一点的,不过和vuex比起来.mixns还是很好理解,简单很多了 就我目前理解mix ... 
- 关于navicat 系列软件一点击菜单栏就闪退
			navicat 系列软件一点击菜单栏就闪退 多次卸载安装都出现了闪退的现象 后来发现,原来是启动了有道词典屏幕取词才会出现这种现象,关了有道就没事. 
- Web测试系列之测试方法
			一.输入框 1.字符型输入框: (1)字符型输入框:英文全角.英文半角.数字.空或者空格.特殊字符“~!@#¥%……&*?[]{}”特别要注意单引号和&符号.禁止直接输入特殊字符 ... 
- Servlet的请求转发和重定向
			在学习servlet中对于转发和重定向的理解是非常重要的,但是常常把重定向和转发给混了,今天特地花点时间来总结以下. 一.servlet的转发 1.请求原理图如下所示: 2.可以简单理解转发就好比一 ... 
- linux查看硬件信息的方法
			目前会Linux的人不少,但是精通的不多,怎样才能做一个符合企业需求的Linux人才,首先要有良好的Linux基础知识.本文为你讲解Linux的知识,今天所讲的是 Linux硬件信息怎样查看,希望你能 ... 
- Apache Samza - Reliable Stream Processing atop Apache Kafka and Hadoop YARN
			http://engineering.linkedin.com/data-streams/apache-samza-linkedins-real-time-stream-processing-fram ... 
- 《从零開始搭建游戏server》项目公布到Linux环境
			前言: 之前我们提及了怎样使用Maven来创建.管理和打包项目,也简单过了一遍Linux中搭建Java开发环境的步骤,如今我们就開始将我们之前开发的项目demo公布到Linux环境下.并让它正常执行起 ... 
- C#的Installer生成的msi的安装文件,安装新版本时提示:已经安装了该产品的另一个版本。无法继续安装此版本
			之前折腾了个C#的项目: WLW (Windows Live Writer) Plugin–InsertSkydriveFiles 然后又弄了个对应的Installer: [已解决]给一个C#的Dll ... 
- FB05付款清帐Function
			函数组:FIPI-->内部FI过帐接口1.CALL FUNCTION 'POSTING_INTERFACE_START'. -->Initial information for inter ... 
- PHP计算经纬度之间的距离
			<?php /** * 求两个已知经纬度之间的距离,单位为米 * * @param lng1 $ ,lng2 经度 * @param lat1 $ ,lat2 纬度 * @return floa ... 
