相关知识

首页 > 相关知识 > 正文

谈谈微信支付曝出的漏洞

2018年11月10日 热度:317 ℃

一、背景

(2018-07-04)微信支付的SDK曝出重大漏洞(XXE漏洞),通过该漏洞,攻击者可以获取服务器中目录结构、文件内容,如代码、各种私钥等。获取这些信息以后,攻击者便可以为所欲为,其中就包括众多媒体所宣传的“0元也能买买买”。

二、漏洞原理

1.  XXE漏洞

此次曝出的漏洞属于XXE漏洞,即XML外部实体注入(XML External Entity Injection)。

XML文档除了可以包含声明和元素以外,还可以包含文档类型定义(即DTD);如下图所示。

在DTD中,可以引进实体,在解析XML时,实体将会被替换成相应的引用内容。该实体可以由外部引入(支持http、ftp等协议,后文以http为例说明),如果通过该外部实体进行攻击,就是XXE攻击。

可以说,XXE漏洞之所以能够存在,本质上在于在解析XML的时候,可以与外部进行通信;当XML文档可以由攻击者任意构造时,攻击便成为可能。在利用XXE漏洞可以做的事情当中,最常见最容易实现的,便是读取服务器的信息,包括目录结构、文件内容等;本次微信支付爆出的漏洞便属于这一种。

本次漏洞影响的范围是:在微信支付异步回调接口中,使用微信支付SDK进行XML解析的应用。注意这里的SDK是服务器端的SDK,APP端使用SDK并不受影响。

SDK中导致漏洞的代码是WXPayUtil工具类中的xmlToMap()方法:

如上图所示,由于在解析XML时没有对外部实体的访问做任何限制,如果攻击者恶意构造xml请求,便可以对服务器进行攻击。下面通过实例介绍攻击的方法。

3.  攻击复现

下面在本机环境下进行复现。

假设本地的web服务器127.0.0.1:8080中存在POST接口:/wxpay/callback,该接口中接收xml字符串做参数,并调用前述的WXPayUtil.xmlToMap(strXml)对xml参数进行解析。此外,/etc/password中存储了重要的密码数据(如password1234)。

攻击时构造的请求如下:

其中xml内容如下:

1

2

3

4

5

6

"1.0"

encoding=

"utf-8"

?>

"file:///etc/password"

>

>

%xxe;

]>

1

2

3

""

>

%shell;

%upload;

这样,攻击者便得到了/etc/password文件的内容。

在本例中,攻击者窃取了/etc/password文件中的内容,实际上攻击者还可以获取服务器中的目录结构以及其他文件,只要启动web应用的用户具有相应的读权限。如果获取的信息比较复杂,如包含特殊符号,无法直接通过http的URL发送,则可以采用对文件内容进行Base64编码等方法解决。

三、漏洞的解决

解决该漏洞的原理非常简单,只要禁止解析XML时访问外部实体即可。

漏洞曝出以后,微信进行了紧急修复,一方面是更新了SDK,并提醒开发者使用最新的SDK;SDK中修复代码如下:

加入了如下两行代码:

1

2

documentBuilderFactory.setExpandEntityReferences(

false

);

documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,

true

);

1

2

3

4

5

6

7

documentBuilderFactory.setFeature(

,

true

);

documentBuilderFactory.setFeature(

,

false

);

documentBuilderFactory.setFeature(

,

false

);

documentBuilderFactory.setFeature(

,

false

);

documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,

true

);

documentBuilderFactory.setXIncludeAware(

false

);

documentBuilderFactory.setExpandEntityReferences(

false

);

笔者本人使用上述方案中建议的如下代码修复了该漏洞:

1

2

3

4

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

documentBuilderFactory.setFeature(

,

true

);

DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

……

四、扩展与反思

1.  危害不只是“0元也能买买买”

在很多媒体的报道中,强调该漏洞的风险在于攻击者可以不支付也可以获得商品。确实,攻击者在通过上述漏洞获得微信支付的秘钥以后,有不止一种途径可以做到不支付就获得商品:例如,攻击者首先在系统中下单,获得商户订单号;然后便可以调用微信支付的异步回调,其中的签名参数便可以使用前面获取的秘钥对订单号等信息进行MD5获得;这样攻击者的异步回调就可以通过应用服务器的签名认证,从而获得商品。不过,在很多有一定规模的购物网站(或其他有支付功能的网站),会有对账系统,如定时将系统中的订单状态与微信、支付宝的后台对比,如果出现不一致可以及时报警并处理,因此该漏洞在这方面的影响可能并没有想象的那么大。

然而,除了“0元也能买买买”,攻击者可以做的事情还有很多很多;理论上来说,攻击者可能获得应用服务器上的目录结构、代码、数据、配置文件等,可以根据需要进行进一步破坏。

(1)接口使用xml做请求参数

(2)接口对外公开,或容易获得:例如一些接口提供给外部客户调用,或者接口使用http很容易抓包,或者接口比较容易猜到(如微信支付的异步回调接口)

(3)接口中解析xml参数时,没有禁用对外部实体的访问

建议大家最好检查一下自己的应用中是否有类似的漏洞,及时修复。

3.  xml与json

xml 与 json是系统间交互常用的两种数据格式,虽然很多情况下二者可以互换,但是笔者认为,json 作为更加轻量级更加纯粹的数据格式,更适合于系统间的交互;而xml,作为更加重量级更加复杂的数据格式,其 DTD 支持自定义文档类型,在更加复杂的配置场景下有着更好的效果,典型的场景如 spring 相关的配置。

在前面曾经提到,应用中存储的秘钥一旦泄露,攻击者便可以完全绕过签名认证,这是因为微信支付使用的是对称式的签名认证:微信方和应用方,使用相同的秘钥对相同的明文进行MD5签名,只要应用方的秘钥泄露,签名认证就完全成了摆设。

在这方面支付宝的做法更规范也更安全:支付宝为应用生成公私钥对,公钥由应用方保存,私钥由支付宝保存;在回调时,支付宝使用私钥进行签名,应用方使用公钥进行验证;这样只要支付宝保存的私钥不泄露,攻击者只有公钥则难以通过签名认证。

发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

相关文章

支付宝自动还款信用卡,有几点要注意别踩雷

支付宝自动还款信用卡,有几点要注意别踩雷

如今,支付宝在生活中提供了很多的便利,在还信用卡也是。支付宝可以开通自动还款,在信用卡的还款日可以自动还款,但是并不是所有的银行都支付,与支付宝有相关合作的银行才能自动还款。目前支付宝能够自动还款的银...

支付业强监管加码!新的出路何在?

支付业强监管加码!新的出路何在?

广告:以下产品均为招商信息不零售文来源:《财经国家周刊》记者 刘秋娜支付行业的强监管仍在加码。继发布《关于加强特约商户管理防范商户挪用支付接口的风险提示》后,中国支付清算协会(下称“支付协会”)10月...

一款集成支付宝、微信的支付JavaSDK

最近项目中遇到支付宝支付、微信支付接口开发的同学们,可以看看这篇文章,应该对你有帮助!这个SDK是用JAVA语言编写的,它其中封装好多与支付相关的接口, 同时整合了多种支付场景于一体。整体感觉还是不错...

加密货币支付,一个可以预期的未来

加密货币支付,一个可以预期的未来

加密货币的真实价值不仅在于有多少人愿意在交易所购买、持有它,更在于有多少人愿意在支付时使用它。在中本聪于2008年11月发表的《比特币:一种点对点的电子现金系统》论文中,清晰阐述了比特币是一套「基于密...

严监管成第三方支付常态 年内央行开出六张2000万以上罚单

严监管成第三方支付常态 年内央行开出六张2000万以上罚单

年内央行开出六张2000万元以上罚单今年以来监管机构加强了金融行业的监管,合规要求提升,各金融行业收到行政处罚的数量和金额都有所增加,其中,第三方支付行业的罚单值得关注。据《证券日报》记者对公开数据不...

手机双十一疯抢价,华为32G手机669元,64G的1089元,能微信指纹支付Nova 3i,6加64G特价1750元.新款特价

华为Nova3特价,6+64G,2259元,6+128G,2350元。介绍:支持微信指纹支付。6.3英寸全面屏。安卓8.1系统,采用3D双曲面炫光玻璃设计,搭载的是麒麟970,八核处理器,Soc准旗 ...