更换可执行文件的 glibc 版本
准备学堆了, 不同版本的 glibc 对于堆的管理稍有不同 (比如高版本可能增加了一些补丁, 使得某些漏洞无法利用). 由于需要本地调试, 所以得先学一下怎么更换 glibc 版本.
glibc-all-in-one
https://github.com/matrix1001/glibc-all-in-one
首先得先下载对应版本的 glibc 吧. 这个工具非常方便.
对着 readme 照猫画虎就行.
download
文件中可以把清华镜像源换成 ubuntu 源.他会把相应的 deb 包下载到 ./debs/
下, 然后解压到 ./libs/
文件夹下.
其中, 我们需要的是 libc.so.6
和 ld-linux.so.2
. 这两个文件是符号链接, 可以把他们复制到题目文件夹下, 便于后续工作.
patchelf
https://github.com/NixOS/patchelf
可执行文件把链接器路径写死在 ELF 文件中了, 所以当指定其他 glibc 版本时, 连接器版本也需要指定, 否则会发生错误.
使用 patchelf 工具进行.
假设当前题目文件夹下有之前复制过来的 libc.so.6
和 ld-linux.so.2
, 以及题目 (ELF) pwn
(建议备份一下).
乐, 这样 rizin 调试的时候输出不了堆, 原因 rizin 找 glibc 的时候文件名要有 -
, 而 libc.so.6
没有, 离谱. radare2 有这个 issue, 好像已经解决了, rizin 没有看到.
既然如此, 就直接设置到 glibc-all-in-one 的 /libs
对应的文件夹下, 不复制出来了.
首先设置连接器:
|
|
然后设置运行路径 (RUN_PATH, rpath), 也就是程序所使用的共享库路径:
|
|
或者写成一行:
|
|
比如:
|
|
可以用 ldd
查看连接器, file
查看共享库来检查修改成功与否.
有空写个脚本一键操作 (或者找师傅们要一个). github 上找到了两个, 效果貌似都不怎么样.