• linux更换题目(可执行文件)libc版本问题


    0x00 前言

    本文主要记录了在做pwn题目由于libc版本问题需要替换ELF文件动态连接libc库的解决方法,此方法同时可以推而广之到linux下的任何ELF文件连接库的修改。

    0x01 如何获取不同的glibc

    获取不同的glibc版本这里建议直接使用现有的开源工具glibc-all-in-one,其比较好的一点是可以下载符号表,同时将符号表存入对应版本libc的.debug文件夹中。

    0x02 为什么要下载对应版本的glibc

    这个问题也是开始一直困扰的疑问,为什么不直接使用手头分发的glibc,设置环境变量LD_PRELOAD=./libc.so.6 ./xxx直接让加载指定的libc执行,而要去下载一个对应版本的glibc重新编译呢?

    首先第一个原因是如果系统中的ld.solibc.so不匹配的话,使用LD_PRELOAD很可能会直接导致程序崩溃,如下所示

    $ LD_PRELOAD=./libc.so.6 ./test
    段错误 (核心已转储)
    

    找到问题所在就可以对应解决问题了,这时候只需要解决执行时候的ld.so的链接就可以了

    $ LD_PRELOAD=/path/to/libc.so.6;
    $ /path/to/ld.so ./test
    

    0x03 使用patchelf修改ELF文件

    上述的方法每一次运行都需要指定环境变量,比较麻烦,这里强烈安利一款工具patchelf来更改ELF中硬编码的ldlibc

    一般 ELF 文件的 lddfile 结果与下面类似,可以看到 libc 等动态库的路径被写死在文件中,而 libc.so.6 是一个符号链接,所指向的文件是真正的 libc。

    $ ldd /usr/local/bin/patchelf
        linux-vdso.so.1 (0x00007ffc497e5000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f2d46aee000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2d4696b000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f2d46951000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2d46790000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f2d46caf000)
    
    $ file /usr/local/bin/patchelf
    /usr/local/bin/patchelf: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=cfa182b059312c4c03e401efc8efe47a373d348c, with debug_info, not stripped
    
    $ file /lib/x86_64-linux-gnu/libc.so.6
    /lib/x86_64-linux-gnu/libc.so.6: symbolic link to libc-2.28.so
    

    我们通过 patchelf 修改 ELF 文件达到加载指定版本 libc。我们先用 --set-interpreter 这个选项来将旧的 ld.so 替换为要加载的 ld.so,然后使用 --replace-needed这个选项将旧的 libc.so 替换成要加载的 libc.so。在使用 --replace-needed 时,第 2 个参数是程序原本的动态库的路径,可以由 ldd $目标文件 得到,第 3 个参数是新的动态库的路径,第 4 个参数为要修改文件的路径。

    这里我们修改 "./patchelf" 这个文件的的 libc.so 和 ld.so。根据上面 ldd 的结果,可以知道 ELF 中的 libc 的路径为 "libc.so.6",所以替换 libc 时所使用的第 2 个参数为 "libc.so.6"

    $ patchelf --set-interpreter /opt/libs/2.27-3ubuntu1_amd64/ld-2.27.so ./patchelf
    $ patchelf --replace-needed libc.so.6 /opt/libs/2.27-3ubuntu1_amd64/libc-2.27.so ./patchelf
    

    然后再用 ldd 和 file 命令查看程序,可以看到 libc 和 ld 都修改成功了。

    $ ldd ./patchelf
        linux-vdso.so.1 (0x00007fff785a0000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb408672000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb4084ef000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb4084d5000)
        /opt/libs/2.27-3ubuntu1_amd64/libc-2.27.so (0x00007fb4080e4000)
        /opt/libs/2.27-3ubuntu1_amd64/ld-2.27.so => /lib64/ld-linux-x86-64.so.2 (0x00007fb408a67000)
    
    $ file ./patchelf
    ./patchelf: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /opt/libs/2.27-3ubuntu1_amd64/ld-2.27.so, for GNU/Linux 3.2.0, BuildID[sha1]=cfa182b059312c4c03e401efc8efe47a373d348c, with debug_info, not stripped
    

    注:本文大部分内容参考看雪富强民主和谐帖子,原链接

  • 相关阅读:
    用nodejs 开发的智能提示
    分布式系统之消息中间件rabbitmq
    理解RESTful架构
    zf框架的思想及学习总结
    php网上支付易宝
    phpstorm使用技巧
    phpstorm使用技巧
    mysql中的数据类型
    CF113D 高斯消元、dp
    bzoj4008: [HNOI2015]亚瑟王 dp
  • 原文地址:https://www.cnblogs.com/Taolaw/p/16281185.html
Copyright © 2020-2023  润新知