某打印机固件更新校验突破
漏洞复现
复现一下一些比赛的漏洞,学习一下,也方便之后打比赛。
某打印机可以通过篡改更新包实现恶意固件上传。
先拿到官方给的更新工具

看到是个exe,直接执行了会报错,直接丢进binwalk,看到解出了一些东西,直接对MICE_ALL.fw进行分析

丢IDA里全是乱码,发现有gzip的压缩头,意识到固件可能分块了,继续丢binwalk,能看到压缩包,-e解出来发现还有四个包。

直接把simple.bin丢进IDA开始分析,搜索firmware、fw、update、upgrade等字符串去定位,设备没有shell,只能静态分析。
大概如下

定义了一个header的结构体,从固件包里获取0x18字节的头信息存进header里,从代码里知道信息包括偏移,文件大小,长度,checksum,于是结合文件头来分析

先计算文件长度

发现头部有8CDEED倒序出现,确定了文件长度的存放位置
发现文件长度下面还有个8CDE69,与文件长度十分相似,做个差0x8CDEED – 0x8CDE69 = 0x84

于是猜测此为偏移量(header长度),文件总长度,文件数据长度,文件头长度

现在开始计算checksum,由于checksum的方法比较多,甚至有可能自己设计,所以得根据代码去分析,定位到代码

逻辑比较简单,单纯的将DATA每位相加,最后获取一个总和。
可以用工具粗略判断一下

也可以自己写脚本验证

继续分析代码,发现头最开始的四个字节代表的是这个块的标识,决定这是什么固件,走什么样的解析


有明文意义的可以当做设备和固件型号,也有把厂商或者是工具的标签写在头里的。
现在包头还有两个四位的信息意义未知

跟着逻辑找没有找到关于这两个地方的代码,可能需要一点猜测。
看到gzip包有字段和他比较相似,

看了下gzip的文件结构,发现这是时间戳,那么这个地方就大概率是时间戳了。
最后一个地方,发现没有对header进行校检的操作,猜测有可能是对header进行校检,用工具试了试

到这里基本是分析完了,要注意的是他采取的是多个header校检的方式,最外面的header校检通过了以后,才开始校检data的header,这个过程十分耗时,即使采用了最简单的校检和
格式如下


还遇到点小问题,直接用系统的gzip没法还原压缩包,得设置个压缩等级,最后用python的Gzip函数,compresslevel参数0-9一个一个试过去,发现6压缩出来的包与目标一致

每次改包+上传至少得三四十分钟,十分磨人,放两张对比图
原来的报错页面

改过的报错页面

到此分析完毕。