freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

老题新招 | 再解Vxworks加密漏洞
2018-07-19 10:00:29

*本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担。

前言

工控固件逆向题,有时会在vxworks上做文章。笔者在啃工匠安全实验室第二道CTF题时(见传送门),在原文的基础上,通过编写程序,计算出了hash为固定值cQwwddSRxS所使用key的解。

正文

对工控固件(一般为vxworks)的分析有固定的步骤,总结如下:

1.用binwalk查看固件基本信息并解压固件;

2.确认解压固件的信息如CPU类型,编译固件使用的大头序;

3.确定固件的加载地址,一般为0x10000(原文中未对如何找加载地址进行解读);

4.用IDA pro反汇编程序,并修复固件中的函数名;

5.找到对应的漏洞函数进行分析。

由于原文中未对如何找出固件加载地址进行说明,也未对最后碰撞hash值的过程进行说明。在这样的疑惑下,本人对这两个问题进行了进一步的解析:

一是找出了靠谱的计算固件加载地址的方法(这里要感谢"工匠安全实验室"的大哥给出的思路);

二是通过编写程序,碰撞出多个同一hash值的多个key解。

一、计算固件加载地址

固件加载地址的计算是通过vxworks固件中的函数符号表计算得出的。在固件中,与函数字符串相关的有两个地址,一个是在固件中字符串的存储地址;另一个是固件中保存的函数字符串的内存地址。这两个地址相减,就能得出固件的加载地址。因此,我们只需要定位到一个固定的字符串,找到它在固件中的位置以及在内存中加载它的地址,就能算出固件的加载地址了。在winhex中搜索APP_STATION这个字符串(该字符串有它的特殊性,它是函数字符表中的最后一个字符串,见下图,如果搜不到该字符串,按照这种方式找到字符表的最后一个字符串也是可以的),记下它在固件中的地址为0x26656c。

image.png

下一步还需要找到该字符串在内存中的加载地址,根据函数符号表的特点,它的内存加载地址为符号表的起始位置。在binwalk中可以查看vxworks的字符表的大致起始位置,如下图所示,binwalk计算的符号表的起始位置为0x301E74。

image.png

需要说明的是,这个值不一定准确,还需在winhex中进一步确认。在winhex中跳转到0x301E74,如下图所示。图的右侧出现了很规律的".....'e..."的列。这种规律复合函数符号表的排列方式,因此,根据排列规律,符号表的起始位置应该为0x301E64。

image.png

在这个地址存储的是字符串的内存地址为0x27656C,而且可以看到,字符串的地址是倒序排列,所以这个地址就是前面的最后一个字符串的内存地址。

那么,加载地址为字符串的内存地址减去字符串地址有:0x27656C - 0x26656C =0x10000

算出了固件的加载地址,当我们加载固件后,需要修复函数名该怎么办呢?可以利用函数名修复脚本完成这一操作,使用的脚本如下图所示:

image.png

在对具体的工控固件进行函数名修复时,脚本中有三个值需要注意下。loadaddres即是刚刚算出的加载地址,eaStart即是函数符号表的起始地址为0x301E64,eaEnd是函数符号表的结束地址,这个地址怎么找,还是只有根据符号表的规律来找。如下图所示,符号表会规律的排列,这种规律排列在0x3293a4结束,因此,这个地址即为符号表的结束地址。

image.png

这样,才可以顺利地加载并运行该脚本。

二、暴力碰撞hash值

先通过固件逆向分析loginDefaultEncrypt函数,在IDA Pro中可以看到loginDefaultEncrypt函数的反汇编情况,结合vxworks给出的源码,可重写该函数为:

image.png

在函数里可以看到,输入的密码key长度有限制,长度得大于8,小于40。而hash值cQwwddSRxS的长度为10。经分析发现,长度为9和10的key都可能会产生长度为10的hash值。因此,本人先通过编写程序随机生成长度为10的密码本,代码如下,为shell脚本。

image.png

在大for循环中,共生成了100万个长度为10的密码。在shell中运行该程序:

./10pass.sh > 1.txt  #将随机密码输出到1.txt文件中。

再编写程序循环读入密码本中随机生成的密码,采用已经写好的loginDefaultEncrypt函数算出密码对应的hash值;最后,与题目给出的hash值进行比较,如算出的hash与题目hash的值相等,则视为碰撞出了key值。下面是给出程序的main函数,在函数中可以清楚地看到每一步的操作。

image.png

用gcc编译:gcc -o guesshash ./guesshash.c,运行,碰撞出的结果如下图所示。

image.png

可以看到,这确实是一个很弱的加密算法,100万个随机密码就碰撞出11个hash值相同的结果。

最后,本次实验的所有实验代码见github:https://github.com/scu-igroup/ctf_vxworks

总结

vxworks固件已曝出多个漏洞,要想定位这些漏洞,还需一些固件逆向的知识。本人即是在学习的过程中,发现计算固件加载地址和hash碰撞在现有的资料中,涉及的并不多,因此自己总结出了一套方法,在此分享出来,供大家参考。如有其他思路和建议,欢迎一起讨论。

*本文原创作者:scu-igroup,转载请注明来自FreeBuf.COM

# hash # CTF # VxWorks
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者