智能设备逆向工程之外部Flash读取与分析篇

唐朝实验室 · 2015/10/19 11:19

author: rayxcp

0x00 前言


目前智能家居设备的种类很多,本文内容以某智能豆浆机为例完成对其的固件提取和分析。

究其分析内部逻辑的原因可能会有很多种,和安全相关的原因主要有:

  1. 了解设备内部运行逻辑,逆向后有条件更改原有逻辑
  2. 通过逆向后的代码找到可利用的漏洞或原有隐藏功能

0x01 读取Flash


首先,准备好螺丝刀,镊子等工具。把设备拆解。取出设备主控板。如下图:

正面,其中红圈所在的黑色小板是Wi-Fi模块,上面的8脚Flash的芯片已通过吹焊台的热风机取下。

反面图

当目标为取得设备的运行逻辑时,首先需要找到运行逻辑存放的位置。以STM32 MCU的开发板为例,会有多种boot模式,其中一种boot模式是从MCU内部的Flash中启动,也就是说系统启动初期的逻辑在这种模式下是从MCU内部Flash读出的。但是这部分Flash的大小受限,通常容量情况为32KB ~ 512KB。那么其他的逻辑会通过SPI或者总线接口连接的外部Flash或SD卡等存储设备存放。针对这一款设备,除了MCU内部Flash外,板上还预制了一颗容量为2MB的外部Flash。

本篇关注外部Flash上的逻辑获取,通过SWD方式读取MCU内部Flash和调试等方法会在后续章节介绍。智能家居设备上一般的外部Flash为SOP8宽体芯片。见下图插座上的8脚芯片:

图中红圈的芯片就是从设备Wi-Fi模块上取下的Flash

Flash厂商品牌常见的有: winbond,gigadevice等。

以gigadevice GD25Q16名称为例

  • GD为厂商名
  • 25为芯片系列号
  • 16为MBit容量 也就2MB字节大小的Flash

Flash的内容可以通过编程器读取,首先在PC端安装相关的驱动和软件(在购买时会由商家提供)后,就可以读取Flash内容了。对编程器的选择上建议一定要带上插座,这样可以减少芯片的吹焊次数。此外还有芯片夹,可以夹住板上的Flash芯片,直接尝试读取,免于取下的过程,但是实测成功率不是很理想。

一般连接PC后,编程器配套的软件会自动识别出芯片类型和大小等信息。如果没有可手工尝试选择近似的型号(根据芯片名称)。

点击读取,待读取结束后,可以将读出的内容保存为bin文件。至此就获取到了Wi-Fi模块上Flash中的二进制内容。

0x02 逆向分析


在得到bin文件后就可以开始逆向分析了。

从设备MAC地址以及一些bin文件中特征字串和Wi-Fi模块的外观形态判断,该设备Wi-Fi模块使用的是上海汉枫公司(之后简称HF)提供的HF-LPT100S-10。该模块包含一枚HF自研的MCU(HF-MC101,内置128KB SRAM)。而模块上的Flash大小2MB。

将bin文件放入IDA,在加载的第一步中设置CPU类型为ARM Little End(根据该款设备的CPU类型)。之后会出现内存选项,如下图。这里可选设置RAM的起始位置和大小,这一步将方便之后设置RAM中的变量名,建议根据芯片实际情况进行设置。这里RAM是128KB,起始位置是0x20000000。

现在需要分析bin中包含的逻辑。在HF官网上提供了SDK的下载(基于Keil开发环境)。通过查看SDK包含的文档,得到如下针对ROM内容的结构描述。

这时可以建立一个ida py脚本,将得到的信息添加其中,在IDA中标注出各个segment:

当然也可以直接按长度,提取出各个段,例如提取出bin文件前512KB的app_main内容(见下面的附件)。

在进一步分析代码前可以先标记出基础库,例如标记出文件管理,内存操作等相关函数。一般有两种方式,第一种从文件自身的调试打印信息或者符号表包含的信息反推出函数;第二是加载获取的FLIRT类信息到当前文件。

FLIRT是Fast Library Identification and Recognition Technology的缩写,可以在https://www.hex-rays.com/products/ida/tech/flirt/index.shtml中找到相关的描述。简单的说就是通过建立库函数中使用汇编指令串以及各类引用的特征值匹配到当前当目标文件,标注出已知的各种函数名。当然定位函数,除了单纯指令串特征值外,诸如bindiff类插件也会通过函数内逻辑,和相互间调用关系来确定函数,这样的好处是提高库函数的命中范围和提高准确度。类似技术运用在函数定位上可以参见下面的插件:

https://github.com/devttys0/ida/tree/master/plugins/rizzo

针对LPT100S,有两类库文件可以导入,一类是Keil自身的一些库,还有就是在HF提供的SDK中包含的库LPB100Kernel.lib。通过FLIRT工具包,可以从这些库中提取出sig文件。步骤如下(以LPB100Kernel.lib为例):

  1. 下载ida的sdk文件,解压其中的flirt.zip
  2. 在bin目录下找到对应系统的目录,运行
    1. Pelf LPB100Kernel.lib LPB100Kernel.pat
    2. Sigmake LPB100Kernel.pat LPB100Kernel.sig
      1. 这时会报错,打开LPB100Kernel.exc,处理冲突函数并删掉开头处的注释
      2. 重新运行该条命令
  3. 将生成的LPB100Kernel.sig复制到ida安装目录\sig\arm\下

在IDA界面中通过Load File -> FLIRT signature file方式加载通过上面步骤生成的sig文件。之后就能生成如下效果了。

除了SDK中的库文件,Keil自带的C基础库在Keil安装目录下的ARMCC\arm\lib\中,可以按照同样过程生成sig文件,并加载至分析文件中。这样mem,str等基本的函数调用也会匹配上。

至此就能更方便的查看内部逻辑了。

0x03 感谢


piaca和redfree

http://www.devttys0.com/

0xFF 版权声明


本文独家首发于乌云知识库(drops.wooyun.org)。本文并没有对任何单位和个人授权转载。如本文被转载,一定是属于未经授权转载,属于严重的侵犯知识产权,本单位将追究法律责任。

智能设备逆向工程之外部Flash读取与分析篇的更多相关文章

  1. MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析

    MPC8313ERDB在Linux从NAND FLASH读取UBoot环境变量的代码分析 Yao.GUET@2014-05-19 一.故事起因 由于文件系统的增大,已经大大的超出了8MB的NOR FL ...

  2. 基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)

    在做一个用到ucGUI的项目的时候要用到不定的汉字和英文字符,但是ucGUI本身又不支持读取芯片外部flash的字库来显示,于是查了下资料,如下: http://www.cnblogs.com/hik ...

  3. STM32学习笔记(八) SPI总线(操作外部flash)

    1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...

  4. keil将程序装入外部FLASH具体解释

    在实际项目中,常常出现芯片的内部FLASH空间不够的情况,这就须要将程序分一部分装到外部FLASH中. 为了让大家能少走些弯路,在这里把我在这当中遇到的一些问题和经验教训给大家分享一下. 仅供參考,假 ...

  5. flash读取XML节点内容以及节点属性

    原文地址:http://hi.baidu.com/yqzdm/item/f95fd9d24679d916d90e44c9 一.xml的写法: 这里的xml只是在有限范围内的了解,限于写一些简单的用于f ...

  6. ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件

    源:ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件 如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash) ucgui的字库

  7. html外部文件读取/写入

    1.文件的读取 外部文件读取控件: <input type="file" id="file_jquery" onchange="file_jqu ...

  8. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台: ...

  9. 【转】android 电容屏(三):驱动调试之驱动程序分析篇

    关键词:android  电容屏 tp 工作队列 中断 坐点计算  电容屏主要参数平台信息:内核:linux2.6/linux3.0系统:android/android4.0  平台:S5PV310( ...

随机推荐

  1. asp.net identity 2.2.0 中角色启用和基本使用(五)

    建立控制器UsersAdminController 第一步:在controllers文件夹上点右键>添加>控制器, 我这里选的是“MVC5 控制器-空”,名称设置为:UsersAdminC ...

  2. dubbo 试用全过程

    概述: dubbo服务容器是一个standalone的启动程序,因为后台服务不需要Tomcat或JBoss等Web容器的功能,如果硬要用Web容器去加载服务提供方,增加复杂性,也浪费资源. 服务容器只 ...

  3. [troubleshoot][archlinux][X] GPU HANG

    前言:如下内容已经是在hang完大概半个多月后了,当时想写,一直没过来写,写blog果然也是已经花费时间的事情. 最近一直在休假,电脑的使用频率也不多.后来还是为了生活,不情愿的去开始上班了,上班的第 ...

  4. js展开一颗树

    Tree View 指令不支持 树结构数据源, 只支持单层数组.(也许是我没发现,人家可以设置) .我只能把树展开,变成单层数组.然后还要记录已经递归到第一层了.比如这样. <!doctype ...

  5. Nhiberate (一)

    严重参考感谢:@wolfy 操作数据库一直都是直接写SQL语句, 接触的ORM框架也不多,新项目要用数据库,数据库访问采用NHibernate. 1. NHibernate 是基于.Net 的针对关系 ...

  6. Python之路-python(面向对象进阶)

    一.面向对象高级语法部分 1.静态方法.类方法.属性方法 2.类的特殊方法 3.反射 二.异常处理 三.Socket开发基础 一.面向对象高级语法部分 静态方法(@staticmethod) 定义:只 ...

  7. 字节流和字符流(InputStream类和OutputStream类)

    java流包括字节流和字符流,字节流通过I/O设备以字节数据的方式读入,而字符流则是通过字节流读入数据转换成字符"流"的形式由用户驱使. InputStream是所有字节输入流的父 ...

  8. 将java项目转换成Web项目

    http://www.cnblogs.com/kaige123/p/5866446.html 在项目上点击右键,进入Properties配置,点击Project Facets,再点击Convert t ...

  9. php Windows系统 wamp集成环境下redis的使用

    先说一下我的本地环境,使用的是wamp集成环境,(Apache 2.4.9.PHP 5.5.12.MySQL 5.6.17) windows下安装PHP扩展: 第一步:找到扩展文件(.dll),htt ...

  10. [课程设计]Scrum 2.8 多鱼点餐系统开发进度(下单一览页面-菜式一览功能的最终实现)

    Scrum 2.8 多鱼点餐系统开发进度 (下单一览页面-菜式一览功能的最终实现) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4.团队 ...