工具:ACR122U、Mifare One卡分析工具、Mifare 卡数据写入工具
实验对象:自己的饭卡
以下是从卡中读取出来的数据:
从图中可以看出卡片中有五个扇区加密了,每个扇区是4个区块。
第0个扇区(红色框)的第一个区块中的数据用于存放厂商代码,已经固化,无法修改。
第0个扇区的中间的两个数据块没有填写数据
第0个扇区的最后一个数据块是控制块,其中前六个字节为密码A,后六位为密码B,中间四位为存取控制。
下面对存取控制的四位进行分析,因为所有区块的存取控制位都使用了默认值 FF 07 80 69 ,所以就先分析吧。
十六进制: FF 07 80 69
换算成二进制:
1111 1111
0000 0111
1000 0000
0110 1001
根据下面的数据可得:
块0 : C10 C20 C30
块1 : C11 C21 C31
块2 : C12 C22 C32
块3 : C13 C23 C33
存取控制(4字节,其中字节 9为备用字节)结构如下所示:
bit 7 6 5 4 3 2 1 0
字节 6 | C23_b | C22_b | C21_b | C20_b | C13_b | C12_b | C11_b | C10_b |
字节 7 | C13 | C12 | C11 | C10 | C33_b | C32_b | C31_b | C30_b |
字节 8 | C33 | C32 | C31 | C30 | C23 | C22 | C21 | C20 |
字节 9 |
|
|
|
|
|
|
|
|
( 注: _b表示取反 )
则
C1X | C2X | C3X | |
X=0 | 0 | 0 | 0 |
X=1 | 0 | 0 | 0 |
X=2 | 0 | 0 | 0 |
X=3 | 0 | 0 | 1 |
又按照存取控制:数据块(块0 、块1、块 2)的存取控制如下:
控制位( X=0.1.2 )
| 访 问 条 件 (对数据块 0 、1 、 2) | ||||||
C1X | C2X | C3X | Read | Write | Increment | Decrement, transfer, Restore | |
0 | 0 | 0 | KeyA|B | KeyA|B | KeyA|B | KeyA|B | |
0 | 1 | 0 | KeyA|B | Never | Never | Never | |
1 | 0 | 0 | KeyA|B | KeyB | Never | Never | |
1 | 1 | 0 | KeyA|B | KeyB | KeyB | KeyA|B | |
0 | 0 | 1 | KeyA|B | Never | Never | KeyA|B | |
0 | 1 | 1 | KeyB | KeyB | Never | Never | |
1 | 0 | 1 | KeyB | Never | Never | Never | |
1 | 1 | 1 | Never | Never | Never | Never |
(KeyA|B 表示密码 A或密码B ,Never表示任何条件下不能实现)
例如:当块0的存取控制位 C10 C20 C30=1 0 0时,验证密码A或密码 B正确后可读;
验证密码B正确后可写;不能进行加值、减值操作。
控制块 块3 的存取控制与数据块(块0、 1、2 )不同,它的存取控制如下:
|
|
| 密码 A | 存取控制 | 密码 B | |||
C13 | C23 | C33 | Read | Write | Read | Write | Read | Write |
0 | 0 | 0 | N ever | KeyA|B | KeyA|B | N ever | KeyA|B | KeyA|B |
0 | 1 | 0 | N ever | Never | KeyA|B | N ever | KeyA|B | N ever |
1 | 0 | 0 | N ever | KeyB | KeyA|B | N ever | N ever | KeyB |
1 | 1 | 0 | N ever | Never | KeyA|B | N ever | N ever | N ever |
0 | 0 | 1 | N ever | KeyA|B | KeyA|B | KeyA|B | KeyA|B | KeyA|B |
0 | 1 | 1 | N ever | KeyB | KeyA|B | KeyB | N ever | KeyB |
1 | 0 | 1 | N ever | Never | KeyA|B | KeyB | N ever | N ever |
1 | 1 | 1 | N ever | Never | KeyA|B | Never | Never | Never |
例如:当块3的存取控制位 C13 C23 C33=1 0 0时,表示:
密码A:不可读,验证 KEYA或KEYB 正确后,可写(更改)。
存取控制:验证 KEYA或KEYB 正确后,可读、可写。
密码B:验证 KEYA或KEYB 正确后,可读、可写。
故此时:
区块0 | 验证密码A或B后可读、可写、可加、可减、可存储、可传输 |
区块1 | 验证密码A或B后可读、可写、可加、可减、可存储、可传输 |
区块2 | 验证密码A或B后可读、可写、可加、可减、可存储、可传输 |
区块3 | 密码A:永不可读,当验证密码A或B时可写 |
这些值都是卡的厂商设定的初始值,不知到学校为啥没有修改。
接下来分析其他数据:
这是原卡的内容:
此时将饭卡(余额:31.36)复制了一份,然后用原饭卡消费N次后,原饭卡的余额变为1.71元,这个时候出问题了,因为我刷我复制的饭卡,余额任然是31.36元,所以判定饭卡的余额是存储在饭卡上的。
此时再做一次对比,如下所示:
由上图对比分析可以看出:
由上图对比分析可以看出:
扇区0存了些卡片ID和厂商的代码,具体是哪个公司或者哪个型号我就不关心了。0区块存的是卡片的ID号(最前面的X1 X2 X3 X4 YY)<其实真正的ID只有4个字节,第五个字节DA是ID的校验码,校验方法选的是相邻两个字节相互异或,即:X1 xor X2 xor X3 xor X4 = YY >,08应该是卡片的大小8Kbit,04 00 逆序后是00 04是卡片的类型,后面的数据是厂商自定义的数据。
扇区1存的是学校的相关信息,其中
0区块存的是卡片的ID号(最前面的X1 X2 X3 X4 YY)
1区块存的是学校后勤集团的名字,西大当然就是西大后勤集团了。
2区块存的可能是后勤集团的负责人或者是当初办理饭卡的负责人(主观臆测滴,无可信度,个人觉得是办理饭卡的办理人,因为我测试了几张不同年级的学生的卡片,当然也就是办理时间不同了,结果这个名字都不相同,所以这个名字应该是后勤集团的办理卡片的人的名字)
3区块存的自然是密码了,不知道或许是这部分信息无关重要,所以学校没有修改这个扇区的B密码和控制权限:FF 07 80 69
扇区2存的是个人信息:其中
0区块存的是学生证号,X1 X2 32 01 02 00,此处采用的是逆序存储法,将该数据倒过来就是00 02 01 32 X2 X1,我的学生证号为20132X2X1,刚好对应。(不知为何此处十六进制和十进制之间没有转换,直接将十进制的数据写进来了,是为了方便?)
1区块存的是名字,我的名字:“慎为之”,3个汉字,每个汉字占2个字节,共留个字节,后面的都为空格。(十六进制的20对应十进制的32,也就是空格的ASIIC码值)。
2区块存的是:"学生证20132X2X1" ,当然这是我的学生证号,别人的就是:"学生证$学生证号"
3区块存的还是密码,难道我们的个人信息也不重要?为啥重新设置访问权限和B密码,如果是这样的话我就可以直接B密码通过验证然后进行操作了,食堂的漏洞?虽然食堂的服务器端有验证措施,后面会讲到,但这样做终归是不好的。
扇区3存的信息才是和Money相关的信息,想知道么?下面是分析:
0区块前四个字节存的是金额,第一个字节存的是小数点后面的,第二、三、四个字节存的是小数点前面的,不进行十进制和十六进制的转换,此处的36 31 00 00 表示余额为31.36元,第二幅图中的71 01 00 00 表示1.71元。第4-7字节是消费次数,不论是充值或者是消费,每充值一次或者是消费一次,该值都会加一,采用逆序存储。
后面的8-15字节存储的是数据很难分析,一下是一些观察到的规律:
1、存钱不对这些数据(后面8个字节)产生影响,所以这些位应该不是对数据的校验,也就是说这部分数据和前八个字节没有任何关系。
2、经对比分析,11和12字节(或许也包括13)是当天的消费金额。充值不对该数据产生影响,所以该数据应该只和消费有关。
3、第十五字节是十进制,代表年份,14表示2014年,第十四个字节表示是上次消费是今年的第多少天(目前值分析到该字节是16进制,且每天加一,在2014年6月4号当天我的饭卡上的该字节是0X94,转换为十进制后是148,但当天应该是第155(31+28+31+30+31+4=155)天,相差7天,不知该处为何相差刚好一周的时间。)。充值不对该数据产生影响,所以该数据应该只和消费有关。
4、第九和第十个字节应该是连在一起的一个什么数据,在随着消费增加也在增加,但是具体的关系还无法得到。充值不对该数据产生影响,所以该数据应该只和消费有关。另外该字节应该不是对余额或者消费次数(即前八个字节做校验)。
5、最后一个字节不知道是什么数据,充值不对该数据产生影响,所以该数据应该只和消费有关。
1区块不知存的什么数据,不过永远都不变是真的,不管你消费了还是充值了都是那串数字,不同的人的饭卡有不同的序列。
2区块存的数据和0相同
3区块密码
扇区4存的信息才是打水的信息:
0区块未使用,还是初始的全零
1区块存的是金额,是以没四个字节分开,该处的金额是以分为单位,比如卡上有10块钱的虚拟金额可以打水,那么0-3字节存的就是E8030000,换算成十进制就是1000,4-7字节存的是0-3字节数据取反,8-11存的还是0-3字节的内容,12-15字节存的数据是10 EF 10 EF,不知道是啥数据,也懒得分析,反正永远不变。。
2区块存的数据和1相同
3区块密码,不知道为何此处的密码倒是设置的挺安全的,A密钥和B密钥都修改过了。