本文实验环境:windows10虚拟机VirtualBox:Ubuntu16
payload链接:https://pan.baidu.com/s/1vrcvYwhKjNTBxmkSCRfbYA
提取码:njfj
工具:
- file: 解决文件类型
- head:将文本内容的前几行(默认前10行)显示到stdout中
- base64:对Base64进行解码和编码(Base64是一种将二进制数据编码为ASCII文本的方法)
- ldd:探索文件依赖性
- xxd:查看文件内容
- dd:转换和复制文件
- nm:列出二进制文件,对象文件或者共享库中的符号
- strings:查看二进制文件中中的字符串
- strace:显示二进制文件执行时的系统调用
- ltrace:显示二进制文件执行时的库文件调用
- objdump:linux自带的反汇编工具
- readelf:解析ELF文件
- tar:解压缩工具
- gdb:调试工具
以上工具命令行查询建议使用tldr. 泰酷啦!!!
目标:解锁所给文件(本文payload),找到flag,完成本次挑战。
步骤:
- 查看payload的文件类型,ASCII文本
- 使用base64对payload解码并查看解码后的文件类型,两层压缩,首先是gzip格式的压缩,然后是tar压缩
对其解压,得到ctf ,67b8601两个文件
分别查看两个文件的类型, - 运行ctf,缺库文件
查看67b8601文件的前几行,发现ELF关键字,说明缺的库文件隐藏在该位图文件中
提取ELF头部,64字节,并通过readelf查看
通过elf_header确定共享库文件的大小,由ELF可知道,节头表在ELF的最后,elf_header中可以看到节头表的位置偏移量是8568,一共有27个节,每个节的大小是64,因此该共享库文件的大小=8568+27*64=10296。提取该共享库文件,并且查看elf头部和符号表以确定提取无误。 - 再次运行ctf文件,设置LD_LIBRARY_PATH环境变量以通知动态链接库搜索当前路径
运行后无任何提示,但查看退出状态为1,说明文件运行失败,寻找失败位置 - strings提示,查看ctf的字符串,以寻求新的线索。
‘DEBUG:argv[1]=%s'得知,程序需要接收一个参数
果然,程序提示checking 'foobar',但说明检查失败,尝试strings中的’show_me_the_flag‘
checking成功,但退出状态仍为1。需要寻找其他线索 - 利用strace和ltrace跟踪ctf的系统调用和库文件调用,试图确定下一步操作
似乎没有有用的线索,尝试ltrace
在退出之前,调用了getenv,这是一个用于查找环境变量的标准库函数,确定ctf需要一个GUESSME的环境变量,先设置为虚拟值,测试程序行为
果然,程序行为发生变化,但是设置的虚拟值是错的,需要想办法找出真的虚拟值。 - 使用objdump检查指令集行为。从guess again地址找到相关指令。
确定guess again 的地址为0x4011af。反汇编-text节
分析上段反汇编代码,400dcd处的指令是上述环境变量比较失败后的分支,所以往上看,找到环境变量期望值的存储地址,在400dc8处将环境变量输入值的低字节与期望值比较,因此期望值的基址在rcx寄存器处,需要gdb调试找到。 - 使用gdb转储动态字符串缓冲区
至此,找到环境变量的期望值字符串'Crackers Don't Matter' - 验证成功
至此,该实验完成啦!
计算机学习需要深入理解,活学活用,实践为王,不能仅限于理论层面的学习,共勉!!!