M1卡分析

工具:ACR122UMifare 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 12 )不同,它的存取控制如下:

  

 

 

 

密码 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:不可读,验证 KEYAKEYB 正确后,可写(更改)。

         存取控制:验证 KEYAKEYB 正确后,可读、可写。

           密码B:验证 KEYAKEYB 正确后,可读、可写。



 故此时:

区块0

验证密码AB后可读、可写、可加、可减、可存储、可传输

区块1

验证密码AB后可读、可写、可加、可减、可存储、可传输

区块2

验证密码AB后可读、可写、可加、可减、可存储、可传输

区块3

密码A:永不可读,当验证密码AB时可写
密码B:当验证密码AB时可读可写
存取控制:当验证密码AB时可读可写。


这些值都是卡的厂商设定的初始值,不知到学校为啥没有修改。




接下来分析其他数据:

这是原卡的内容:

此时将饭卡(余额:31.36)复制了一份,然后用原饭卡消费N次后,原饭卡的余额变为1.71元,这个时候出问题了,因为我刷我复制的饭卡,余额任然是31.36元,所以判定饭卡的余额是存储在饭卡上的。

此时再做一次对比,如下所示:



由上图对比分析可以看出:

由上图对比分析可以看出:

扇区0存了些卡片ID和厂商的代码,具体是哪个公司或者哪个型号我就不关心了。0区块存的是卡片的ID号(最前面的X1 X2 X3 X4 YY<其实真正的ID只有4个字节,第五个字节DAID的校验码,校验方法选的是相邻两个字节相互异或,即:X1 xor X2 xor X3 xor X4 = YY >08应该是卡片的大小8Kbit04 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、经对比分析,1112字节(或许也包括13)是当天的消费金额。充值不对该数据产生影响,所以该数据应该只和消费有关。

3、第十五字节是十进制,代表年份,14表示2014年,第十四个字节表示是上次消费是今年的第多少天(目前值分析到该字节是16进制,且每天加一,在201464号当天我的饭卡上的该字节是0X94,转换为十进制后是148,但当天应该是第15531+28+31+30+31+4=155)天,相差7天,不知该处为何相差刚好一周的时间。)。充值不对该数据产生影响,所以该数据应该只和消费有关。

4、第九和第十个字节应该是连在一起的一个什么数据,在随着消费增加也在增加,但是具体的关系还无法得到。充值不对该数据产生影响,所以该数据应该只和消费有关。另外该字节应该不是对余额或者消费次数(即前八个字节做校验)。

5、最后一个字节不知道是什么数据,充值不对该数据产生影响,所以该数据应该只和消费有关。

1区块不知存的什么数据,不过永远都不变是真的,不管你消费了还是充值了都是那串数字,不同的人的饭卡有不同的序列。

2区块存的数据和0相同

3区块密码

扇区4存的信息才是打水的信息:

0区块未使用,还是初始的全零

1区块存的是金额,是以没四个字节分开,该处的金额是以分为单位,比如卡上有10块钱的虚拟金额可以打水,那么0-3字节存的就是E8030000,换算成十进制就是10004-7字节存的是0-3字节数据取反,8-11存的还是0-3字节的内容,12-15字节存的数据是10 EF 10 EF,不知道是啥数据,也懒得分析,反正永远不变。。

2区块存的数据和1相同

3区块密码,不知道为何此处的密码倒是设置的挺安全的,A密钥和B密钥都修改过了。



posted on 2016-05-10 21:04  C语言程序设计  阅读(3474)  评论(0编辑  收藏  举报

导航