一次版本切换引发的惨案
背景
最近新换了ubuntu的22版本,尝鲜。感觉都还行
膨胀了,觉得可以用来做pwn题,血案开始。
报错
本以为可以像之前每一个版本一样,随便切切
1 | blacktea@blacktea-virtual-machine:~/ctfs/pwn/pig$ xclibc -x ./pig /home/blacktea/tools/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so readelf: Warning: Separate debug info file /home/blacktea/tools/glibc-all-in-one/libs/2.31-0ubuntu9.7_amd64/libc-2.31.so found, but CRC does not match - ignoring |
结果
1 | blacktea@blacktea-virtual-machine:~/ctfs/pwn/pig$ ./pig |
一系列的符号表是找不到的,难受。
这种问题一般是高版本gcc编译的二进制动态文件,放进了低版本环境,导致程序找不到对应版本的函数符号表报错
但是,我本机glibc2.35的版本,程序原本预期运行环境是2.31(是的,可以向下兼容运行,但是一些特性会不一样,我想要的是将二进制文件的运行库切换成2.31的)
不知道盲生有没有发现华点?
我这本来就是高版本,就选切换了低版本,怎么汇报这个错,一时间怎么也没想过来怎么会事
开始找问题。准备一个一个的排除。
预想可能的原因
二进制文件的问题
解决方法:将文件用高版本gcc重新编译
解决效果:开玩笑的呢,源码呢?自己逆码?
环境的问题
解决方法:本地用高版本gcc重新编译一下glibc
解决效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `fstat64@GLIBC_2.33'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_key_create@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_rwlock_unlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_detach@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_setspecific@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libgcc_s.so.1: undefined reference to `_dl_find_object@GLIBC_2.35'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `__libc_single_threaded@GLIBC_2.32'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_join@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_rwlock_wrlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_getspecific@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_key_delete@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `lstat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `stat@GLIBC_2.33'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_once@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_rwlock_rdlock@GLIBC_2.34'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so: undefined reference to `pthread_create@GLIBC_2.34'
collect2: error: ld returned 1 exit status
make[2]: *** [../Rules:215: /home/blacktea/test/glibc-2.31/build/support/links-dso-program] Error 1
make[2]: Leaving directory '/home/blacktea/test/glibc-2.31/support'
make[1]: *** [Makefile:470: support/others] Error 2
make[1]: Leaving directory '/home/blacktea/test/glibc-2.31'
make: *** [Makefile:9: all] Error 2我,2333333~,算了,我放弃,毁灭吧,赶紧的。
我找了些资料
有篇文章说,将二进制文件的符号表给改了(手动的那种)
https://blog.csdn.net/w16212/article/details/126577157
https://cloud.tencent.com/developer/article/1758586
1 | objdump -T tester | grep GLIBC_2.1.* #查看符号表 |
我一看,觉得好有道理,但就是和我情况相反而已(我总不可能把我libc库给改了吧)
其间,当我以为是编译器的问题,顺便还去切换了gcc,然并卵。
查看依赖
1 | blacktea@blacktea-virtual-machine:~/ctfs/pwn/pig$ ldd ./pig |
当我已经将libc.so.6的链接目标给换了,但是报错,我仔细看了看又看,好像明白了。。。
我查看stdstdc++的依赖
1 | blacktea@blacktea-virtual-machine:~/ctfs/pwn/pig$ ldd /lib/x86_64-linux-gnu/libstdc++.so.6 |
直接原因
这是C++写的程序(A代替),会用到libstdc++.so.6
(B)这个库,刚好这个库他又要用到libc.so.6
(C or c)
虽然我们用patchelf更改了二进制文件的链接器(ld)和相应的动态文件(so),但是。。。。。。这就要简单说一下改链接的原理了。
patchelf将二进制文件的动态链接字段(姑且这样理解,里面储存有相应链接库和链接器软链接地址)
也就是说,
我们将A中指向C的地址,改成了别处,但是目前改不了A中指向B的地址。
有没有可能将B中的c的地址也改了?
我试了,电脑直接黑屏(改的是一个库文件,不是普通用户文件,也许同一时刻,很多程序都需要他,还好我命大,及时快照了)
那么,问题怎么解决?
我试过了,C文件可以不受影响。至于C++,我能想到的,要么强行改符号表,要么重新用高版本gcc编译glibc。
如果有人看到这里,说明我还没解决,有好心人知道更好办法的话,请联系一下,求求了。
about里有邮箱。谢谢。