小区门禁卡需要升级了,我不得不把卡片信息从手机里重新写到物业发的门禁卡中,正好记录关于MifareOne卡片的相关资料,之前玩Arduino时折腾过,但是现在都忘记了
卡片的芯片M1,是恩智浦公司(Phillips旗下子公司)的一种广泛应用的芯片,各种小区门禁卡、会员卡、包括学校食堂的饭卡水卡有很多都是M1卡片。(虽然M1本身也有很多安全漏洞)
工作原理
读卡器会不断发出携带有信息和一定能量的射频信号,当M1卡片靠近时,卡内的线圈会从射频信号中获取能量,给卡内的电容充电,电压达到一定阈值以后,卡内的芯片就会开始工作,给读卡器返回响应的信息,进行数据传输。当有多张卡位于读卡器射频范围内时,读卡器可以选中其中一张卡进行通信。
技术参数
- EEPROM:1K字节
- 工作频率:13.65 mhz
- 读写速率:106 kbps
扇区结构
M1卡内部有一个1Kb字节的EEPROM,分成16个扇区,每个扇区再分为4个块,每个块拥有16个字节的存储空间。
可以参考我制作的结构图片:(这是我所在小区的门禁卡的Dump数据)
其中第0扇区的0块一般用于存放厂商代码(序列号),已经固化,无法修改(下图中黄色标识),除了第一扇区可用空间为2x16=32字节以外,其它扇区都是3x16=48字节。未被使用字节使用白色表示,可以看到只有扇区1里面存储了部分数据,其它扇区都是未使用状态。(已被使用的字节使用深绿色表示)
每个扇区内块0-3(Block)是数据块,顾名思义就是用来存储数据的地方,而最后的块3(Block)则是控制块,就是用来控制数据块的读写权限的。
控制块分3个部分:密码A
、读写控制位
、密码B
。
- 密码A永远不可读取,但可以修改
- 密码B则可读可写
- 读写控制位会对0-3块的每个块单独设置读写权限
- 如果两个密码都忘记了,整个扇区就相当于锁死了,无法修改(但仍然有后门操作可以找回)
- 每个扇区都有自己独立的密码A和密码B,一个扇区的密码丢失不会对其它扇区造成影响。
每个块的读写权限由3个控制位组成
读写控制 | 控制位1 | 控制位2 | 控制位3 |
---|---|---|---|
块0 | C01 | C02 | C03 |
块1 | C11 | C12 | C13 |
块2 | C21 | C22 | C23 |
块3 | C31 | C32 | C33 |
而每个块的3个控制位分别存储在读写控制字节
(上图中紫色的部分)中不同的位置。带有^
标记表示需要取反存储
控制字节 | 位7 | 位6 | 位5 | 位4 | 位3 | 位2 | 位1 | 位0 |
---|---|---|---|---|---|---|---|---|
字节6 | ^C32 | ^C22 | ^C12 | ^C02 | ^C31 | ^C21 | ^C11 | ^C01 |
字节7 | C31 | C21 | C11 | C01 | ^C33 | ^C23 | ^C13 | ^C03 |
字节8 | C33 | C23 | C13 | C03 | C32 | C22 | C12 | C02 |
字节9 | - | - | - | - | - | - | - | - |
有意思的是字节9不参与任何读写控制,它的值似乎总是0x69(1101001),可能是行业惯例。
控制位由3个bit组成,不同的控制位组合在一起会有不同的权限策略,下方列出了数据块(0-2块)的读写权限表和控制块(3块)的读写权限表。
数据块的读写权限表
AB
表示密码A或者密码B都可以执行这个操作,B
代表只有密码B才能执行这个操作,-
代表无论密码A还是B都无法执行这个操作。M1芯片除了支持直接读写以外,还支持增加操作和减少操作。
控制位1 | 控制位2 | 控制位3 | 读操作 | 写操作 | 加操作 | 减操作 |
---|---|---|---|---|---|---|
0 | 0 | 0 | AB | AB | AB | AB |
0 | 1 | 0 | AB | - | - | - |
1 | 0 | 0 | AB | B | - | - |
1 | 1 | 0 | AB | B | B | AB |
0 | 0 | 1 | AB | - | - | AB |
0 | 1 | 1 | B | B | - | - |
1 | 0 | 1 | B | - | - | - |
1 | 1 | 1 | - | - | - | - |
例如:100表示:
- 读操作:AB密码均可
- 写操作:需要B密码
- 加操作:AB密码均无法执行
- 减操作:AB密码均无法执行
控制块的读写权限表
控制块有自己独立的一套权限表,并不和数据块一致
AB
表示密码A或者密码B都可以执行这个操作,B
代表只有密码B才能执行这个操作,-
代表无论密码A还是B都无法执行这个操作。
控制位1 | 控制位2 | 控制位3 | 读密码A | 写密码A | 读"读写控制"位 | 写"读写控制"位 | 读密码B | 写密码B |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | - | AB | AB | - | AB | AB |
0 | 1 | 0 | - | - | AB | - | AB | - |
1 | 0 | 0 | - | B | AB | - | - | B |
1 | 1 | 0 | - | - | AB | - | - | - |
0 | 0 | 1 | - | AB | AB | AB | AB | AB |
0 | 1 | 1 | - | B | AB | B | - | B |
1 | 0 | 1 | - | - | AB | B | - | - |
1 | 1 | 1 | - | - | AB | - | - | - |
例如:101表示:
- 读密码A:AB密码无法读取
- 写密码A:AB密码无法写入
- 读"读写控制"位:AB密码均可
- 写"读写控制"位:需要B密码
- 读密码B:AB密码无法读取
- 写密码B:AB密码无法读取
关于UID/FUID/CUID卡
普通的MifareOne卡的0扇区0块在出场之前就已经被固化,无法修改,一般是存储厂商编号和卡的序列号,有些时候读卡器不仅会验证卡内的数据,也会验证卡的序列号,如果使用了克隆卡,就会认证失败。
接着UID卡就出现了,UID卡和普通IC卡最大的区别就是0扇区0块可以擦写,由此可以伪造任何一张卡的卡号,但是许多读卡器在读卡时会对卡片发出特殊指令,如果卡片响应了这个特殊指令,则代表这是一张UID卡,读卡器就会认证失败,如果没有响应,读卡器就会以为是一张普通IC卡。
再后来出现了CUID卡,和UID卡的区别在于不会响应读卡器的特殊指令,看起来就和普通IC卡一样。
FUID卡比较特殊一点,它的0扇区只能写入一次,写入之后就和普通IC卡一样了,也不会响应后门指令
还有另外一种比较高级的UFUID卡,用特殊指令封卡之后就变成了一张普通IC卡,再用特殊指令解封之后就变成了一张UID,可以灵活切换
浅谈防御攻击
因为M1卡片有安全漏洞,导致能容易被破解,即使是普通的Arc122u或者PN532都能在某些情况下轻松完成破解工作。
一般的攻击方式是获取整张卡的Dump数据以后分析数据格式,然后修改金额达到破解的目的,或者给卡片做一个Dump(可以理解为快照),刷卡扣钱以后再把快照恢复,这样就可以无限刷卡了,这就是典型的重放攻击。
防御方式有很多种,最最简单的就是使用复杂的加密算法加密卡内的数据,使用冗余位进行校验,验证是否为UID卡和卡号,最后是给所有扇区修改默认密码,无论是否存储了数据(M1卡有典型的知一密解全密的漏洞),不过这样仍然不能达到绝对的安全,因为如果使用专业的Proxmark3等设备,甚至能利用监听模式破解全加密的卡片。
最安全也是最保险的方式是让读卡器联网验证,确保数据的安全性,卡片本身只保存一个卡号,或者再激进一点,将校验数据加密后保存到卡片里,每次读卡时不仅要校验卡号,还要校验卡内的校验数据,来确保卡片本身没有修改过。
在金融领域,早已不再使用安全性欠佳的M1卡片,而是使用磁条卡等接触式安全性更高的卡片,卡片内部的芯片也不再是简单的存储芯片,而是复杂的CPU卡,可以使用更复杂的加密算法来确保交易的安全。