★pwn 更改pwn题libc保姆级教程★
★pwn 更改pwn题libc保姆级教程★
- 🍚前言
- 🥟安装
- 🥟glibc-all-in-one下载与调整libc
- 🥟patchelf更改libc
- 🥟clibc的使用与分析
🍚前言
现在市面上有很多关于改libc的教程,但是基本有以下几个问题:没有符号表、错误、过时、繁琐、高版本不适用。于是我找了一种最简单并且全libc通用的方法。现分享如下。
🥟安装
在开始前,需要安装一下本文所需软件
glibc-all-in-one
cd ~/
git clone https://github.com/matrix1001/glibc-all-in-one
cd ~/glibc-all-in-one
sudo python3 update_list
cd ..
patchelf
sudo apt install patchelf
clibc
cd ~/
git clone https://github.com/dsyzy/free-libc
cd ~/free-libc
sudo sh ./install.sh
cd ..
🥟glibc-all-in-one下载与调整libc
先确定好题目的libc是多少,题目可能没给libc,需要泄露获得,这不在本教程的考虑范围内。如果题目给了libc,可以通过以下命令来获得libc版本
strings libc.so.6 | grep ubuntu
其中,libc.so.6是libc的文件名,后面的ubuntu如果找不到这个字符串也可以找Ubuntu等等
这里可以看到libc版本是2.23-0ubuntu11.3
cat list
cat old_list
接下来进入glibc-all-in-one,命令cat list可以看到所有能够下载的libc版本,命令cat old_list可以看到不经常使用的libc版本。接下来下载2.23-0ubuntu11.3_amd64
./download 2.23-0ubuntu11.3_amd64
输入该命令即可下载,下载完成后,会保存在libs目录中
进入刚刚下好的2.23libc目录中,将能够看见隐藏文件打开
接下来能看到这个.debug目录,这个目录中保存了该libc的符号表信息
接着依次进入.debug,lib,x86_64-linux-gnu目录下,找到libc-2.23.so文件
将这个文件,放到.debug目录的根目录下。当然,其实也可以把那些文件全部拖到这里来。这里简洁一些
这样,就可以在不用动用gdb的命令情况下,patchelf更改好文件libc后,gdb打开文件,直接就能加载好符号表,非常方便。这是最关键的一步
2.31后大更改了一下符号表,2.31中,07这个目录中的debug文件是要找的,将这个文件放在.debug目录的根目录下即可
如图所示
2.34后的又有些许不同,不是在07这个目录中了,具体在哪个目录中我也没有尝试,而是采用全部复制到.debug根目录的方式。
下个2.35的libc,进入这里,接下来要将这些目录中的所有文件放到.debug目录的根目录下,命令是:
cp ./*/* ../
解释一下该命令。./*/*是要复制的内容,. ./是复制到这里去。./代表当前目录,. ./代表上一级目录,/*是指将该目录下的所有文件,而不包括该目录。连续两个杠星,先是将.build-id目录下的所有文件指定,再将每个文件看作目录,再指定每个目录下的文件而不复制目录。这个过程稍微有点复杂,大概的意思能理解即可
效果如上,即算复制成功
接下来利用patchelf更改libc,可以先准备好与libc适配的题目,像我之前发的文章中就给了题目,Lit CTF 2024,Litctf 2024中有2.23,2.27,2.31,2.35,2.39这5个版本的heap题目,本文用的就是这些题目
🥟patchelf更改libc
我个人习惯将2.23的libc文件直接从glibc-all-in-one中拖过来,等会改的时候比较方便
2.23的libc,输入命令:
patchelf heap --set-interpreter ./2.23-0ubuntu3_amd64/ld-2.23.so --set-rpath ./2.23-0ubuntu3_amd64
如上图,即可更改成功,可以用ldd查看
其中,–set-interpreter是设置ld,指定目录下的ld文件,–set-rpath设置了运行环境,指定libc的目录
gdb运行后,就能看到识别符号表成功
2.35以上略有不同,因为ld换成了默认的,没有具体的版本名了
patchelf heap --set-interpreter ./2.35-0ubuntu3.8_amd64/ld-linux-x86-64.so.2 --set-rpath ./2.35-0ubuntu3.8_amd64
加载符号表成功
🥟clibc的使用与分析
有人还嫌patchelf改的麻烦,命令太长,怎么办呢?可以写一个bash脚本来解决,github上已经有大佬写了一个脚本叫clibc,原理就是利用了patchelf的–set-interpreter和–set-rpath两个命令
接下来对这个bash脚本分析一下
打开.sh安装文件,开始自动下载了一下patchelf防止你没有,然后下载到了/usr/local/bin中,去那里看一下
找到clibc文件,可以看到确实是用的patchelf这两个命令,不过有瑕疵,因为这个脚本写的时间比较早,所以他脚本写的是ld-$LIBC_VERSION.so,而上文讲到了,libc在2.34后更改了ld的名称,统一叫ld-linux-x86-64.so.2,所以如果是要用clibc改2.34以上的libc会失效,导致文件打不开。因此稍微修改一下该脚本即可:
if [ "$3" ];then
if [[ "$LIBC_VERSION" > "2.33" ]];then
patchelf --set-interpreter $libc_dir/ld-linux-x86-64.so.2 --set-rpath $WORKDIR/ $1
else
patchelf --set-interpreter $libc_dir/ld-$LIBC_VERSION.so --set-rpath $WORKDIR/ $1
fi
elif [[ "$LIBC_VERSION" > "2.33" ]];then
patchelf --set-interpreter $libc_dir/ld-linux-x86-64.so.2 --set-rpath $libc_dir/ $1
else
patchelf --set-interpreter $libc_dir/ld-$LIBC_VERSION.so --set-rpath $libc_dir/ $1
fi
echo "success!!!"
我不是很会写bash脚本,改的比较乱,不过能用就行,如果检测到输入的libc版本大于2.33,就会用ld-linux-x86-64.so.2,具体libc是在哪个版本用的ld-linux-x86-64.so.2我没测,问题不大,一般是用2.31和2.35,不会用到32或33
使用前需要先将libc目录从glibc-all-in-one中拖到/usr/lib/freelibs/amd64这个目录中,64的就在amd64,如果是32的,就是拖到/usr/lib/freelibs/i386中
clibc heap 2.35
输入这个命令即可更改,其中,heap是你要更改的文件名,2.35是指定的libc版本,可以看到上图已经更改成功了
本教程到此就结束啦,本文所述方法目前应该是全网唯一,如果你有更好的换libc的方法或者之前就有人说过我这个方法的,欢迎在评论区留个坐标。如果按照上述方法来做出现了问题,例如没有符号表等,可以在评论区留言,我看到了就一定会回复的!