🖨️
IOT 固件安全 All in One
  • 前言
  • WIKI
    • 固件分类
    • 固件获取
    • 固件解密
    • 固件解剖
    • 固件调试
    • 仿真分析
    • 固件FUZZ
    • 静态分析
    • 同源分析
    • 漏洞挖掘—Web接口
    • 漏洞挖掘—无线协议
    • 漏洞挖掘—APP应用
  • appendix
    • 附录1:信息收集
    • 附录2:工具列表
    • 附录3-1: 指令集分析-MIPS
    • 附录3-2: 指令集分析-PowerPC
    • 附录3-3: 指令集分析-ARM
    • 附录4: 基线
    • 附录5:Azure IOT SDLC Best Practice
    • 附录6: 论文
    • 附录7: 参考资料
Powered by GitBook
On this page
  • 一、固件加密判断
  • 二、硬件获取密钥
  • 三、调试直接读取
  • 四、对比边界版本
  • 五、向升级程序
  • 六、漏洞获取密钥
  1. WIKI

固件解密

Previous固件获取Next固件解剖

Last updated 2 years ago

有些IOT设备会对固件加密甚至签名来提高研究门槛和升级时的安全性,因为加解密比较耗费资源,这类设备一般配置会比较高,比如一些路由器和防火墙。

一、固件加密判断

判断固件是否加密比较简单,有经验的小伙伴有二进制编辑器打开就能看出一二,一般会存在以下特性。

除了固件指示头没有可见字符,(除去header)数据按比特展开01频率基本一致binwalk(-e)无法解析固件结构,且(-A)没有识别出任何cpu架构指令。

如果满足上述特点,就会猜测固件已被加密,固件解密一般会从这几个角度,但也不局限于下面的方法。

二、硬件获取密钥

此种方法只限于固件始终以加密状态存在,当系统启动时才通过解密解包加载至flash,且设备缺乏(UART/JTAG等)动态调试手段。由于flash中有完整的解密过程,可以通过编程器读取flash,逆向解密算法和密钥,达到解密固件的目的。比如从某设备的读取的flash内存分布如下:

0x000000-0x020000 boot section
0x020000-0x070000 encrypt section
0x070000-0x200000 encrypt section
0x200000-0x400000 config section

显然我们需要的加密过程在boot section中,我们需要从中找到加密算法和密钥,一般加密都采用AES等公开分组算法,关键是找到分组模式,IV(非ECB)和密钥。将boot加载到IDA pro中,并没有自动识别:

可以通过对比ARM代码最开始部分的中断向量表结构手动识别,常见的入口代码如下所示。

.globl _start
_start:
    b       reset
    ldr     pc, _undefined_instruction
    ldr     pc, _software_interrupt
    ldr     pc, _prefetch_abort
    ldr     pc, _data_abort
    ldr     pc, _not_used
    ldr     pc, _irq
    ldr     pc, _fiq
...
_irq:
        .word irq

之后可以就可以逆向得到加密算法为AES,密钥通过设备序列号的sha256哈希获得。

通过IDA pro识别此类结构将在后文介绍RTOS时探讨,利用这种固件加密方式的设备安全级别教高,一般设备只在升级时进行解密验证。

三、调试直接读取

这个方法最容易理解,即在设备启动后利用UART、JTAG、Console或网络等手段把固件(打包)回传,这样就绕过了解密环节。值得注意的是需要设备提供这些接口,具体方法因设备不同而异,这些接口的使用将会在硬件篇里作介绍。

四、对比边界版本

此种方法适用于厂商一开始没采用加密方案,即旧版固件未加密,在某次升级中添加了解密程序,随后升级使用加密固件。这样我们就可以从一系列固件中找到加密和未加密之间的边界版本,解包最后一个未加密版本逆向升级程序即可还原加密过程。

通过下载上图所示某路由器固件,解包后通过搜索包含诸如“firmware”、“upgrade”、“update”、“download”等关键字的组合定位升级程序位置。当然存在调试手段也可以在升级时ps查看进程更新定位升级程序和参数:

/usr/sbin/encimg -d -i <fw_path> -s <image_sign>

通过IDA pro逆向encimg程序很快得到加解密过程代码,采用了AES CBC模式:

AES_set_decrypt_key (
   // user input key
   const unsigned char *userKey,
   // size of key
   const int bits,
   // encryption key struct which will be used by
   // encryption function
   AES_KEY *key
)

AES_cbc_encrypt (
   // input buffer
   const unsigned char *in,
   // output buffer
   unsigned char *out,
   // buffer length
   size_t length,
   // key struct return by previous function
   const AES_KEY *key,
   // initializatin vector
   unsigned char *ivec,
   // is encryption or decryption
   const int enc
)

五、向升级程序

此种方法适用于已经通过接口或边界版本得到升级程序,可以利用分组算法的盒检测工具来判别加密算法和定位位置,当然binwalk也可以解析某些简单情况,比如某工控HMI固件:

iot@attifyos ~/Documents> binwalk hmis.tar.gz
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
34       0x22        OpenSSL encyption, salted, salt:0x5879382A7

直接加载升级程序,定位openssl调用很容易就得到解密命令:

六、漏洞获取密钥

如果找不到边界版本,又找不到调试接口或不熟悉硬件调试,可以考虑采用历史版本漏洞先获取设备控制权,在拿到升级程序逆向加密算法。这种方法比较取巧,需要设备存在RCE漏洞的历史固件,通过降级操作植入漏洞获取权限,下载所需升级程序,然后逆向得到加密算法。

Page cover image