面临的窘境

在我做ctfshow的pwn26时,我明明已经设定对了ASLR保护值,但是得不到正确的flag。

关于题目中给出的libc也不会用,于是进行了问题的查询,发现这是一个pwn手经常遇见的问题。

解决问题

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

这个问题也是开始一直困扰的疑问,为什么不直接使用手头分发的glibc,设置环境变量LD_PRELOAD=./libc.so.6 ./xxx

直接让加载指定的libc执行,而要去下载一个对应版本的glibc重新编译呢?

因为ld.solibc.so不匹配可能会导致程序无法运行。

安装及使用glibc-all-in-one

安装

1
2
3
git clone https://github.com/matrix1001/glibc-all-in-one
cd glibc-all-in-one
python3 update_list

查看可下载列表

确保工作目录为glibc-all-in-one

1
cat list

下载glibc

工作目录为glibc-all-in-one

1
./download {你要的版本}

安装及使用patchelf

前置知识

原理:程序相关的libc.sold.so是被硬写到程序中的,你可以使用ldd命令查看

1
2
3
4
5
ldd pwn
linux-vdso.so.1 (0x00007ffe64733000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000079835dbaf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000079835d800000)// libc c标准语言库
/lib64/ld-linux-x86-64.so.2 (0x000079835dbc8000)// 看到ld 动态连接器

patchelf介绍

patchelf是一个用于修改ELF可执行文件和库的小型实用程序。它允许用户更改动态链接器(dynamic linker)和 RPATH(运行时搜索路径),从而方便地调整可执行文件和库的运行环境。patchelf 主要用于 Linux 系统,支持多种 ELF 格式的文件。

关键技术:

  • ELF文件格式:patchelf 主要操作 ELF 格式的可执行文件和库。
  • 动态链接器:允许用户修改可执行文件的动态链接器。
  • RPATH:允许用户修改和调整可执行文件和库的运行时搜索路径。

安装

这一套安装流程的讲解:

克隆项目源码

1
2
git clone https://github.com/NixOS/patchelf.git
cd patchelf

生成构建文件

1
./bootstrap.sh

可能会报错:

1
./bootstrap.sh: 2: autoreconf: not found

进行如下操作:

1
sudo apt install autoconf automake libtool

配置构建环境

1
./configure

编译项目

1
make

运行测试

1
make check

check成功只需要没有error

安装patchelf

1
sudo make install

配置和使用

常用用法

  • 修改ld的地址

    1
    patchelf --set-interpreter ld_addr file_name
  • 修改libc的地址

    • 这里old_libc就是ldd查到的那个ld地址(==>之前)比如:libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6那么就是libc.so.6
      1
      patchelf --replace-needed old_libc new_libc file_name
  • 修改Libc的地址(不太稳定)

    1
    patchelf --set-rpath new_rpath your_file

大部分功能

命令行输入patchelf,会得到(部分):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
syntax: patchelf
[--set-interpreter FILENAME]
[--page-size SIZE]
[--print-interpreter]
[--print-soname] Prints 'DT_SONAME' entry of .dynamic section. Raises an error if DT_SONAME doesn't exist
[--set-soname SONAME] Sets 'DT_SONAME' entry to SONAME.
[--set-rpath RPATH]
[--remove-rpath]
[--shrink-rpath]
[--allowed-rpath-prefixes PREFIXES] With '--shrink-rpath', reject rpath entries not starting with the allowed prefix
[--print-rpath]
[--force-rpath]
[--add-needed LIBRARY]
[--remove-needed LIBRARY]
[--replace-needed LIBRARY NEW_LIBRARY]
[--print-needed]
[--no-default-lib]
[--debug]
[--version]
FILENAME

翻译后是:

  • 设置动态库解析器
  • 设置页大小
  • 设置 DT_SONAME
  • 设置 rpath
  • 删除 rpath
  • 添加允许的 rpath 前缀
  • 打印 rpath
  • 强制使用 rpath
  • 添加需要的动态库
  • 删除需要的动态库
  • 替换旧的动态库为新的
  • 打印帮助信息
  • 不链接默认的动态库
  • 输出调试信息
  • 打印版本号