唐朝实验室 · 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的缩写,可以在www.hex-rays.com/products/id…中找到相关的描述。简单的说就是通过建立库函数中使用汇编指令串以及各类引用的特征值匹配到当前当目标文件,标注出已知的各种函数名。当然定位函数,除了单纯指令串特征值外,诸如bindiff类插件也会通过函数内逻辑,和相互间调用关系来确定函数,这样的好处是提高库函数的命中范围和提高准确度。类似技术运用在函数定位上可以参见下面的插件:

github.com/devttys0/id…

针对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. CSR8675学习笔记:从外部Flash读取bin文件

    为了让CSR867x的开发更容易,现与思度科技联合推出CSR867x学习板[淘宝链接:思度科技CSR开发板]. 技术交流QQ群号:743434463 开发板会员QQ群号:725398389(凭订单号入 ...

  2. Cortex-M单片机下载数据到外部flash

    主机环境:Windows 10 64bit 开发环境:MDK 5.23 目标板:LPC54114 之前在NXP社区得到一块LPC54114的板卡,是由万利制作的,LPC54114是一款双核MCU,包含 ...

  3. STM32H743+CubeMX-QSPI+DMA读取外部FLASH(W25Q128JVSQ)

    文章目录 一.前言 二.硬件电路 三.CubeMX 3.1.Parameter Setting 3.2.GPIO Settings 3.3.MDMA Settings(重点) 3.4.CubeMX生成 ...

  4. emwin从外部flash中读取bmp图片显示

    在emwin中有提供了一个从外部读取图片数据进行显示的函数,如下: 而且提供了官方例程,不过官方历程中从外部读取是从外部文件系统中进行读取的bmp图片进行显示,官方例程如下 /* ********** ...

  5. Flash读取XML文件出现的中文乱码问题 flash读取外部中文时显示乱码的问题

    Flash读取XML文件出现的中文乱码问题    原因:中文乱码,不用说都是编码惹的祸.Flash是使用UTF-8编码的.而一般我们保存文本文件时(也就是XML文件),用的编码是GB2321.ANSI ...

  6. CC2640之OAD固件升级实操(使用外部Flash)

    CC2640之OAD固件升级(外置Flash) 转至zzfenglin的博客. 实验环境 1.软件: 协议栈版本:BLE-STACK SDK V2.2 Python版本:Python 2.7.x (v ...

  7. STM32 音频数据的Flash读取与DAC播放

    STM32 音频数据的Flash读取与DAC播放 STM32 音频数据的Flash读取与DAC播放 STM32 音频数据的Flash读取与DAC播放 一.题目内容 二.Flash地址空间数据读取 1. ...

  8. 6713_EMIF操作外部flash

    6713EMIF操作FLASH 1. 6713EMIF的特点 Ø       数据总线宽度:32位,有32条数据线D[31:0] Ø       存储空间:4个,#CE0-#CE3,对应地址为0x80 ...

  9. STM32H743+CubeMX-QSPI读写外部FLASH(W25Q128JVSQ)

    文章目录 一.前言 二.硬件电路 三.CubeMX 3.1.Clock Configuration 3.2.QUADSPI Parameter Settings 3.3.QSPI GPIO Setti ...

最新文章

  1. Livox 开源分享:关于激光雷达去畸变的那些事儿
  2. 【解决方案】MySQL-5.7.9 服务无法启动-“NET HELPMSG 3534”
  3. Python基础教程:函数的可变参数
  4. 第五十八期:AI艺术日渐繁荣,未来何去何从?
  5. hive 如何将数组转成字符串_教你如何将Power Logic的原理图转成Orcad的原理图
  6. linux文件i节点,深入理解linux中i节点(inode)
  7. JS高级——面向对象方式解决歌曲管理问题
  8. Security+ 学习笔记4 社会工程攻击
  9. android 应用中 assets 下文件的绝对路径
  10. 计算机基本应用Excel考题,excel考题_大学计算机基础期末考试试题word ppt excel的操作题_淘题吧...
  11. 【UCSC Genome Browser】比老东家还出名的基因组数据库
  12. 【转】芯片设计流程 芯片的设计原理图
  13. 调用登录接口返回“参数错误”
  14. No module named ‘_ssl‘
  15. JFinal和JBoot创建一个定时任务
  16. C++学习之路抓紧跑路版(七)-动态申请内存空间
  17. 【计算机网络】域名解析(DNS)过程
  18. 计算机仿真初审多长时间,普刊初审时间多久有回复
  19. java数字连连看实验报告_2019年全国高校计算机能力挑战赛初赛java语言解答
  20. 可动态迁移的 mysql 架构

热门文章

  1. python智能光环板_学而思编程推出全新智能学习系统,搭配多种硬件
  2. 百度SEO资源吧emlog模版全套源码
  3. linux 重复执行脚本,防止shell脚本重复执行的代码
  4. vue函数input输入值即请求,优化为用户输入完成之后再请求
  5. WordPress主题导航源码webstackpro-支持个人自定义本地保存
  6. linux VPS上装FTP
  7. CuteEditor 5.0 的使用
  8. 脚本(js)控制页面输入
  9. CSS3 Media Query实现响应式Web设计(针对不同移动设备宽度)
  10. Swift中文教程(十一) 方法