- A+
本文介绍一个NFC卡简单破解的全部流程,并对破解过程中的读写原理进行探讨。在逆向分析中,我们会接触多种多样的工具,在使用工具的同时,希望大家思考一下原理,便于更深入的进行了解和学习。
注:本文内容仅做技术研究,请勿用于非法用途,否则后果自负。
目录:
0x1.工具及卡片介绍
0x2.卡片信息读取
0x3.卡片数据分析及修改
0x4.卡片信息写入
接下来步入正题,先从背景介绍开始。之前购得ACR122U之后闲置了一段时间,最近办理了一张餐饮消费会员卡,于是忍不住拿来分析一下。
先说一下会员卡,该卡片是M1卡。
所谓的M1芯片,是指菲利浦下属子公司恩智浦出品的芯片缩写,全称为NXP Mifare1系列,常用的有S50及S70两种型号,截止到2013年11月4日,已经有国产芯片与其兼容,利用PVC封装M1芯片、感应天线,然后压制成型后而制作的卡即是智能卡行业所说的M1卡。
工具是读写器硬件设备ACR122U以及配套的用于读写的PC软件。
ACR122U NFC读写器是一款基于13.56 MHz非接触(RFID)技术开发出来的连机非接触式智能卡读写器。它符合ISO/IEC18092近场通信(NFC)标准,支持Mifare®卡、ISO 14443 A类和B类卡、以及全部四种NFC标签。
为了确定该读写器的主芯片,将其拆解,确认读写的主芯片为NXP(恩智浦)的PN532:
0x2.1 卡片信息读取
该设备的提供的读取程序为M1卡服务程序:
电脑安装驱动以后,连接读卡器,卡片靠近读卡器,选择读卡器后,点击开始破解,即可等待破解完成。完成后我们就可以拿到M1卡的二进制文件信息,文件扩展名为dump,大小为1KB。
下图为读取到的dump文件及分析结果标注:
我们先了解一下M1卡的存储结构,M1卡分为16个扇区,每个扇区由4块(块0、块1、块2、块3)组成,存储结构如图所示:
其中第0扇区用于存储卡片的UID信息以及厂商写入的信息,一般不需要我们分析修改;
每个扇区的块0、块1、块2为数据块,可以用于存储数据;
块3位控制块,由密码A、存取控制(控制字)、密码B组成,且每个扇区的密码和存取控制都是独立的,即 每个扇区都有自己的密码。
FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF // 密码A | 存取控制 | 密码B
接下来我们看一下我们读取到的数据,将dump文件使用十六进制编辑器打开
第0扇区我们暂不理会,显然,数据基本存储在第10扇区与第11扇区,且两个扇区的控制块是相同的,后续我们着重分析这两个扇区。
0x2.2 PN532读写过程
对于PN532而言,读取过程又是怎样的呢?我们先来了解一下PN532。
PN532由NXP出品,是一款高度集成的载波的13.56MHz传输模块,基于80C51内核有40KROM、1KRAM。 使用不同的固件支持13.56MHz频段的无线协议。
这里我们介绍一下ACR122U对M1卡的读写卡流程:
// 【初学者仅作了解】 // 1.唤醒PN532 PC->PN532: 55 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 FD D4 14 01 17 00 PN532->PC: 00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00 // 唤醒的数据包头为固定格式 // 2.获取卡UID PC->PN532: 00 00 FF 04 FC D4 4A 02 00 E0 00 // 析: // 04 -> 代表有四个数据分别是 D4 4A 02 00 // FC -> 这是04的补码 // 4A -> 命令 // 02 -> 卡数量,0--2 // 00 -> 波特率 106K // E0 -> 校验位 D4+4A+02+00=0x0120 取后两位20的补码为E0 PN532->PC: 00 00 FF 00 FF 00 00 00 FF 0C F4 D5 4B 01 01 00 04 08 04 86 7D C9 56 06 00 // 析: // 00 00 FF 00 FF 00 -> ACK // 00 00 FF 0C F4 // D5 -> PN532 到 MCU // 4B -> 响应命令 // 01 -> 目标卡1 // 01 -> 目标卡数量,最大为0x02,最小为0 // 00 04 -> ATQ // 08 -> 卡容量 08=1K // 04 -> 4个字节UID // 86 7D C9 56 -> UID // 06 00 -> DCS+POST // 3.秘钥验证 PC->PN532: 00 00 FF 0F F1 D4 40 01 60 07 FF FF FF FF FF FF 86 7D C9 56 C2 00 // 析: // 40 -> 命令 // 01 -> 卡1 // 60 -> 密钥验证命令 // 07 -> 块号 // FF FF FF FF FF FF -> 密钥 // 86 7D C9 56 -> UID // C2 -> 检验位 PN532->PC: 00 00 FF 00 FF 00 00 00 FF 03 FD D5 41 00 EA 00 // 析: 41 00 -> 正确状态 // 4.开始读卡 PC->PN532: 00 00 FF 05 FB D4 40 01 30 06 B5 00 //读第6块 PC->PN532: 00 00 FF 05 FB D4 40 01 30 07 B4 00 //读第7块 PC->PN532: 00 00 FF 05 FB D4 40 01 30 08 B3 00 //读第8块 // 析: // 40 -> 命令 // 01 -> 卡1 // 30 -> 读卡命令 // 06 -> 块号 PN532->PC: 00 00 FF 00 FF 00 //ACK 00 00 FF 13 ED D5 41 00 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF 01 00 //7块 PN532->PC: 00 00 FF 00 FF 00 //ACK 00 00 FF 13 ED D5 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 EA 00 //6块 // 析: // 41 00 -> 正确 // 41 03 -> 错误 // 5.写卡操作 PC->PN532: 00 00 ff 15 EB D4 40 01 A0 06 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F CD 00 // 析: // 40 -> 命令 // 01 -> 卡1 // A0 -> 写卡命令 // 06 -> 块号 // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F -> 16字节数据 // CD -> 校验和 PN532->PC: 00 00 00 FF 00 FF 00 00 00 FF 03 FD D5 41 00 EA 00 // 析: // 41 00 -> 正确
PN532读写过程均已经介绍,卡片信息写入时仅介绍操作,不再赘述原理。
分析过程我们需要取多组数据,进行分析来确认不同数据所代表的的意义,此处我们仅分析第10及第11两个扇区。
根据上图内容,我们可以看到,10扇区的块0没有数据,10扇区块2和11扇区块0相同,11扇区的块1和块2相同,所以我们仅仅分析10扇区块1,11扇区块0和块1。
接下来我们对比不同余额时对应的数据:
// 余额319.4 # 扇区10块1 01 00 01 00 00 05 FD 20 05 04 00 00 6D B7 00 51 # 扇区11块0及块1 17 10 30 00 00 00 00 00 00 00 00 00 00 00 00 57 00 00 00 26 00 00 7C C4 FF FF 83 3B 00 00 00 22 // 余额298.6 # 扇区10块1 01 00 01 00 00 05 FD 20 05 04 00 00 6D B7 00 51 # 扇区11块0及块1 17 10 30 00 00 00 00 00 00 00 00 00 00 00 00 57 00 00 00 27 00 00 74 A4 FF FF 8B 5B 00 00 00 23
根据数据结果,我们可以看出,在消费后,只有11扇区块1(块2相同)发生了变化。
其中余额319.4及298.6,以分为单位是31940和29860,转化为十六进制为 0x7CC4和0x74A4,恰好可以与11扇区中块1中的数据对应。
// 余额298.6 # 扇区11块1 00 00 00 27 00 00 74 A4 FF FF 8B 5B 00 00 00 23 # 27和23为计数,每消费一次增加1 # 00 00 74 A4 为余额数据 # FF FF 8B 5B 为余额校验数据,为余额取反
我们继续看下扇区10块1
// 余额298.6 # 扇区10块1 01 00 01 00 00 05 FD 20 05 04 00 00 6D B7 00 51 #卡片上印刷的卡号为28087,对应十六进制为0x6DB7,恰好与扇区10块1对应
至此数据基本分析完毕,我们来尝试写入看结果如何。
我们把余额改为600,也就是60000分,十六进制为0xEA60,取反为0x159F,修改如下:
// 余额298.6修改为600 # 扇区11块1,修改前 00 00 00 27 00 00 74 A4 FF FF 8B 5B 00 00 00 23 # 扇区11块1,修改前 00 00 00 27 00 00 EA 60 FF FF 15 9F 00 00 00 23
修改后保存dump文件,使用MiFare Card Programming工具将其写入到卡中
需要注意的是,每个扇区需要有本身对应的密码才可以写入。
【补充】
写入更改后的余额后,测试可正常消费,为避免因卡号记录追溯到用户信息,可以更改卡号信息,即扇区10块1中的6DB7可以更改,更改后需要同时更改块1的末尾数据,因为末尾的数据51为校验位,是块1的前15位数据取和后获得的值,请大家根据情况自行理解分析,此处不作赘述。
PS: 相关问题已反馈商家,请大家在学习技术的同时,不要让利益污染了技术。