一周前,嘶吼报道了《微信支付曝“0元购”漏洞,官方称已修复,实际风险隐患巨大》的事件。这个漏洞是首发在Seclists上,在被爆出的那几天,国内有很多安全厂商对这件事进行了及时的跟进与相应。嘶吼联系了在移动互联网安全领域领先的盘古实验室,他们也对这个漏洞在技术方面进行了下面严谨的分析:

从该漏洞的技术细节看,漏洞的利用需要2个先决条件,

1)攻击者必须获取有效的商户服务器的notify_url(异步通知接口)以实施攻击。例如漏洞发布者提到的momo和vivo商户服务器:

Momo:https://pay.immomo.com/weixin/notify

Vivo:https://pay.vivo.com.cn/webpay/wechat/callback.oo

2)商户服务器使用了微信支付存在漏洞的Java SDK或者采用了其他可以加载外部实体的方式,且WAF等未对攻击代码进行过滤,如:

从移动应用看微信支付SDK XML实体注入漏洞

通过翻阅最新版的微信支付开发文档,包括刷卡支付、公共号支付、扫码支付、APP支付、H5支付和小程序支付等场景的文档后发现,notify_url一般是用在商户服务器和支付平台的交互中。如果开发者遵守官方的开发指引,该信息就不会流经用户,因此获取该信息难度较大。

通过密钥泄漏获取notify_url。为了获取和微信支付相关的有效notify_url,我们转向盘古实验室基于多年移动安全的研究成果并结合大数据平台的移动安全威胁数据平台——Janus。在微信支付的开发过程中,经常有不严谨的开发者把商户与支付平台的交互过程实现在应用与支付平台之间,从而导致密钥泄漏,同时这个过程也泄漏了商户服务器的notify_url。虽然有些开发者在新版应用中对该问题进行了修复,并且更换了密钥,但并没有更换notify_url。更有很多应用仍然将有效支付密钥和notify_url写死在应用中。通过Janus平台的查询,我们发现22,443个应用(包含相同应用的不同版本)可能将商户与支付平台的交互过程实现在应用与支付平台中,应用的这种支付实现将泄漏商户的notify_url。

从移动应用看微信支付SDK XML实体注入漏洞

对此,技术团队也通过分析应用的AST / 动态验证等手段收集到了7,269个应用泄漏了微信支付的密钥,在提取这些有效密钥的同时存储了对应的notify_url。列表如下:

从移动应用看微信支付SDK XML实体注入漏洞

为了进行测试,从列表中随机抽取了500个notify_url,并进行测试,最终提取到80个仍然可访问的notify_url。

通过POST请求,共收到了4个目标服务器的请求。也就是说有4个商户服务器仍然受此漏洞的影响,实际受漏洞影响的商户服务器比例应该比目前测试结果高。针对这4个商户,盘古技术团队正在尝试与其建立联系,以通报该漏洞。

在上述测试结束后,继续对之前已入库的应用进行潜在威胁测试。在后续的测试中,发现有大量使用同一开发者证书的应用会受此漏洞的影响。根据Janus平台对该证书特征值的记录,仅该开发者所发行的应用便有1877个,应用数量众多。

从移动应用看微信支付SDK XML实体注入漏洞

在Janus平台查询到的使用统一证书的应用

从移动应用看微信支付SDK XML实体注入漏洞

图为可能受到影响的应用

据盘古实验室的研究员介绍,由于存储的压力,Janus后期使用了按需解析的策略来处理入库的应用,这导致大部分应用无法被查询到,我们推测,实际泄漏异步通知接口的应用会更多。

嘶吼因此又联系了某移动安全团队对这个漏洞的利用进行了模拟演示复现。

演示:漏洞可以如何被不法分子利用

1.通过XXE读取配置文件

读取得到了商户的数据库配置信息。

从移动应用看微信支付SDK XML实体注入漏洞

成功连接至商户数据库,可进行任意地增删查改操作。

从移动应用看微信支付SDK XML实体注入漏洞

某库中包含大量的用户敏感信息。如果攻击者进行删库或将库拖取,就会出现大量用户数据被不法分子盗取的情形。更严重者,不法分子可以任意修改个人账户下的余额,将某笔未支付的订单修改为已支付状态。

从移动应用看微信支付SDK XML实体注入漏洞

2.若读取到商户私钥,也可伪造异步通知造成0元支付

查看商家在验签后的校验逻辑,如下图这个商家只验证out_trade_no、return_code、result_code。

从移动应用看微信支付SDK XML实体注入漏洞

只需要根据商家的代码校验逻辑和最终的入库逻辑去生成相应的部分参数和签名,无需知道其它参数内容。

<xml><out_trade_no><![CDATA[H711977989080610]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><total_fee>1</total_fee><sign><![CDATA[6BE587ECCFDD0217B21544A56997D5AB]]></sign></xml>

3.在商户处完成下单,向商户服务器发送伪造的异步消息通知,即可实现免费购物。

因涉及相关商户的资金安全,此处恕不进行步骤演示。