首页
社区
课程
招聘
[翻译]Mastercard(万事达卡)的互联网网关服务存在 Hash 设计漏洞,攻击者可以修改交易金额
2017-10-31 14:10 4919

[翻译]Mastercard(万事达卡)的互联网网关服务存在 Hash 设计漏洞,攻击者可以修改交易金额

2017-10-31 14:10
4919
 

目录

    去年我发现了Matercard网关服务使用的一个MD5 version方面的设计错误。该错误能导致随意修改交易金额。当时还奖励了我一笔费用。今年,他们改为使用HMAC-SHA256,但是又有一个问题,目前我还没有从Mastercard获得反馈。如果你指想知道这个Bug是什么,可以直接跳过问题介绍部分。

什么是MIGS

    当你在一个网站支付时,该网站尝试将他们的系统连接到一个中间的支付系统网关(跳转到另一个网站)。这个支付系统网关连接着多个支持系统。对于信用卡支付,支付系统网关会链接到另一个网关(其中有一个就是MIGS),再由这个网关和多个银行进行交互,并提供3DSecure服务。

如何工作的

MIGS的支付流程如下:

  1. 你从网上商店选择购买的物品。
  2. 结账时,输入信用卡号。
  3. 然后,信用卡号,金额,等信息被签名,然后浏览器将POST这些数据给中间支付系统网关。
  4. 中间支付系统网关,转换格式为MIGS需要的格式,签名(使用MIGS key),然后返会给浏览器,浏览器发送再POST请求给MIGS服务器。
  5. 如果没有请求3D Secure服务,则直接进行第6步。如果请求了,MIGS将把请求转发给银行,银行将查询OTP,之后生成一个HTML,将Data 以POST请求形式发送给MIGS。
  6. MIGS将返回一个签名后的数据给浏览器,同时将POST这些数据给中间网关。
  7. 中间网关将检查是否数据是被签名和有效的。如果无效,则产生一个错误的页面。
  8. 基于MIGS返回信息,支付系统网关将转发状态给网上商店。

注意:这些服务器之间的通信并不是直接进行交互的,而是通过用户的浏览器来进行的,但是所有的信息都被签名。理论上,如果签名和验证过程是正确的,则一切OK.但不幸的是,并不总是这样。

MIGS的MD5 哈希问题

该Bug十分简单,通常的HASH方法如下:

MD5(Server + Data)

这些数据都是类似于这样格式,对于每一个查询的参数,它都是以vpc_开头,排序,然后连接值,之间没有分隔符。举个例子,如果我们有如下数据:

Name: Joe
Amount: 10000
Card: 1234567890123456

vpc_Name=Joe&Vpc_Amount=10000&vpc_Card=1234567890123456

排序后:

vpc_Amount=10000
vpc_Card=1234567890123456
vpc_Name=Joe

获取值,连接:

100001234567890123456Joe

注意,如果将参数该为这样:

vpc_Name=Joe&vpc_Amount=1&vpc_Card=1234567890123456&vpc_B=0000

排序后:

vpc_Amount=1
vpc_B=0000
vpc_Card=1234567890123456789
vpc_Name=Joe

获取值,连接:

100001234567890123456Joe

MD5值是一样的。所以,当数据发送给MIGS时,我们可以在金额后插入一个额外的参数来“吃掉”最后的几个数字,或者在之前,“吃掉”前几个数字,则金额数量锐减,你只需要支付2 USD就可以买2000 USD的MacBook。中间网关和网上商店同样可以修复这个bug,只需检查MIGS返回的金额数量,来确保和请求的金额数量是一致的即可。对此问题,MasterCard奖励了我8500 USD。

HMAC-SHA256 哈希的问题

    新采用的HMAC-SHA256有一个问题,如果我们可以注入一个无效的值给中间支付系统网关,即可被利用。我测试过,至少一个支付网关(包括Fushion Payments)都有这个bug。我从Fusion Payments处获得了500 USD。但是它同样可以影响别的连接到MIGS的支付网关。
在新的版本中,他们增加了分隔符(&),额外的field 名字,不简单的只是值,而且采用了HMAC-SHA256方法,对于上面提到,同样的值,被哈希的数据如下:

Vpc_Amount=10000&vpc_Card=1234567890123456&vpc_Name=Joe

我们无法修改任何一处,每一项看起来都OK。但是如果一个值包含&或者=或者其它等特殊字符呢?在文档中,有这么一句话:

Note: The values in all name value pairs should NOT be URL encoded for the purpose of hashing.

 

"NOT"是重点。意味着如果我们有如下成员:

Amount=100
Card=1234
CVV=555

它将被HASH:HMAC(Amount=100&Card=1234&CVV=555),如果我们这样呢,在Amount中加入&=

Amount=100&Card=1234
CVV=555

它将被HASH: HMAC(Amount=100&Card=1234&CVV。和之前一样。
<br>
    当然,我认为可能文档出错了,也许它确实被encoded。但是我检查了MIGS的行为,行为正如文档中提到的。也许,他们不想处理不同的编码问题吧(比如,用%20替代+)。当然这个看起来不会有什么问题,任何无效的值会被MIGS检查,返回一个错误。但是,我检查了多个支付网关,并不是在自身服务端验证输入的有效性,他们只是简单的签名,然后转发给MIGS。在客户端使用JavaScript来实现检查是非常简单的,只需给数据签名,让MIGS来检查是否CardNumber是正确的,或者是错误的。在Fusion支付系统中,它正是这样做的,允许输入任意长度的任意字符给CVV,然后签名转发给MIGS。

利用

为了利用这个bug,我们需要构造一个字符串,是一个有效的请求,同时是也是可以有效的获得MIGS返回。我们无需连接到MIGS服务器,只需要强制客户端签名它们自己的数据。
一个基本的请求如下:

vpc_AccessCode=9E33F6D7&vpc_Amount=25&vpc_Card=Visa&vpc_CardExp=1717&vpc_CardNum=4599777788889999&vpc_CardSecurityCode=999&vpc_OrderInfo=ORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

一个基本的返回如下:

vpc_Message=Approved&vpc_OrderInfo=ORDERINFO&vpc_ReceiptNo=722819658213&vpc_TransactionNo=2000834062&vpc_TxnResponseCode=0&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

在Fusion 支付的问题中,该利用是通过注入vpc_CardSecurityCode(CVV)来实现的

vpc_AccessCode=9E33F6D7&vpc_Amount=25&vpc_Card=Visa&vpc_CardExp=1717&vpc_CardNum=4599777788889999&vpc_CardSecurityCode=999%26vpc_Message%3DApproved%26vpc_OrderInfo%3DORDERINFO%26vpc_ReceiptNo%3D722819658213%26vpc_TransactionNo%3D2000834062%26vpc_TxnResponseCode%3D0%26vpc_Z%3Da&vpc_OrderInfo=ORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

对于这个字符串,客户端/支付网关将产生正确的HASH。
现在,我们可以POST这些数据给客户端自身(没有去MIGS服务器),但是我们轻微的改动,使得客户端可以读取到正确的值,(大部分客户端只检查vpc_TxnResponseCodevpc_TransacationNo):

vpc_AccessCode=9E33F6D7%26vpc_Amount%3D25%26vpc_Card%3DVisa%26vpc_CardExp%3D1717%26vpc_CardNum%3D4599777788889999%26vpc_CardSecurityCode%3D999&vpc_Message=Approved&vpc_OrderInfo=ORDERINFO&vpc_ReceiptNo=722819658213&vpc_TransactionNo=2000834062&vpc_TxnResponseCode=0&vpc_Z=a%26vpc_OrderInfo%3DORDERINFO&vpc_SecureHash=THEHASH&vpc_SecureHashType=SHA256

注意:

  1. 这个和之前的数据一样被HASH。
  2. 客户端不检查vpc_AccessCode和它的值。
  3. 客户端只检查vpc_TxnResonseCode等,同时假设交易是有效的。

可以说,这个是MIGS客户端的bug,但是是MasterCard哈希方法的选则导致这个问题的产生,一旦value被encoded,则该bug将不可能被利用。

支付网关中的问题

    额外提一下:即使支付网关负责处理金钱事务,但是并没有人们想想的那么安全。在我的pentest中,我发现多个支付协议设计上的问题。不幸的是,我无法在此处详细介绍。同时还发现了在实现上的一些问题。比如,Hash长度扩展攻击,XML 签名验证错误等。
    在Fusion Payment中,一个bug是,他们甚至没有检查MIGS的签名。即意味着,我们可以随意修改MIGS返回的数据,同时标注交易成功。只需要简单的将一个字符从F(false)改为o(success)。故基本上,我们只需要输入任意的信用卡号,获取一个失败的MIGS相应,修改为成功,则支付就成功了。这是一个 2千万USD的公司,对于这个bug我却只得到了400 USD。
    这并不是唯一有这个问题的支付网关,在我的pentest中,我在另一个payment中也发现了同样的问题。

结论

    支付网关并没有你想的那么安全。同时如此低的赏金,我怀疑有多少人已经开始利用了这些问题。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

收藏
点赞1
打赏
分享
最新回复 (1)
雪    币: 1790
活跃值: (2972)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
拍拖 2 2018-1-11 13:49
2
0
请教下译文中反馈的“MD5值是一样的”是“MD5值碰撞”吗?可以那么容易产生碰撞吗?
游客
登录 | 注册 方可回帖
返回