首页 > 其他分享 >二进制漏洞挖掘与利用-第二部分

二进制漏洞挖掘与利用-第二部分

时间:2023-11-11 21:00:44浏览次数:38  
标签:plt 函数 二进制 挖掘 漏洞 地址 调用 动态链接库 got

二进制漏洞挖掘与利用-第二部分

1. ROP概念

    ROP全名为:返回导向编程
    ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。
    当你想要执行一段攻击代码(代码)时,发现这段代码不是连续的,那么你就可以操控eip来不断地执行分离的片段(gadget),最终达到执行攻击代码的目的。(ROP)
    参考:
    https://www.yijinglab.com/html/news/news.html?newsId=NEWS-3fa-bbe4-4014-802a-21cafc832a7d
    ROP就是通过寻找gadget,进行组合(跳转),最终达成攻击的这样的一种思想。
    gadget一般都是以ret结尾的代码片段,方便进行跳转。
    查找pop或者ret的指令片段。
    ROPgadget --binary ret2syscall --only "pop|ret"

2. 系统调用

2.1 系统调用的定义

    操作系统提供给用户的编程接口
    是提供访问操作系统所管理的底层硬件的接口
    本质上是一些内核函数代码,以规范的方式驱动硬件。
    x86 通过 int 0x80 指令进行系统调用
    amd64 通过 syscall 指令进行系统调用

2.2 执行系统调用的流程

    假设你想写一个my_puts()函数,将数组当中的信息输出到屏幕上,那么你应该在函数内部调用了动态链接库当中的write()函数。
    假设你已经完成了这个操作,接下来我们来讲述一下具体的流程。
    首先,main函数调用my_puts("Hello World!")函数,随后进入到my_puts("Hello World!")函数,执行到了write(1,&"Hello world!",12)函数,由于该函数是动态链接库当中的函数。因此,程序执行流会导向虚拟内存当中的shared libraries区域中,寻找这个函数。
    找到这个函数之后,这个函数会执行内部封装好的系统调用sys_write()函数。只不过在系统调用前,会先传递sys_write()的系统调用号到eax中(假设为4),然后会将参数一一传递到ebx,ecx等寄存器中。(ebx = 1;ecx = &"Hello World!";edx = 12)
    传递完之后,会执行int 0x80(int本质上是中断,x86通过中断来进行系统调用(0x80代表是系统调用)) 来启动这个系统调用(sys_write())。
    启动完系统调用后,在执行系统调用时(内核代码),操作系统就会将字符串显示到屏幕上。
    所以说:系统调用通常都会封装在库函数(并不是所有)中,当用户调用库函数时,实际上是执行了系统调用,让操作系统驱动硬件来完成用户的需求。
    补充:
        1.  ldd命令,查看一个可执行文件的所有的动态链接库。
        2.  动态链接库装载器会将一个二进制文件需要的所有动态链接库装载到虚拟内存当中的shared libraries 区域当中。 
        3.  一个动态链接库装载器:
            /lib64/ld-linux-x86-64.so.2
        4.  动态链接库装载器是不会有漏洞的。
        5.  动态链接库也是一个可执行文件。执行它会输出动态链接库的相关信息。
        6.  execve()系统调用会执行第一个参数当中的命令(以字符串形式)。
        7.  system()函数内部封装了execve()系统调用。
        8.  系统调用本质上就是一堆指令的集合。

3. ROP详解

3.1 ROP的执行流程

img

    假设,我们通过栈溢出,将返回地址之上的内容进行了覆盖(一系列gadget的地址)。
    首先,我们执行ret,ret的作用是将栈顶的值给到eip。此时,eip = 0x08052318。同时,esp + 1(字长)。此时,eip到达了图上的位置。

img

    此时,执行pop %edx。这条指令的作用是将栈顶的值给到edx寄存器中。此时edx = value。esp + 1。
    再执行ret指令,该指令的作用就是将栈顶的值给到eip,esp + 1。 eip = 0x0809951f,此时eip到达了图上的位置。

img

    将eax寄存器的值和自身进行异或,最终的结果为将eax的值清0。
    执行ret,此时eip = 080788c1,esp + 1。此时eip到达了图上的位置

img

    将eax寄存器的值给到edx寄存器
    执行ret,此时eip = 0x41414141,esp + 1。

4. 动态链接

4.1 静态链接与动态链接的区别

    1.  如果对同一个.c文件进行编译,静态链接比动态链接占用的空间大。
    2.  静态链接会将ELF文件所需要的所有库函数(完整实现)全部都写到ELF文件本身(位于.text节)。动态链接会将ELF文件所需要的库函数进行标记(符号),当使用时,在从对应的动态链接库中进行调用(需要.plt节解析库函数在内存中的真实地址,然后再根据该地址进行调用)(此时动态链接库也在内存(shared libraries区域))。

img

4.2 动态链接相关结构

    1.  .dynamic节提供了动态链接的相关信息
    2.  link_map保存了进程载入的动态链接库的链表。
    3.  dl_runtime_resolve:装载器中用于解析动态链接库中函数的实际地址的函数(仅在第一次调用库函数时执行(.plt会调用它),之后会将解析后的真实地址保存在.got.plt节中)。
    4.  .got节为全局偏移量表,保存了整个程序虚拟地址空间中各个符号所需的全部的偏移量(地址)。
    5.  .got保存的是变量的地址,.got.plt保存的是函数的地址。
    6.  .plt和.got.plt会保存到代码段中。
    7.  .plt是一个表(每一个表项对应着动态链接的库函数),.got.plt仍是一个表(每一个表项对应着动态链接的库函数的真实地址)。
    8.  当第一次调用时,.got.plt还没有该函数的真实地址。此时存放的是.plt表项的首地址的下一个地址。因此,如果没有,会直接跳回该表项的下一条语句。

img

4.3 动态链接过程

img

    假设我们已经编写好了一个程序,该程序的内部调用了动态链接库的foo函数。那么,接下来我们来详细解释一下程序调用foo函数时都发生了什么?

img
img

    此时会跳转到.plt中的foo表项,执行该表项内的汇编代码。首先,.plt中的代码会立即跳转到.got.plt中记录的地址。

img

    但是,由于进程是第一次调用foo,因此.got.plt中记录的地址是.plt表项中首地址的下一个地址。因此会跳回到.plt表项中,执行push index。

img

    接下来会执行jmp PLT0

img

    接下来会执行push *(GOT + 4)
    以上的push的两个值均为解析真实地址的函数的参数。
    index代表你要解析的是.plt表项的第几个函数。(索引)
    第二个参数代表你要从第几个动态链接库中找到这个库函数?

img

    之后跳转到dl_runtime_resolve函数,开始解析真实地址。

img
img

    解析之后,会填入到.got.plt的对应表项中。
    之后就可以按照真实地址调用库函数了。

img
img

    等到第二次解析时,就可以直接通过.plt表项再到.got.plt获取到该库函数的真实地址。之后执行即可。

img

    上图为第一次调用foo函数的情况。

img

    上图为第二次调用foo函数的情况。

img

    补充知识点:
        1.  .init节存储着初始化的相关代码。(只在动态链接中存在)
        2.  在pwndbg中我们可以使用plt命令来查看plt的内容,got命令来查看got表的内容。

标签:plt,函数,二进制,挖掘,漏洞,地址,调用,动态链接库,got
From: https://www.cnblogs.com/gao79135/p/17813832.html

相关文章

  • 二进制漏洞挖掘与利用入门
    二进制漏洞挖掘与利用1.pwn概述及基本术语补充1.1pwn概述pwn可以指:1.破解、利用成功(程序的二进制漏洞)2.攻破了设备、服务器3.控制了设备、服务器(简单理解)pwn漏洞指的就是:已经编译成机器码的二进制程序(可执行程序)相关的漏洞。1.......
  • C++ 采用read()和write()读写二进制文件
    以文本形式读写文件和以二进制形式读写文件的区别,并掌握了用重载的>>和<<运算符实现以文本形式读写文件。在此基础上,本节继续讲解如何以二进制形式读写文件。举个例子,现在要做一个学籍管理程序,其中一个重要的工作就是记录学生的学号、姓名、年龄等信息。这意味着,我们需要用一个......
  • 域名遍历子域名挖掘机layer
    c端攻鸡,攻记二级域名拿到账号密码,然后做横向或者向上级渗头。敏感的比如beta、account、static、mai12如比static可能是别人默认缓存页面,点进去的话可能不用授权,直接就点进去了。web服务器是根据beta返回的内容截取出来的。木板原理,刚好有一个页面有漏洞,基于这个页面进行......
  • Linux软件包(源码包和二进制包)
    Linux下的软件包众多,且几乎都是经GPL授权、免费开源(无偿公开源代码)的。这意味着如果你具备修改软件源代码的能力,只要你愿意,可以随意修改。GPL,全称GeneralPublicLicense,中文名称“通用性公开许可证”,简单理解GPL就是一个保护软件自由的一个协议,经GPL协议授权的软件必须开源......
  • QEMU CVE-2021-3947 和 CVE-2021-3929 漏洞利用分析
    QEMUCVE-2021-3947和CVE-2021-3929漏洞利用分析‍CVE-2021-3947信息泄露漏洞漏洞分析漏洞点是nvme_changed_nsliststaticuint16_tnvme_changed_nslist(NvmeCtrl*n,uint8_trae,uint32_tbuf_len,uint64_toff,Nvm......
  • 文件上传漏洞总结
    文件上传漏洞总结0x00原理文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。“文件上传”本身没有问题,有问题的是文件上传后,......
  • Java圈高危安全漏洞
    主要高危漏洞:1、fastjson-1.2.78报告网址:https://devhub.checkmarx.com/cve-details/CVE-2022-25845/风险指数:9.8/10解决方式:升级版本至1.2.832、spring-web:5.2.9.RELEASECVE-2016-10000279.8DeserializationofUntrustedDatavulnerabilityCVE-2021-221187.8Imprope......
  • XXE漏洞与有回显的XXE
    XXE漏洞与有回显的XXEXXE:XML外部实体注入(xmlexternalentity),可造成文件读取,命令执行等攻击HTML侧重页面外观,XML侧重数据与存储XML没有预定义标签,可以自定义,通常用DTD(文档类型定义)规范XML的格式定义DTD的方式:内部DOCTYPE声明外部文档声明(重点)内部声明不能读文件,外部声明......
  • Java Fastjson反序列化漏洞研究
    一、Fastjson简介Fastjson是阿里巴巴的一个开源项目,在GitHub上开源,使用Apache2.0协议。它是一个支持JavaObject和JSON字符串互相转换的Java库。Fastjson最大的特点在于它的快速,它超越了JackJson、Gson等库。据官方发布的说明,Fastjson从2011年fastjson发布1.1.x版本之后,其性能......
  • java基础学习:二进制,八进制,十六进制
      ......