首页
社区
课程
招聘
[翻译]Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)
发表于: 2017-4-18 09:25 13685

[翻译]Linux (x86) Exploit 开发系列教程之六(绕过ASLR - 第一部分)

2017-4-18 09:25
13685

前提条件:

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

虚拟机安装:Ubuntu 12.04(x86)

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

      堆栈地址(跳转到shellcode)

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

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

什么是 ASLR?

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

       堆栈地址

       堆地址

       共享库地址

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

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


其中

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

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

现在当我们打开完全随机化(使用下面的命令)

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使用这个表来重新定位具有两级间接的功能地址。

    


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 2
支持
分享
最新回复 (13)
雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
2
不知不觉已经翻译了一半了~
2017-4-18 11:38
0
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
3
飞龙使者 不知不觉已经翻译了一半了~
是啊,可惜没人高兴翻译,不然我就不用这么麻烦了。
2017-4-18 13:18
0
雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
4
那个“where”不是”哪里“,而是“其中”
2017-5-3 10:31
0
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
5
飞龙使者 那个“where”不是”哪里“,而是“其中”
ok,我修改一下
2017-5-3 10:52
0
雪    币: 93
活跃值: (369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6

请教下,strcpy的溢出,plt表地址是带0的,这个怎么ROP?

LOAD:0000A334     ; int system(const char *command)

2017-5-24 01:17
0
雪    币: 704
活跃值: (228)
能力值: ( LV12,RANK:230 )
在线值:
发帖
回帖
粉丝
7
lcys 请教下,strcpy的溢出,plt表地址是带0的,这个怎么ROP?LOAD:0000A334     ;&am ...
换成`strncpy`,`strlcpy`,`sprintf`或者`snprintf`。
2017-5-24 08:39
0
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
8
lcys 请教下,strcpy的溢出,plt表地址是带0的,这个怎么ROP?LOAD:0000A334     ;&am ...
我也很菜鸟,这个没关系啊,只要找到上面的plt地址往上面的poc样本填就行了
2017-5-24 08:48
0
雪    币: 24
活跃值: (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
堆的那一块挺复杂的  呵呵  还没翻译呢 
2017-5-29 16:56
0
雪    币: 93
活跃值: (369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
hackyzh 我也很菜鸟,这个没关系啊,只要找到上面的plt地址往上面的poc样本填就行了
plt地址高位是0,strcpy遇到0结束了,只能控制一个栈,不知道这样怎么构造ROP链?
2017-6-5 17:50
0
雪    币: 1746
活跃值: (227)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
11
你的plt的地址是不是没找对啊,gdb反汇编可以直接找到的。
2017-6-7 14:05
0
雪    币: 203
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
好文,正在研读
2017-6-28 22:58
0
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
great,谁说缓冲区溢出已死?never  end!!!
2017-7-30 11:37
0
雪    币: 96
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
function@PLT貌似aslr作用下加载基地址也会变化,这个利用方式有作用吗,可否说说
2017-12-10 22:40
0
游客
登录 | 注册 方可回帖
返回
//