您尚未登录。

楼主 #1 2020-03-12 00:31:03

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

CH558利用Bootloader漏洞导出固件

免责声明:
下文中的所有内容仅供学习和研究之用,对由此造成的各种问题概不负责,如有侵权请删除本帖,谢谢。

今天在沁恒官网论坛看到这个帖子:关于单片机里面的程序的安全性,颇感兴趣,遂亲自验证了一下,发现确实可行,于是发帖分享下经验。
帖子里面说的GitHub地址应该是这个:MarsTechHAN/ch552tool,结合导出的bootloader分析,发现验证固件的命令有漏洞,虽然数据需要由PC端发出且一次至少需验证8个字节(此时理论的可能性达到2^64种,无法枚举),并且设备只会返回是否校验正确,但由于该命令不限制范围和字节对齐,因此可以利用已知字节+1个未知字节的方式,遍历该未知字节的值直到校验成功为止(理论可能性为256种,可以接受)。正好0xFC00开始的部分flash内容恒为0xFF(这部分内容由bootloader管理),因此可以利用0xFC00开始的已知字节,倒推出前面所有未知字节。
我写了个程序:metro94/ch55x_dumper,导出的时间大概是5分多钟(4KB左右的代码量),相对来说比较慢,毕竟需要花时间猜。
最后说一句,由于bootloader存在漏洞,因此打算商用的小伙伴们建议替换或直接关掉这个bootloader(通过修改No_Boot_Load的方式)。由于官方工具的IAP实际上会在进入bootloader后才调用,因此也不保险。目测bootloader区域没有额外锁定,应该可以在运行主程序时进行替换。

最近编辑记录 metro (2020-03-12 00:32:51)

离线

楼主 #3 2020-03-15 12:05:10

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

演技担当黄晓明 说:

下载一个木马APP导出bootlloader ,然后在分析调用

我已经自己导出并用IDA Pro反汇编了,有一些编码指令似乎在GitHub上没看到有人用过。
它的bootloader还比较初级,虽然范围检查之类的有,但是没有对关键数据的加密选项。所以那个论坛帖子里面的老外看起来自己搞了一个bootloader。

离线

楼主 #5 2020-03-16 09:53:10

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

panlizzx 说:

直接弄一块芯片,写一个程序和pc通讯,用UINT8C指针赋值为bootloader所在的地址就能轻而易举的导出bootloader

是的,我就是写了一个简单的程序读出bootloader并分析的,参考的是FX2的方式。由于bootloader不设防,所以导出的过程很简单。
不过这篇文章是从bootloader导出用户区的代码,即使用户区的代码禁止拷贝程序,因为管不到bootloader,所以可以绕过用户程序直接导出Flash上的所有代码,包括bootloader和用户代码。这恐怕不是WCH设计bootloader时的本意(他们提到新版本bootloader修复了1.0版本的漏洞,但漏洞依然存在)。

离线

楼主 #7 2020-03-16 15:45:14

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

mini_uc 说:

看来用了这个CH55X系列就麻烦大了.

还好,bootloader可以自己替换,自己写一个没有bug的bootloader替换上去就行了,理论上还是安全的。
现在疑惑的地方是CH55x有专用编程器,本身并不公开。按理说CH55x是有代码保护功能的,保护的也就是这种ICP的下载方式,希望这块足够安全吧。

离线

楼主 #9 2020-03-16 16:15:14

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

mini_uc 说:

比如CH552的自带BOOT在0x3800上的能换下来嘛?

另外GCC下,ROM_CFG_ADDR这个寄存器是16位的,要关闭No_Boot_Load?

感觉有点坑哇。呵呵

我没试过,但是1楼那个帖子的老外说是可以的。
通过No_Boot_Load关闭bootloader,那样的话bootloader提供的ISP下载就直接废了,除非你自己的程序可以修改自己,否则就只能用他那个不公开的专用编程器才能下载。
所以我现在打算自己写个bootloader把它替换掉,通过附加额外的限制使得固件不能随意烧入(比如密码验证),这样的话只要bootloader本身和原有的用户程序足够安全,就不存在导出固件的方法了。
当然理论上还有其它修补办法,比如修改原来的bootloader之类,但我觉得不如另起炉灶,毕竟原来的ISP工具也不见得多好用。

离线

楼主 #13 2020-05-07 10:29:32

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

尼尔 说:

版主有没有联系方式  我用你写的测试了一下运行不了啊

运行不了是哪方面的问题?可以直接回帖说明情况。

离线

楼主 #15 2020-05-07 10:44:13

metro
会员
注册时间: 2019-03-09
已发帖子: 445
积分: 489

Re: CH558利用Bootloader漏洞导出固件

尼尔 说:

Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 223, in get_interface_and_endpoint
    return self._ep_info[endpoint_address]
KeyError: 2

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\ch55x_dumper-master\ch55x_dumper-master\dump.py", line 9, in <module>
    dev.write(0x02, bytearray([0xA7, 0, 0, 0x1F, 0]))
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 940, in write
    intf, ep = self._ctx.setup_request(self, endpoint)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 215, in setup_request
    intf, ep = self.get_interface_and_endpoint(device, endpoint_address)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 225, in get_interface_and_endpoint
    for intf in self.get_active_configuration(device):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 236, in get_active_configuration
    self.managed_open()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 102, in wrapper
    return f(self, *args, **kwargs)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\core.py", line 120, in managed_open
    self.handle = self.backend.open_device(self.dev)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\backend\libusb1.py", line 786, in open_device
    return _DeviceHandle(dev)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\backend\libusb1.py", line 643, in __init__
    _check(_lib.libusb_open(self.devid, byref(self.handle)))
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python38\lib\site-packages\usb\backend\libusb1.py", line 593, in _check
    raise NotImplementedError(_strerror(ret))
NotImplementedError: Operation not supported or unimplemented on this platform

可能是驱动问题。试试用最新版的Zadig安装WinUSB的驱动。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn