使用电脑浏览效果更佳!
摘要
在学习堆内存管理器ptmalloc,想深入的了解各版本的glibc库在malloc,free中做的判断与安全保护(如double free的检测),挖掘一些glibc的漏洞与绕过手法,深入调试带符号的Glibc版本是有必要的(感觉上),在安装环境过程中,发现百度,Google在这方面的资料是在过于匮乏与过时,在此记录一些我在从下载对应版本Glibc库-> 编译带符号glibc库-> 修改当前程序loader-> gdb的lay src源码窗口调试的过程。
刚入门pwn,说实话做pwn如果把堆内存学号应该是一个分水岭了吧,一年来纠结于提高专业课程的成绩与自己热爱的pwn学习中,断断续续的学,还真把一些知识重复的看了好几遍(看了过一段时间又忘了),也知道在安全方面有一个师傅是真的好(听说德国的工程师是师傅带徒弟的模式),希望有志同道合的朋友一起学习(扣扣:2280986957),也期盼有大佬手下小弟做徒弟-_-
方案介绍
一些google搜索关于源码调试glibc解决方案:
方案一:
安装官方编译好的glibc-dbg带符号调试版本
# 其他版本 https://launchpad.net/ubuntu/+source/glibc/2.21-0ubuntu4 # 如32位,此处安装的是64位 sudo apt-get install libc6-dbg sudo apt-get source libc6-dev # sources.list 中dbkg-src的作用,下载源码 # 参考 https://blog.csdn.net/u012927281/article/details/51289608
显然,此处安装的是根据当前系统自带的glibc版本来安装对应调试版本,并不能自定义的选择glibc版本。此方案适用非安全专业适用也够了。
方案二:
自己选择Glibc版本下载进行编译安装。此方案可以自己选择glibc版本进行编译安装,且不用更改系统默认的glibc库,同时使用多个Glibc库。只需要更改调试程序的rpath即可
此处选择方案二进行安装(实践、,可行)
参考:
带符号Glibc库调试环境
下载版本glibc库
http://ftp.gnu.org/gnu/glibc/
指定安装与源码存放的位置
# 如安装在
/usr/local/glibc/glibc2.23
# 源码存放
/home/thonsun/Desktop/glibc/glibc-2.23/
程序config配置
# 在下载源码的文件夹解压进入源码
# /home/thonsun/Desktop/glibc/glibc-2.23/
mkdir build # 要在新的空的文件夹进行configure配置,存放makefile文件
# configure编译时提示:configure: error: you must configure in a separate build directory
x64的编译配置
CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" ../configure --prefix=/path/to/install # ../configure --prefix=/usr/local/glibc/glibc2.23/x64 我的配置 # touch /usr/local/glibc/glibc2.23/x64/etc/ld.so.conf
x32的编译配置
# 在前面的已经生成64位的情况下,再同保留两个版本的要新建一个build32/,和安装文件夹x32/ # /usr/local/glibc/glibc2.23/x32 # /home/thonsun/Desktop/glibc/glibc-2.23/bulid32 CC="gcc -m32" CXX="g++ -m32" \ CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error" \ CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" \ ../configure --prefix=/usr/local/glibc/glibc2.23/x32 --host=i686-linux-gnu # libc2.21错误 /usr/bin/ld: Relocatable linking with relocations from format elf64-x86-64 to format elf32-i386
安装
# 在root的shell su make && make install
修改loader
他们在程序运行加载的作用:
ELF interpreter:
RPATH:
# ubuntu16.04的更新源
https://blog.csdn.net/lym152898/article/details/79100507
# 安装pathelf
sudo apt-get install patchelf
# pathelf使用 https://nixos.org/patchelf.html
# 修改要调试的程序(推荐使用)
# x64
patchelf --set-interpreter /usr/local/glibc/glibc2.23/lib/ld-linux-x86-64.so.2 --set-rpath /usr/local/glibc/glibc2.23/lib/ double_free
# x32
patchelf --set-interpreter /usr/local/glibc/glibc2.23/x32/lib/ld-linux.so.2 --set-rpath /usr/local/glibc/glibc2.23/x32/lib/ double_free32
# 注:ld-linux-x86-64.so.2为一个编译生成的lib库中的loader的ld-so.2的连接文件,会默认加载当前的libc
效果
检查程序依赖
x64
x32
Double free检查
vim ~/.gdbinit
(gdb)>lay src
directory xxxx
使用docker来承载题目:
参考: https://e3pem.github.io/2018/10/01/%E6%9D%82%E9%A1%B9/%E5%9C%A8docker%E4%B8%AD%E6%90%AD%E5%BB%BApwn%E7%8E%AF%E5%A2%83/ https://github.com/skysider/pwndocker
pwn题选择libc版本
问题:低版本的ld-x.so无法加载高版本的libc-x.so(ld-x.so与libc-x.so的爱恨情仇)
解决:
- 自编译替换challenge binary的ld(loader | interpreter)和libc的加载路径 => patchelf
- 采用docker容器运行challenge binary,使用gdb远程attach
参考解决:
http://look3little.blogspot.com/2017/12/debug-symbolglibc.html
https://bbs.pediy.com/thread-225849.htm
http://brieflyx.me/2018/linux-tools/handling-so-hell/
https://www.cnblogs.com/xingzherufeng/p/9682660.html
# 过时的用法
1. LD_PRELOAD=/usr/local/glibc/glibc2.21/x64/lib/libc.so.6 /usr/local/glibc/glibc2.21/x64/lib/ld-2.28.so ./binary
2.export LD_LIBRARY_PATH=`/usr/local/glibc/glibc2.21/x64/lib` #当前目录为加载目录
export LD_PRELOAD=/usr/local/glibc/glibc2.21/x64/lib/libc.so.6 #你的libc #加载本地pwn题目下的libc
最后不用了在:unset LD_PRELOAD #调试完记得删除环境变量