一.实验要求
栈溢出+ ret2libc ROP
操作系统:Ubuntu 16.04 64bit
安全机制:不可执行位保护,ASLR(内存地址随机化)
打开安全机制,确保×××能绕过以上安全机制,利用漏洞完成attack,实现基本目标:调用system(“/bin/sh”),打开shell。
二.实验概述
ret2libc(return-into-libc)是一种利用缓冲区溢出的代码复用技术,主要通过覆盖栈帧的返回地址(EIP),使其返回到系统中的库函数,利用库函数中已有的功能来实施attack,而不是直接定位到注入的shellcode。
Linux系统关于缓冲区溢出主要有栈不可执行和ASLR的保护机制。ASLR 可以实现对进程的堆、栈、代码和共享库等的地址在程序每次运行的时候的随机化,大大增加了定位的难度。此外,在Linux64位系统中,函数间传递参数不再以压栈的方式,而是以寄存器方式传递参数。所以,要想在64位Ubuntu系统中实施attack操作,除了要绕过上述两个安全机制外,还需要控制用于传递参数的寄存器。本次attack主要有三个关键点:
1) 栈不可执行→代码复用(ret2libc调用系统函数)
2) ASLR→通过plt和got表获取系统函数的地址
3) 64位系统以寄存器方式传递参数→通过ROP控制寄存器
三.实验环境
Ubuntu desktop 16.04 LTS amd64
Gcc Gdb Python PwnTool
四.实验内容
4.1 漏洞程序
漏洞程序vul.c代码如下,main函数把“Hello ,World”读取到标准输出中,调用vulnerable_function()函数。在vulnerable_function()函数中,申请了128字节的buf,调用read()读取标准输入到buf中,未做边界检查,这就是漏洞所在。
将地址空间随机化打开sudo sysctl –w kernel.randomize_va_space=2
gcc编译漏洞程序,显式指明-z noexecstack,正常运行效果如下图所示:
4.2 attack漏洞程序
4.2.1 获取溢出点位置
为了正确定位溢出点位置,构造如下txt文件。
在gdb调试中运行发现溢出,由于程序使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常,所以程序停在了vulnerable_function()函数中。