首页
社区
课程
招聘
[原创]关于不同版本 glibc 更换的一些问题
发表于: 2019-10-4 18:24 56658

[原创]关于不同版本 glibc 更换的一些问题

2019-10-4 18:24
56658

在做 pwn 题时,更换 ELF 文件的 libc 版本一直让人头疼,所以写文记录关于 glibc 的下载,替换,调试的一些问题。

通过镜像源可以下载到常见版本的 glibc 及其符号表。

通过 Ubuntu 的 old-releases 镜像站 或者 清华的镜像站 可以下载到不同版本的 glibc。然后通过 dpkg -x *.deb 来解压 deb 包得到 libc。

当然也可以通过 Debian 等发行版的镜像源来下载 glibc。

有两个项目可以实现自动下载 libc:https://github.com/niklasb/libc-databasehttps://github.com/matrix1001/glibc-all-in-one,前者不会下载符号表,而后者会将符号表存入对应 libc 的 ".debug" 文件夹中。

因为 ld.so 和 libc.so 不匹配的原因,所以直接设置 LD_PRELOAD 可能会炸,就如下所示...

可以将配套的 ld 和 libc 一起使用即可实现动态加载 libc。只需将下面代码中 LD_PRELOAD 后面的 "/path/to/libc.so.6" (要加载的 libc 的路径)和第二行的 "/path/to/ld.so" (要加载的 ld 的路径)替换成相应文件的路径就行了。

在 pwntools 启动程序时,可以按照下面的代码进行设置。

在 github 上有一个项目叫 patchelf,通过这个项目可以实现修改 ELF 中硬编码的 libc 和 ld 的路径。

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

我们通过 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"

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

我写了个简单脚本,使用 "patchelf" 给 ELF 文件 Patch 上 "glibc all in one" 下载的 libc。将下面脚本以 "chlibc.sh" 保存后,只需要使用 ./chlibc.sh $libc所在目录 $目标文件 就能修改 libc 了。例如 ./chlibc.sh /opt/libs/2.23-0ubuntu10_i386 echo3 就是将 "echo3" 这个 ELF 文件的 libc 和 ld 换成 /opt/libs/2.23-0ubuntu10_i386 这个目录下的 libc 和 ld。

需要注意的是 patchelf 可能会有 Bug,所以使用从 Github 上的代码进行编译得到的 patchelf 能避开一些 Bug。

在看 LIEF 文档时发现了一篇老外的博文,讲的是通过 LIEF 来使用不是系统自带的 libc。

如果只是直接 Patch 了 ELF 文件的 ld 和 libc,而没有放置符号表的话,那么在使用 GDB 调试的时候就不容易看到 libc 中的各种结构。所以我们需要加载符号表来方便调试。

Ubuntu 的软件维护者在编译对应的 ELF 文件时,会将符号表与 ELF 文件分离,将符号表命名为 "*-dbg.deb"。这样我们就可以通过手动下载符号表来方便调试。

如果是使用 "glibc all in one" 下载的 libc,会在 libc 等库放置的位置使用 ".debug" 文件夹存放好了 libc 的符号表,使用 gdb 可以自动加载。但是碰到 "glibc all in one" 没有的 libc 版本时就需要手动下载 debug 文件,并手动加载了。

在放置 libc 的目录下新建 ".debug"文件夹,将 debug 文件放入其中即可。原理见参考文章 2,glibc 的官方文档。

在参考文章1可以看到关于 gdb 如何加载分离的 debug 文件,我们只要将 libc 等库的 debug 文件放入对应文件夹,并通过 set debug-file-directory $directories 命令将文件夹设为分离的 debug 文件目录,就可以让 gdb 加载 debug 文件。

gdb 的 python api 中有一个Objfile.add_separate_debug_file (file)来让对应的二进制文件加载分离的 debug file,这里我将其封装成了命令,在程序运行起来后通过修改下面的命令即可加载。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2020-3-19 01:45 被富强民主和谐编辑 ,原因: 丰富细节,增加说明
收藏
免费 18
支持
分享
最新回复 (15)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这么好的文章居然没人留言。。。
2019-12-25 14:45
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
推荐个工具是pwn_debug  https://github.com/ray-cp/pwn_debug
2019-12-25 14:48
0
雪    币: 207
活跃值: (96)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好文章,支持一下!
2020-3-18 21:19
0
雪    币: 1187
活跃值: (123)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
专门注册了一个账号就是为了赞你
2020-8-17 17:24
0
雪    币: 11
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
00D
6
很有用啊,救了我
2020-9-25 23:11
0
雪    币: 290
活跃值: (193)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
好文,不过我在实践的时候发现文章提到的结合pwntool的用法
p = process(["/path/to/ld.so", "./test"], env={"LD_PRELOAD":"/path/to/libc.so.6"})
会导致system执行出错。
patchelf的方法不会。
2020-10-9 15:45
1
雪    币: 220
活跃值: (123)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
wx_LONELYGOD 好文,不过我在实践的时候发现文章提到的结合pwntool的用法 p = process(["/path/to/ld.so", "./test"], env={ ...
同问,想知道为什么会这样
2020-10-27 10:37
0
雪    币: 188
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
非常感谢大佬啊,一直在寻找更好libc后gdb无法识别的问题的解答
2021-1-10 23:53
0
雪    币: 234
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
已经有一个libc-2.19.so的文件 能否得到对应的版本 对应ld的版本呢
2021-2-22 01:28
0
雪    币: 4168
活跃值: (15932)
能力值: ( LV9,RANK:710 )
在线值:
发帖
回帖
粉丝
11
很有用的实用技巧,支持!
2021-2-23 22:59
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12

感谢楼主


最后于 2021-3-30 23:54 被kr0emer编辑 ,原因:
2021-3-15 16:54
0
雪    币: 27
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
不知道楼主和各位大佬有没有遇到过这种问题,我最近重编了一个libc2.23,用里面的loader去加载以前2.23题目给的libc,会segfault,这是为啥呢
2021-4-13 02:43
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
好文顶一下
2021-10-31 10:24
0
雪    币: 164
活跃值: (1024)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
a3uRa 已经有一个libc-2.19.so的文件 能否得到对应的版本 对应ld的版本呢
strings <libc.so文件> | grep 'ubuntu'命令会显示要用的ld版本
2023-12-29 08:31
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
师傅讲的十分详细!!!感谢!
2024-10-16 17:02
0
游客
登录 | 注册 方可回帖
返回
//