最近,项目突发状况,之前开发的一个手机端APP内嵌H5页面突然异常。现象是刷新页面后,有很大概率页面卡死在数据加载阶段。于是联系App开发人员,出调试包。开始调试。
开始调试后,首先发现页面加载时发送了一个奇怪的请求-http://8.525cm.com/v2/v.php?id=105,返回还是404,于是猜测被运营商DNS劫持,篡改了我们的HTML(话说运营商是联通啊啊啊,开始完全不相信,因为自己孤陋寡闻,只见过小城市的电信干这种事,而我大北京的联通应该不至于吧),而我们的页面确实并未开启HTTPS。嗯嗯,查HTML,发现在head部分确实被插入了一个script标签,如下图:
看来问题找到了。
进一步思考,发现这个原因仍然无法解释为什么我们的页面会卡死在加载阶段,理论上这种劫持不会影响原页面的的功能啊。看来仍然需要进一步调查。
页面卡死一般会有两种情况,某些请求没有返回,一直在Pending状态,或者JS的执行出错了。分别查看网络请求和控制台输出,果然是JS执行出错了。具体查看出错信息,发现是我们依赖的一个JS库没有执行。这就很奇怪了,在网络请求中该JS库是正常返回的。再次查看网络请求确认,发现该JS请求竟然不是我们所依赖的库,竟然被替换成了下面这份鬼样子:
高潮来了,让我们来审查一下这段神奇的代码。首先,它会试图去找一个id为mck0的dom,找到了就什么都不干。如果找不到,嘿嘿,它会向DOM添加两个JS节点(使用appendChild()API),一个是之前被域名劫持掉的JS,自作聪明的作者企图通过这这种方式掩盖他的罪行;另一个就是真正干坏事的请求-8.525cm.com/v2/v.php?id=105。但是百密一疏的是作者居然使用了appendChild,JS的加载顺序被他改掉了,正巧项目中的其它JS依赖了这个被替换掉的JS,于是其它JS在加载时妥妥的报错了,页面卡死也就不足为奇了。
进一步实验还发现,如果整个站点起在HTTPS下面,并且将所有JS也全部托管于HTTPS下,该伪造的JS并不会聪明的分辨协议,还是使用了一个HTTP的JS来还原之前被劫持掉的HTTPS JS,这样整个JS都会因为浏览器的安全策略而加载失败。也就是说如果我们的站点是在HTTPS下的,那么站点中一定会有一个JS因为劫持而加载失败,导致页面出现问题。
通过whois反查,得到如下信息:
貌似域名持有者是中国万网,阿里旗下公司,我们静待大公司如何回应吧。
回到我们的项目,被劫持的JS是托管在七牛的CDN上,并且通过HTTPS访问,所以已经可以断定,七牛分配给我们的域名已经被运营商劫持掉了。现在我们正在联系七牛的客服积极处理中。进一步的进展我会及时更新在这篇文章中。
,