前言
上次挖水星路由器,没有机会恢复Vxworks符号表,因为固件内部已经抹除了符号表了(其实没有完全抹掉,下面会讲),当时只能硬啃库函数和自定义函数,而且不太熟悉rtos的http相关服务是怎么写的,就没有搞出来什么,
这次做题(Nepctf-火眼金睛)遇到一个vxworks带有符号表的题目(没错又是基于水星路由器的固件出的题),这道硬件题本身只需要在vxworks符号表里面找到一个奇怪的函数名(眼睛确实快看出火星子了)然后base32解密即可出flag,但我当时觉得这是个尝试符号表恢复的好机会,所以就赶紧实战恢复了一下,恢复完看到提示才发现只需要找个奇怪的函数名,不过学习了一下相关方法,不亏的
本次使用的文件:http://ba1100n.tech/stroage/attachment.7z
本次恢复使用的脚本https://github.com/0xba1100n/VxhunterIDAForkForPython3HighVersion
寻找主要文件与符号表
vxworks的主程序只有一个,这是最重要的一个文件,其与符号表是分离的,所以还要找符号表(有没有要看运气)
首先binwalk -Me 解包,看到这样,名字缺失的情况,就猜到又是vxworks了
仔细观察binwalk显示的内容,还会发现一些有趣的东西:
主程序在这里,由于位置在固件的0x10400处所以会被命名为10400
固件内部以小端序为主
其架构为armv7
然后grep一些函数名称,可以发现都位于19047F
(当然有些会把所有库函数静态编译后的符号抹掉,但保留自定义函数的符号,比如水星的mw3xx系列路由)
综合以上,我们收集到了如下信息:
主程序是10400,架构armv7,小端序
符号表存在且位于19047F
vxworks符号表恢复原理
打开hex视窗,会发现符号表里存放的内容,看起来有种整齐的感觉,让人想到了windows上的IAT、linux上的plt、got
开头的00 06 4E 9D实际上指示了函数偏移表+符号表的大小
00 00 3F 80 指示了函数偏移表的大小,需要x8+8才是真实的大小值
其正是函数偏移表、函数符号表的分界线
以函数AES_CMAC_GenerateSubKey为例,上图显示其是函数符号表的第二个函数,那就在函数偏移表第二个位置处找到它
其记录了两个偏移量:0x54000009(符号表内函数名称的存放偏移) 0x403E6354(主文件内函数的偏移)
这些都是内存加载时的真实偏移量
不难看出,1fc11-1fc08+0x54000000(符号表在内存中的base)=0x54000009
跟进主文件0x403E6354,发现确实是这个函数
当然也有比较独特的偏移表+符号表模式,以下是我之前分析的一个vxworks固件
其并不是只有单独的一个”偏移表+符号表”文件,
而是“偏移表+符号表+偏移表+符号表+偏移表+符号表+偏移表+符号表”这样的混合的模式
看过vxhunter的源代码就会发现,vxhunter对付不了这种连续分片模式的符号表,自然就恢复不了这个函数。
改进可以从这个地方入手,留坑
vxhunter修复与运行
网上的教程很多都是使用vxhunter的
https://github.com/PAGalaxyLab/vxhunter
但在照猫画虎的过程中,我发现原来这个项目已经有4-5年没有更新了
所以这里面的插件,随着python版本的推移,逐渐变得无法使用
(比如,python3大于某个版本后,str和bytes的拼接变得不再是那么“弱类型”等一些问题,以及脚本有少数的bug也修了)
然后就根据python3对类型方面的需要,修改了一下脚本,时间有限,很惭愧,做了一点微小的工作,没有改进成那种即使是分片的表都能恢复的工具
为了节省大家调试修改的时间,放到网上去了https://github.com/0xba1100n/VxhunterIDAForkForPython3HighVersion
跑起来会是这样的
效果如下
总结
vxhunter对付不了分片的函数偏移表+符号表,这个后面可以想办法改进改进