欢迎光临
我们一直在努力

ret2_dl_runtime_resolve高级栈溢出利用思路

本帖最后由 peiwithhao 于 2022-10-17 19:49 编辑

基础知识
前段时间给堆的基础学的差不多了,今天我们来了解一下高级栈溢出漏洞(因为之前懒,所以栈溢出没学到高级阶段就直接开堆了,这篇文章默认大伙已经掌握栈溢出的基本知识),此漏洞乃妙中妙,基础不扎实的同学可以在读完《程序员的基本修养》动态链接那一章再来观看(这本书对于pwn所需的基本知识讲的十分详细,特别适合想要开始学习二进制漏洞的师傅),如果不是很了解的话也可以接下来往下观看,我会尽量将自己所懂的知识详细解释出来,上面推荐看书也是我的建议而已,也,若大伙懂类似于延迟绑定等基本知识的话就可以掠过我上面所讲。
闲聊就到此为止,我们首先来介绍一下在程序中十分重要的动态链接中延迟绑定的机制。大伙都知道,自从采用动态链接取代静态链接之后,虽然说咱们解决了程序复用的问题,但是动态链接还是有弱于静态链接的地方,那就是动态链接由于是在装载后确定某些符号的地址,这样就导致我们开始运行的时候会存在一个地址解析以及重定位的阶段,而静态链接程序的这一个阶段是在链接过程中就形成的,所以这导致了动态链接程序在运行初期会存在一个地址解析过程,因此会导致速度较静态链接程序慢那么一妞妞,但是相比之于他省下的内存空间来说还是小巫见大巫了。但是程序员们总会对其进行优化,那就是对于函数符号的解析并不是在程序一开始时进行,而是在你第一次使用到这个函数符号时才进行解析,这样就更加省下了很多解析时间,因为在某些程序中,即使里面包含某个函数,但是他自始至终都没使用过,如果我们把它解析了就相当于浪费了时间,这种推迟到我们第一次执行函数的时机也被形象的称为延迟绑定机制。以下程序均默认为32位。

延迟绑定
首先我们得知道,由于动态链接中采用了地址无关代码(PIC),所以我们需要在进行动态重定位的时候需要一个新的表(即GOT表),此表位于程序的.data段中,由于我们采用延迟绑定机制,所以GOT表分离出其中函数的部分,其函数部分又被重新划分为.plt 和.got.plt表,现在我们来看看.plt表的内部结构



可以看到我们的整个plt表结构,他的每个表项有0x10大小,且其中第一个表项也就是0下标位是四个指令,这几个指令在之后再讲,首先我们先看到下面的一系列函数表项,咱们就拿read项来当作例子讲解(此时还没执行过read)。可以看到read表项的第一条指令为:jmp    DWORD PTR ds:0x804a010,即跳转到此地址的值所指向的地方,我们再看看他的值发现就是read@plt的第二个指令的地址,也就是说他从第一个指令跳转到第二个指令8


   
此时咱们分析第二条指令,这个指令可以看出就是将8压栈,这个数字我们过会儿讲解,然后最后一条指令就是:jmp 0x8048370 ,欸是不是很熟悉,对,他就是plt表项的第一项,也就是不存放函数表项的那一项,我在此用plt[0]来进行表示,我们再看看plt[0]的第一个指令这里就要进行一下说明了,这里先给出.plt与.got.plt的结构



咱们可以看到.got.plt的前三个项并不是函数的地址,而是Address of .dynamic、 Module ID、__dl_runtime_resolbe,而咱们的plt[0]首先就是将Module ID压栈,然后再进行jmp到__dl_runtime_resolve中,而我们都知道,假如咱们需要重定位一个函数的地址,咱们需要的是什么呢,无非就是一个lookup()函数,这个寻找函数即为找地址,除了函数,咱们还需要知道咱们本模块的ID好让链接器知道如何定位地址,还需要知道你解析的这个是哪个函数,所以总的来说咱们需要的就是一个函数,两个参数,由于我是在32位前提下进行理解,所以参数都分布在栈上,还记得我么刚刚push的两个值吗,根据从右到左原则,那个8就是我们需要的函数地址偏移,而第二个push的那就是.got.plt上保存的模块ID,而__dl_runtime_resolve函数就是咱们所需要的lookup()函数,他的功能就是将地址填入got表项中,所以在下次咱们调用read的时候当他执行第一条指令,他就会直接运行,而不是跳转到第二条指令。

[C] 纯文本查看 复制代码
PLT0:push *(GOT + 4)jump *(GOT + 8)...read@plt:jmp *(read@GOT)push njump PLT0

相关段基础知识
.dynamic段:
这个段可以说在动态链接过程中至关重要,可以通过他来访问到.dynsym、.dynstr等段,我们先来看看他的结构体

[C] 纯文本查看 复制代码
typedef struct {  Elf32_Sword d_tag;  union {    Elf32_Word d_val;    Elf32_Addr d_ptr;  } d_un;} Elf32_Dyn;

而dynmic段也就是由这个结构体组成的数组来构成,其中d_tag决定了后面d_un的含义,给出具体例子

d_tag类型

赞(0) 打赏
未经允许不得转载:哈哈网 » ret2_dl_runtime_resolve高级栈溢出利用思路

相关推荐

  • 暂无文章

评论 抢沙发

© 2003-2024   哈哈网   网站地图

冀ICP备2023023099号

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续提供更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏