首页
社区
课程
招聘
[原创]探究vxworks文件名恢复
发表于: 2024-11-9 11:59 4934

[原创]探究vxworks文件名恢复

2024-11-9 11:59
4934

VxWorks以其良好的可靠性和卓越的实时性被广泛地应用在通信、军事、航空、航天等高精尖技术及实时性要求极高的领域中,如卫星通讯、军事演习、弹道制导、飞机导航等。
美国的F-16、F/A-18战斗机、B-2隐形轰炸机和爱国者导弹,火星探测器如1997年7月登陆的火星探测器,2008年5月登陆的凤凰号、2012年8月登陆的好奇号都使用到了VxWorks。

遇到好几次Vxworks固件了,真是每次被拷打每次都有新的一点感悟,从不知所措到稍微知道怎么做了
符号表缺失其实可以根据字符串的提示、静态编译的库函数的辨别去硬逆个大概,甚至有些残存符号表可以仔细找找恢复上去,
但如果是遇到某些路由函数,就可能没有办法——没办法去看路由到的文件,有时候就不能很好地分析整个数据流
图片描述
因为,binwalk一把梭vxworks固件出来的画风往往是这样的,命名非常的混乱,但如果实际打开看看,内部内容其实是正常的
图片描述
仔细一想,vxworks系统启动的时候,肯定是有什么参照去恢复文件名和位置的,否则怎么做路由呢
所以就开始了接下来的vxworks文件名恢复探究,以及,一键自动化

既然要恢复文件名,反过来就可以grep一下文件名去找这个表。以上图第二个例子为例
/userRpm/WzdAccessCtrlTargetAddRpm.htm
grep -r "WzdAccessCtrlTargetAddRpm.htm"可以得到这几条结果:
图片描述
可以看到有两个别的文件(实际上也是htm文件)定义了表单,提交数据到WzdAccessCtrlTargetAddRpm.htm
只可惜我们连这两个htm叫什么名称都不知道,这就很难去分析数据流了
说回正题,有两个文件引用了这个htm,分别是0x3FC0和0x53D60处分割出来的文件,以各自在固件中的偏移来命名(3FC0、53D60)
实际上这两个文件是有来由的
3FC0其实就是uImage镜像
图片描述
补充说明一个事情:3FC0文件不是完整的uImage,被binwalk命名为3FC0.7z的文件实际上才是完整的uImage镜像文件
图片描述
而0x53D60的大小远远大于其它LZMA压缩区域,实际上,这正是vxworks的主程序bin文件,也是我们平常分析的重点文件

图片描述
所以比较合理的解释是,53D60有这个字符串的原因是在web服务时进行路由
而3FC0(uImage)作为vxworks的启动镜像,其拥有这个字符串的唯一原因,是在恢复文件名和结构什么的,所以,如果有偏移表,那就在uImage内部。把3FC0.7z放入010editor看看:
首先,是最初的引导部分,这里放的都是程序代码:

图片描述
搜索".htm"或者".png"之类的字符串,就能找到一个很整齐的表

图片描述
可以看到文件名的前面,好像有类似于偏移的记载,不过到目前还是猜测
如果能找到一套正确的计算方法,能完全对上binwalk里面跑出来的镜像偏移的话,那就说明这确实可以用来恢复文件名
至此,我们找到了最关键的表项,而具体的细节还需探究一下

一个容易踏入的误区是,刚开始以为文件名的前面是其对应大小和偏移,为此计算了十几个,发现不对劲,为什么每种文件总是有1-2个的偏移是别的文件类型,而其它都是对应类型的呢
实际上,文件名的一串00 00 00 00后面,才是它的大小和偏移量

图片描述

一些固件,比如这个案例,会记载文件系统的偏移(没记载也可以有兼容性很好的方案,下一节细说)
实际上,表里的偏移量+文件系统的偏移,将会对应到binwalk解包的文件名,即,在固件中的偏移值,这就是vxworks文件名恢复的方法

图片描述

在反复的测试当中,我发现vxworks的文件系统有很多都是文件系统偏移0xF080+xxx的组合。比如,以png来作为测试案例:
首先按MIME type排序一下,因为偏移表本身也是按照类型来集中排布的,这样可以方便实验

图片描述

然后,以png为例进行偏移量的计算测试
可以在010editor等工具里面找到如下.png字样

图片描述
将其偏移逐一取出,并加上刚刚提到的0xF080,我们可以得到一些偏移量:

图片描述

如图所示,所有的文件名都能找到对应偏移,那么,说明这种办法是切实可行的:比如binwalk解析出来的1FDA8,我们就可以知道它其实叫做loginbg.png,等等
(使用的excel语句是=DEC2HEX(HEX2DEC(B2) + HEX2DEC("F080")),可以帮助加快这个测试过程,不用每次都按计算器)
紧接着来测试下jpg、gif,找到偏移表对应表项

图片描述

实验结果如下

图片描述
图片描述
全对,看来该方法是正确的

接下来就是想自动化这个繁杂的过程,就是想能够像binwalk一样一键提取并恢复,而且为了以后反复使用,需要比较可靠的设计
接下来介绍一些比较奇怪的设计的地方,力求更加兼容

首先,binwalk的各种文件标签识别还是很厉害的,那就必须使用binwalk的结果了。同时我们需要binwalk -Me一下,以提取所有文件
路径最好和默认的不一样,避免用户在先前的vxworks探索中改动了文件名什么的,导致部分文件找不到对应名称
在binwalk结果里,IMG0 (VxWorks) header前后,将会是很多信息的集中点,其前面是uImage偏移,后面是文件系统,所以会有专门的字符串匹配

然后,我们需要读取IMG0 (VxWorks) header后面的那个文件系统偏移地址,

图片描述
经过实验有些案例里面并非IMG0 (VxWorks) header正下方的偏移,而是下下方的偏移

图片描述
所以,为了提高脚本的兼容性,设计成了尝试IMG0 (VxWorks) header后三行的偏移量,应该是没有太大兼容问题的
图片描述

再之后,需要从IMG0 (VxWorks) header前面的那个区域,比如这里的0x3FC0,里面存放有我们需要的表
如何全自动确定这个表的位置,以让我们不需要手动打开HxD和010editor去手动给程序这个参数?

图片描述

但是问题就来了,如刚才所述,最初的引导部分,这里放的都是程序代码:

图片描述
好消息是,在连续的启动引导代码以后,会有大片的00区域,思路是,其实可以进行检测,检测到多少个连续的00,就进入到搜索头部模式;如果检测到又有字符了,那基本上就是我们的IMG0头部了(对...对吗?哦布莱克斯)
图片描述

对,也不对,有些固件是有多段引导代码的,
具体表现例子为:
程序片段1+"00 00 00 00"*n+程序片段2+"00 00 00 00"*n+程序片段3+"00 00 00 00"*n+偏移表
那比较简单地一次匹配多次出现的00字节,自然会不对,这样会让程序匹配到程序片段2
比如水星系列mw313r,其该表项藏在3个程序片段之后,0x8b1f0处,这也让我发现需要去兼容这个问题
图片描述
最后,采取的方案是在使用extract_file_info()函数提取信息时,检测名称的合法性,如果发现提取不了文件名(连续失败到一定的阈值,说明不正常了),那就在提取文件名失败的地方重新开始搜索偏移表
图片描述
图片描述

正确识别文件名,即一个文件偏移记录块的开端,那么同时就可以解决偏移的提取问题
仅限这些字符命名的文件:大小写字母、数字、下划线、短横线、斜杠,
而且,必须有一个"."符号,因为vxworks目前遇到的,所有的文件都是有后缀的,即便是二进制文件
而且,会按照4字节对齐的方式去取文件名
总之这套正则匹配使得精确程度提高了,比如,下面的owowowow...字符串,等等,就不会被匹配进去
图片描述

而万一有些文件里面如果有满足这种规则的坏字符串的话,还有最后两个办法:
长度限制(满足这些规则以外,文件名长度还必须>=5)
到最后的文件重命名环节,其需要确实对上了某个文件偏移才会被引用,否则会被丢弃
图片描述
还有就是,怎么知道文件名提取到了末尾呢
其实就是,每次提取下一个文件名时,如果检测到连续0x100个非00字符,那就说明提取已经到尽头了,因为接下来就是下一个程序片段部分

正确恢复文件名实际上还需要考虑到一件事:
一部分固件的文件名如下,是没有带路径的
图片描述
而另一些还是有的
图片描述
所以需要分情况处理
图片描述

最后,附上开源代码
https://github.com/0xba1100n/vxfile_extractor
效果图
图片描述

图片描述
图片描述

受winmt师傅在评论区的建议启发,遂改进了相关的方法_(:з」∠)_
为了提高vxworks固件提取脚本的泛用性,采用以下方案来避免对任何硬编码字符串(IMG0 header等)的依赖,因为依赖binwalk上的字符串是不够稳妥的——vxworks可不止一种固件结构,而且存在文件偏移表的文件,也不一定会出现一大片可以匹配的00区域(比如wr842nv3),得想点更稳的方法

想来想去,还是决定用这样的混合方式(组合了:精确但仅适用于有http服务固件+不太精确但泛用)来匹配,为了精确和泛用性的平衡吧

首先,我们的漏挖对象几乎都是有http页面的,而且,目前的rtos的web服务由于性能受限都是静态页面,受到SaTC前后端字符串匹配的启发,那就其实可以从文件引用的角度去得到确实存在且有其特殊性的文件名字符串

这意味着,我们可以剔除那些,不包含这些100%正确字符串的固件了,并且认为它们是不具备文件偏移表的固件

步骤是,会先从htm文件内部的"src=xxx"的资源引用语句入手,匹配前端文件引用到的东西,我们可以首先在binwalk刚解包的,名称混乱的区域内执行:

grep -r "src=" | grep -E ".(gif|jpg|js|css)"

然后,我们就得到了一些带路径的被引用静态资源文件名

这时候需要明确一件事:如果真的存在一个足够丰富包含所有偏移的表,那么,其会大量包含这些文件名,只要多次匹配每个被引文件名的结果有重合的文件的话,那就一定是有文件偏移表在里面了,比如以下案例的两个binwalk解包文件,它们包含了所有的被引文件,里面大概率是有表的

那么,使用这种方法来确定表项位置,准确率就会达到真正意义的99.9%了

而且这个文件对应偏移应遵循“够用选小”原则,不仅是因为,这样一个偏移表是初始化时使用的,其偏移基地址一定是偏小的,靠近boot镜像的

为什么会想到这样一个策略呢,因为实测有部分情况(如tplink的wdr7600),如果src引用的文件有很多个都没有对应的表项,但使用grep后缀的方法,还是能匹配到一些二进制文件有部分字样的话。。。这种就另说了,似乎没有文件偏移表

这种实际上我暂时找不到恢复文件名的方法,其仅仅有一些残缺不全的文件名记载,更何况是完整的文件偏移记载了,


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-11-19 16:25 被是气球呀编辑 ,原因: V2版本改进说明
收藏
免费 3
支持
分享
最新回复 (13)
雪    币: 249
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
太棒啦师傅~!
2024-11-10 18:23
0
雪    币: 7
活跃值: (218)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大神真厉害 binwalk就是文件名太乱
2024-11-10 18:54
0
雪    币: 4443
活跃值: (1214)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
4
stonectf 太棒啦师傅~!
谢谢stone师傅
2024-11-11 19:22
0
雪    币: 4443
活跃值: (1214)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
5
microv 大神真厉害 binwalk就是文件名太乱
嘻嘻如果能帮到你那就好,欢迎提issue指导改进建议~
2024-11-11 19:39
0
雪    币: 186
活跃值: (865)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mark
2024-11-12 07:54
0
雪    币: 177
活跃值: (8384)
能力值: ( LV13,RANK:438 )
在线值:
发帖
回帖
粉丝
7
感谢分享。只是粗浅看了下部分文章,想友好地提点个人看法。我感觉目前的适配面还是比较窄,更像是拿了几款固件根据特征适配了下,而不够通用。结合我自己曾经的一些经验,我觉得不能只根据几款固件的特征就从某标识字符串上下来找地址(并且不是所有VxWorks固件都有IMG0 (VxWorks) header这种标识字符串),确定偏移表所在文件和基地址的方法可以改进地更通用些。例如,偏移表所在文件一定是文件(路径)名多样的,数量多的,可以通过strings+grep正则匹配疑似文件(路径)名数量以及文件后缀的种类,来确定偏移表所在文件;对于基地址的确定,例如可以根据偏移表中找到偏移为0位置的文件大小,根据binwalk出来的LZMA文件地址差来确定(如有多个,按此过程二次筛查即可)。当然了,对于RTOS固件分析而言,最重要的不是恢复这些文件名,而是恢复符号表吧哈哈哈,这个工作也是很经典了。
2024-11-12 19:13
1
雪    币: 4443
活跃值: (1214)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
8
winmt 感谢分享。只是粗浅看了下部分文章,想友好地提点个人看法。我感觉目前的适配面还是比较窄,更像是拿了几款固件根据特征适配了下,而不够通用。结合我自己曾经的一些经验,我觉得不能只根据几款固件的特征就从某标识 ...
感谢winmt师傅提建议Thanks♪(・ω・)ノ我是您的粉丝哈哈
哦哦,我也感觉其实这个项目目前普适性不是很高,感觉师傅的想法确实可以诶,grep如果检测到文件名数量多的那块文件,那就一定是偏移表,这样也就不需要IMG0 (VxWorks) header字样了,好的我尽快改改哈哈
对于文件系统基地址的确定这个的话。。。确实,这样做容错会高很多,当时也想过这个做法后来上文那个更简单的办法可行就没有实现这样的做法
符号表恢复确实也好重要,不知道以后能不能做点相关工作呢。。。嘻嘻,毕竟从头到尾都没有符号有点太痛苦
2024-11-12 19:34
0
雪    币: 177
活跃值: (8384)
能力值: ( LV13,RANK:438 )
在线值:
发帖
回帖
粉丝
9
是气球呀 感谢winmt师傅提建议Thanks♪(・ω・)ノ我是您的粉丝哈哈 哦哦,我也感觉其实这个项目目前普适性不是很高,感觉师傅的想法确实可以诶,grep如果检测到文件名数量多的那块文件,那就一定是偏移表 ...

粉丝,不至于不至于。我竟然这么有名的么
之前没注意,看到你开源了。我就去试着拿你的脚本跑了一下,正好试了之前存着的两款都不太行哈哈(也是巧了),TP-Link的WR842N和WDR7660,具体问题没分析,你可以去看看。这两款我好久前也都分析过,印象里都是VxWorks,没加密。
你这个自动化恢复文件名的工作之前我没看人做过,但感觉脚本改好一些还是有价值的。给师傅的Github先Star上了,mark一下。

最后于 2024-11-12 20:19 被winmt编辑 ,原因:
2024-11-12 20:06
1
雪    币: 4443
活跃值: (1214)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
10
winmt 是气球呀 感谢winmt师傅提建议Thanks♪(・ω・)ノ我是您的粉丝哈哈 哦哦,我也感觉其实这个项目目前普适性不是很高,感觉师傅的想 ...
okok,我也是正愁没有更多的vxworks固件来完善脚本的广泛适配,谢谢(*´▽`)ノノ
是的哈哈我好多次在搜索引擎搜iot漏挖和复现文章什么的会经常搜到你的文章,如果师傅忙完毕业的事情可以继续多分享一些漏挖文章那就太好了,嘻嘻,那些文章都很棒(๑•̀ㅂ•́)و✧
2024-11-13 09:43
0
雪    币: 177
活跃值: (8384)
能力值: ( LV13,RANK:438 )
在线值:
发帖
回帖
粉丝
11
是气球呀 okok,我也是正愁没有更多的vxworks固件来完善脚本的广泛适配,谢谢(*´▽`)ノノ 是的哈哈我好多次在搜索引擎搜iot漏挖和复现文章什么的会经常搜到你的文章,如果师傅忙完毕业的事情可以继续多 ...
嗯嗯,恢复VxWorks文件系统内文件名的适配工作还是要花多些时间和精力的。不像是确定VxWorks系统加载地址这类工作能找到较为通用的方法,我见过的就拿MINIFS的文件名和偏移映射表来说都有很多不同的格式…还是很复杂的。我没研究过能否找到通用性思路,但您这篇文章里所描述的例子也是MINIFS吧,而且只是一种格式,我见过的至少还有个三四种吧。我昨天给的那两个TP-Link的样本记得也是你文中这种格式的,就TP-Link而言,很多其他系列即使还是MINIFS的文件系统都有不同格式,你可以去找找,除了TL系列还有Archer系列等等……
2024-11-13 12:03
1
雪    币: 177
活跃值: (8384)
能力值: ( LV13,RANK:438 )
在线值:
发帖
回帖
粉丝
12
是气球呀 okok,我也是正愁没有更多的vxworks固件来完善脚本的广泛适配,谢谢(*´▽`)ノノ 是的哈哈我好多次在搜索引擎搜iot漏挖和复现文章什么的会经常搜到你的文章,如果师傅忙完毕业的事情可以继续多 ...
感谢您的认可!我已经不做IoT漏洞挖掘很久了,之前很多洞因为各种因素,也不方便公开,有时候公开洞还得被厂商找去“喝茶”。技术是一方面,思路是一方面,但是更多的可能还是眼力活和体力活…想去尝试些新东西了,以后有机会的话也会继续分享到看雪。
2024-11-13 12:15
1
雪    币: 4443
活跃值: (1214)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
13
winmt 感谢您的认可!我已经不做IoT漏洞挖掘很久了,之前很多洞因为各种因素,也不方便公开,有时候公开洞还得被厂商找去“喝茶”[em_055]。技术是一方面,思路是一方面,但是更多的可能还是眼力活和体力活…想 ...

是的,已经体会到iot漏挖确实挺偏向于纯体力眼力活,哈哈......预祝师傅在新的领域也能做出一样惊艳的成绩来,到时候想学习一下(*^▽^*)

最后于 2024-11-13 13:44 被是气球呀编辑 ,原因:
2024-11-13 13:31
0
雪    币: 695
活跃值: (3219)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
6666
2024-11-14 20:57
0
游客
登录 | 注册 方可回帖
返回
//