Cool-Y.github.io/source/_posts/小米固件工具mkxqimage.md
2019-07-25 22:22:26 +08:00

81 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 小米固件工具mkxqimage
date: 2019-03-16 14:57:56
tags:
- 小米
- 文件格式
- SSH
categories:
- IOT
---
# 小米固件工具mkxqimage
小米自己改了个打包解包固件的工具,基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能,路由系统里自带:
```
Usage:
mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]]
[-x file]
[-I]
```
## 固件打包
小米官方在打包固件时用RSA私钥计算出固件的RSA签名小米路由器下载固件后用RSA公钥来验证RSA签名有效地防止固件被篡改。
## 固件解包
固件工具mkxqimage完成对固件的解包在解包前先检查Checksum是否正确然后利用RSA公钥/usr/share/xiaoqiang/public.pem检查RSA签名这两个步骤通过后根据[0x0C]的固件类型,以及[0x10]、[0x14]、[0x18]和[0x1C]的4个偏移量拆分固件。
## 固件更新签名校验
小米路由器进行固件更新时同样会进行签名校验,文件/usr/share/xiaoqiang/public.pem是它的公钥用来校验签名正确与否。正因为这样黑客如果想在不拆机的前提下刷入已植入木马的固件只有两条路可走一是通过入侵、社工或破解得到对应的私钥然后对修改后的固件进行签名再刷入二是通过漏洞挖掘新的漏洞或者刷入有漏洞的旧版固件然后再通过漏洞利用得到root shell进而刷入任意固件。一般来讲第一条路是很难的而为了堵住第二条路可以通过限制降级来实现。
由此可见,在限制降级的前提下,在固件更新时进行签名校验,能有效地防止路由器被植入木马。
## [固件格式](http://www.iptvfans.cn/wiki/index.php/%E5%B0%8F%E7%B1%B3%E8%B7%AF%E7%94%B1%E5%99%A8%E5%9B%BA%E4%BB%B6%E5%88%86%E6%9E%90)
路由固件的格式,基本是基于 openwrt 的 trx 这个简单的二进制文件格式
```
48 44 52 30 63 D4 11 03 FE 3D 1A FD 05 00 02 00
20 00 00 00 20 00 FE 00 00 00 00 00 00 00 00 00
FF 04 00 EA 14 F0 9F E5 14 F0 9F E5 14 F0 9F E5
```
第14字节ASCII字符串“HDR0”作为固件的标识
第58字节4字节整型数0x0311D464表示固件的大小51500132字节
第9~12字节固件的检查和
第1314字节0x0005表示固件中包含哪些部分
第1516字节0x0002表示固件格式版本号
第1720字节0x00000020表示固件第一部分在整个固件中的偏移量0.4.85固件的第一部分是brcm4709_nor.bin也就是Flash中除0xfe0000-0xff0000的board_data外的全镜像
第2124字节0x00FE0020表示固件第二部分在整个固件中的偏移量0.4.85固件的第二部分是root.ext4.lzma也就是硬盘中128M固件的压缩包
第33字节开始是固件的正式内容开始。
## 小米开启ssh工具包
使用mkxqimage解包
(现在会提示秘钥不存在)
```
error fopen public key
Image verify failed, not formal image
```
如果能解包应该可以得到脚本文件upsetting.sh
```
#!/bin/sh
nvram set ssh_en=1
nvram set flag_init_root_pwd=1
nvram commit
```
执行脚本文件upsetting.sh后将ssh_en设置为1同时设置了flag_init_root_pwd项。当正式启动时/usr/sbin/boot_check脚本检测到flag_init_root_pwd=1时自动修改root用户密码具体脚本为
```
flg_init_pwd=`nvram get flag_init_root_pwd`
if [ "$flg_init_pwd" = "1" ]; then
init_pwd=`mkxqimage -I`
(echo $init_pwd; sleep 1; echo $init_pwd) | passwd root
nvram unset flag_init_root_pwd
nvram commit
fi
```
初始密码是mkxqimage -I的结果实际是根据路由器的序列号计算得到。路由器的序列号印在底盖上12位数字561000088888
初始密码计算算法为:
`substr(md5(SN+"A2E371B0-B34B-48A5-8C40-A7133F3B5D88"), 0, 8)`
***A2E371B0-B34B-48A5-8C40-A7133F3B5D88*** 为分析mkxqimage得到的salt