当你在一个网站支付时,该网站尝试将他们的系统连接到一个中间的支付系统网关(跳转到另一个网站)。这个支付系统网关连接着多个支持系统。对于信用卡支付,支付系统网关会链接到另一个网关(其中有一个就是MIGS),再由这个网关和多个银行进行交互,并提供3DSecure服务。
MIGS的支付流程如下:
注意:这些服务器之间的通信并不是直接进行交互的,而是通过用户的浏览器来进行的,但是所有的信息都被签名。理论上,如果签名和验证过程是正确的,则一切OK.但不幸的是,并不总是这样。
该Bug十分简单,通常的HASH方法如下:
这些数据都是类似于这样格式,对于每一个查询的参数,它都是以vpc_
开头,排序,然后连接值,之间没有分隔符。举个例子,如果我们有如下数据:
排序后:
获取值,连接:
注意,如果将参数该为这样:
排序后:
获取值,连接:
MD5值是一样的。所以,当数据发送给MIGS时,我们可以在金额后插入一个额外的参数来“吃掉”最后的几个数字,或者在之前,“吃掉”前几个数字,则金额数量锐减,你只需要支付2 USD就可以买2000 USD的MacBook。中间网关和网上商店同样可以修复这个bug,只需检查MIGS返回的金额数量,来确保和请求的金额数量是一致的即可。对此问题,MasterCard奖励了我8500 USD。
新采用的HMAC-SHA256有一个问题,如果我们可以注入一个无效的值给中间支付系统网关,即可被利用。我测试过,至少一个支付网关(包括Fushion Payments)都有这个bug。我从Fusion Payments处获得了500 USD。但是它同样可以影响别的连接到MIGS的支付网关。
在新的版本中,他们增加了分隔符(&),额外的field 名字,不简单的只是值,而且采用了HMAC-SHA256方法,对于上面提到,同样的值,被哈希的数据如下:
我们无法修改任何一处,每一项看起来都OK。但是如果一个值包含&
或者=
或者其它等特殊字符呢?在文档中,有这么一句话:
Note: The values in all name value pairs should NOT be URL encoded for the purpose of hashing.
"NOT"
是重点。意味着如果我们有如下成员:
它将被HASH:HMAC(Amount=100&Card=1234&CVV=555)
,如果我们这样呢,在Amount中加入&
和=
。
它将被HASH: HMAC(Amount=100&Card=1234&CVV
。和之前一样。
<br>
当然,我认为可能文档出错了,也许它确实被encoded
。但是我检查了MIGS的行为,行为正如文档中提到的。也许,他们不想处理不同的编码问题吧(比如,用%20替代+)。当然这个看起来不会有什么问题,任何无效的值会被MIGS检查,返回一个错误。但是,我检查了多个支付网关,并不是在自身服务端验证输入的有效性,他们只是简单的签名,然后转发给MIGS。在客户端使用JavaScript来实现检查是非常简单的,只需给数据签名,让MIGS来检查是否CardNumber是正确的,或者是错误的。在Fusion支付系统中,它正是这样做的,允许输入任意长度的任意字符给CVV,然后签名转发给MIGS。
为了利用这个bug,我们需要构造一个字符串,是一个有效的请求,同时是也是可以有效的获得MIGS返回。我们无需连接到MIGS服务器,只需要强制客户端签名它们自己的数据。
一个基本的请求如下:
一个基本的返回如下:
在Fusion 支付的问题中,该利用是通过注入vpc_CardSecurityCode(CVV)
来实现的
对于这个字符串,客户端/支付网关将产生正确的HASH。
现在,我们可以POST这些数据给客户端自身(没有去MIGS服务器),但是我们轻微的改动,使得客户端可以读取到正确的值,(大部分客户端只检查vpc_TxnResponseCode
和vpc_TransacationNo
):
注意:
可以说,这个是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中也发现了同样的问题。
支付网关并没有你想的那么安全。同时如此低的赏金,我怀疑有多少人已经开始利用了这些问题。
MD5(Server + Data)
Name: Joe
Amount: 10000
Card: 1234567890123456
vpc_Name=Joe&Vpc_Amount=10000&vpc_Card=1234567890123456
vpc_Amount=10000
vpc_Card=1234567890123456
vpc_Name=Joe
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!