zoukankan      html  css  js  c++  java
  • 加深PLT-GOT表机制的理解

    加深PLT-GOT表机制的理解

    之前的一篇讲libc的文章中讲过有关plt-got表的延迟绑定机制,而覆盖got表的方法也早已称为pwn中最常用的技巧之一;但是笔者近期闲来无事对改机制进行了更详细的逆向分析,有了一个更加清晰的图景,借此文分享一下:

    分析就得事必躬亲,自行找一个有libc调用的程序,32位64位皆可,丢进IDA里面去看PLT表,快捷点的方法就是找个call <libc_func>双击函数名一跟,比如我们下面这个例子:

    TIM截图20181112163637

    我们随便找个函数看看,就选exit吧:

    TIM截图20181112164049

    可以看到:PLT表中,exit表项其实是一条jmp指令,这可能和我们的习惯理解有出入,我们习惯思维里面一般感觉表都应该是存一些数据(如地址),但是实际上这里是一个jmp跳板。那么jmp跳到哪呢?就是cs:exit_ptr,最近学了计组才明白这是一个寄存器变址寻址,cs代表一个独立的小代码段(code segment)。

    cs段:

    往往是由单位指令长(32位/64位)整数倍的地址开始,以一系列align对齐伪命令结尾,可能是为了方便寻址吧,具体作用之后有机会再聊,现在只需要了解这两个特点就好。

    在PLT表中,每个jmp跳板其实都是一个cs段,想看的自行看IDA。

    我们现在来看一下plt中jmp跳板项的HEX,以exit为例:

    TIM截图20181112165458

    其中,FF 25代表的就是jmp指令,读者不妨自行看看其他plt表项,每个plt表项的头两个字节都是FF 25;后面的5A 08 20 00是小端序的一个地址偏移,我们刚刚说了此处是寄存器变址寻址,我们现在不妨来看exit的got表:

    TIM截图20181112165831

    可以看到got表地址的小端序是:E0 0F 20 00,与上面的5A 08 20 00的确不同(寄存器变址寻址),我们做个差,算得结果为:0x786,我们到exit的plt项再看,双击jmp cs:exit_ptr中的cs这个词:

    TIM截图20181112170518

    我们看到,cs段的End address正是0x786,这就是通过偏移计算出got表地址的过程(这里还是一个间址寻址)

    好,现在我们去看got表在初始的时候(未绑定的时候)是个什么样子:

    TIM截图20181112191051

    未绑定时,got表的值就是0x201050,这个地址处的东西就是上面的extrn,可见:

    在延迟绑定机制下,第一次调用某个libc函数时(未绑定时),就会执行到上图的位置,进行extrn将libc中相应函数的真实地址扩展进来,扩展的过程实现了将got表项改写为函数的真实RVA,这个过程就叫做“绑定”!

    绑定以后,第二次、第三次再调用这个函数的时候,jmp到的就不是0x201050了,而是jmp到函数的真实地址了!

    有关漏洞挖掘:

    1.我们篡改的都是got表,而从未听说过篡改plt表这种操作,现在了解了plt表项的实质是一个指令后就明白了,代码段根本就不可写。

    2.可供篡改的字节有限时:考虑延迟绑定状态!假如说我们只能获得有限字节数的任意写内存的机会,我们又想要覆盖got表,在某些情形下可能就需要覆盖某些函数的地址高位被随机化的字节,而不是全部字节,目的就是实现当下次调用受害函数时劫持到目标地址,在这种情况下,我们需要考虑在我们进行改写时函数的绑定状态,因为绑定和未绑定时got表中的那个地址值是不一样的,而我们并不是篡改每一个字节!

    谢谢阅读!

  • 相关阅读:
    HDU1041
    HDU1005
    HDU1231
    MYSQL入门总结
    oracle性能问题排查~记一个单实例的问题
    mysql案例~关于mysql的配置文件个人见解
    数据恢复系列~恢复方案制定
    mysql架构解读~mysql的多源复制
    mysql 案例~select引起的性能问题
    遭遇Bad version number in .class file
  • 原文地址:https://www.cnblogs.com/Magpie/p/9948560.html
Copyright © 2011-2022 走看看