<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; 劫持</title>
	<atom:link href="https://zohead.com/archives/tag/tamper/feed" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>移动宽带丧心病狂的流量劫持</title>
		<link>https://zohead.com/archives/cmcc-network-temper/</link>
		<comments>https://zohead.com/archives/cmcc-network-temper/#comments</comments>
		<pubDate>Tue, 30 May 2017 04:26:42 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[生活]]></category>
		<category><![CDATA[网络]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[中国移动]]></category>
		<category><![CDATA[劫持]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1447</guid>
		<description><![CDATA[流量劫持情况 最近我发现在住处的江苏移动宽带网络环境下用手机浏览一些 HTTP 网站很容易出现和网站内容明显不符的抢红包广告，有时候页面会显示错乱，而在 PC 端打开同样的网址又没有问题。这种情况只在 HTTP 网站上碰到过，初步判断这就是移动宽带一贯使用的流量劫持把戏。 被劫持的网页在手机端显示起来是这样的： 页面中间的浮标和页面下方的开红包图标都明显不是原始网站投放的广告。这种劫持行为一般在手机浏览器上刷新一下就暂时没有了，但很多情况下会碰到运营商插入的广告导致移动端网页布局出现异常，无法正常使用。 劫持情况分析 由于直接在 PC 端打开被劫持的网址很可能不会出现被插入广告的情况，模拟手机 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="mobile-temper">流量劫持情况</h2>
<p>最近我发现在住处的江苏移动宽带网络环境下用手机浏览一些 HTTP 网站很容易出现和网站内容明显不符的抢红包广告，有时候页面会显示错乱，而在 PC 端打开同样的网址又没有问题。这种情况只在 HTTP 网站上碰到过，初步判断这就是移动宽带一贯使用的流量劫持把戏。</p>
<p>被劫持的网页在手机端显示起来是这样的：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442856/mobile-temper.jpg" alt="手机端网页劫持" title="手机端网页劫持"></p>
<p>页面中间的浮标和页面下方的开红包图标都明显不是原始网站投放的广告。这种劫持行为一般在手机浏览器上刷新一下就暂时没有了，但很多情况下会碰到运营商插入的广告导致移动端网页布局出现异常，无法正常使用。</p>
<h2 id="temper-analysis">劫持情况分析</h2>
<p>由于直接在 PC 端打开被劫持的网址很可能不会出现被插入广告的情况，模拟手机浏览器 user agent 也要碰运气才能出现，因此我直接使用 Android Chrome 浏览器的远程调试功能来进行分析。</p>
<p>打开 Android 的 USB 调试功能，通过数据线连接电脑，在 PC 端 Chrome 浏览器上进入：<code>chrome://inspect/#devices</code> 就能看到连接上的 Android 手机上 Chrome 浏览器打开的标签页，为了方便调试和安利给大家，我使用的是直接基于 Chrome 的 Chromebook 设备：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737369839/android-chrome-debug.png" alt="Android Chrome 远程调试" title="Android Chrome 远程调试"></p>
<p>点击标签页下方的 <code>inspect</code> 按钮就可以远程调试了。</p>
<p>在 Elements 调试界面可以看到运营商在网页 <code>&lt;/body&gt;</code> 结束之前插入了两个 div：<code>tuia-fubiao</code> 和 <code>tuia-customer</code>，更恶心的是下面还加了一个隐藏的 <code>iframe</code>。</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737371494/isp-http-temper.png" alt="流量劫持代码" title="流量劫持代码"></p>
<p>不过看了被劫持之后实际的网页源代码你才能感受到移动宽带的丧心病狂，首先网页 <code>&lt;head&gt;</code> 标签之后就插入了奇奇怪怪的广告代码：</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;html lang=&quot;zh-CN&quot; prefix=&quot;og: http://ogp.me/ns#&quot; class=&quot; js rgba borderradius boxshadow textshadow opacity cssanimations cssgradients csstransitions fontface generatedcontent video audio js&quot;&gt;
&lt;!-- BEGIN head --&gt;
&lt;head&gt;
&lt;script src=&quot;https://engine.tuia.cn/api/v1/activity/spm4web?type=0&amp;amp;adslot_id=1180&amp;amp;app_key=34J8hJmWWs5CArNgfbjAzReG2hRK&amp;amp;activity_id=3000000024%2C3613&amp;amp;ua=Mozilla%2F5.0%20(Linux%3B%20Android%206.0.1%3B%20ASUS_Z00AD%20Build%2FMMB29P)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F57.0.2987.132%20Mobile%20Safari%2F537.36&amp;amp;os_type=&amp;amp;device_id=QjotWKjhRBHLKsYJlCzM1493608315747&amp;amp;token=1493608315732&amp;amp;time=1493608316137&amp;amp;wdata_token=34J8hJmWWs5CArNgfbjAzReG2hRKTJfWvzV0zCtEGT1guzhG1493608315751&amp;amp;spm_id=34J8hJmWWs5CArNgfbjAzReG2hRK1VQvIKrTPbIdBvb0xx871493608316140&amp;amp;callback=jsonp_0q7no0fhvv36mq9&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://engine.tuia.cn/api/v1/activity/spm4web?type=0&amp;amp;adslot_id=927&amp;amp;app_key=34J8hJmWWs5CArNgfbjAzReG2hRK&amp;amp;activity_id=2000000418&amp;amp;ua=Mozilla%2F5.0%20(Linux%3B%20Android%206.0.1%3B%20ASUS_Z00AD%20Build%2FMMB29P)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F57.0.2987.132%20Mobile%20Safari%2F537.36&amp;amp;os_type=&amp;amp;device_id=QjotWKjhRBHLKsYJlCzM1493608315747&amp;amp;token=1493608315756&amp;amp;time=1493608316119&amp;amp;wdata_token=34J8hJmWWs5CArNgfbjAzReG2hRKTJfWvzV0zCtEGT1guzhG1493608315751&amp;amp;spm_id=34J8hJmWWs5CArNgfbjAzReG2hRKTkxmCuzebbLxiPLAaf0S1493608316129&amp;amp;callback=jsonp_w4rcxsrtl47vpid&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://engine.tuia.cn/api/v1/activity/get4web?request_id=34J8hJmWWs5CArNgfbjAzReG2hRKKtfJakUIBYbHCqfburmv1493608315757&amp;amp;api_version=1.0.0&amp;amp;app_key=34J8hJmWWs5CArNgfbjAzReG2hRK&amp;amp;app_version=1.0.0&amp;amp;app_package=&amp;amp;adslot_id=927&amp;amp;device_type=&amp;amp;os_type=&amp;amp;os_info=&amp;amp;vendor=&amp;amp;model=&amp;amp;screen_size=360*640&amp;amp;device_id=QjotWKjhRBHLKsYJlCzM1493608315747&amp;amp;connection_type=&amp;amp;operator_type=&amp;amp;cellular_id=&amp;amp;ap_mac=&amp;amp;rssi=&amp;amp;ap_name=&amp;amp;wifi_type=&amp;amp;hotspot_type=&amp;amp;geolocation=true&amp;amp;coordinate_type=&amp;amp;longitude=&amp;amp;latitude=&amp;amp;timestamp=&amp;amp;token=1493608315756&amp;amp;time=1493608315756&amp;amp;wdata_token=34J8hJmWWs5CArNgfbjAzReG2hRKTJfWvzV0zCtEGT1guzhG1493608315751&amp;amp;callback=jsonp_9lyfpalx27d62fk&quot; async=&quot;&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://engine.tuia.cn/api/v1/activity/get4web?request_id=34J8hJmWWs5CArNgfbjAzReG2hRKl2K0dtAdcAFOYVPamLi11493608315743&amp;amp;api_version=1.0.0&amp;amp;app_key=34J8hJmWWs5CArNgfbjAzReG2hRK&amp;amp;app_version=1.0.0&amp;amp;app_package=&amp;amp;adslot_id=1180&amp;amp;device_type=&amp;amp;os_type=&amp;amp;os_info=&amp;amp;vendor=&amp;amp;model=&amp;amp;screen_size=360*640&amp;amp;device_id=QjotWKjhRBHLKsYJlCzM1493608315747&amp;amp;connection_type=&amp;amp;operator_type=&amp;amp;cellular_id=&amp;amp;ap_mac=&amp;amp;rssi=&amp;amp;ap_name=&amp;amp;wifi_type=&amp;amp;hotspot_type=&amp;amp;geolocation=true&amp;amp;coordinate_type=&amp;amp;longitude=&amp;amp;latitude=&amp;amp;timestamp=&amp;amp;token=1493608315732&amp;amp;time=1493608315737&amp;amp;wdata_token=34J8hJmWWs5CArNgfbjAzReG2hRKTJfWvzV0zCtEGT1guzhG1493608315751&amp;amp;callback=jsonp_5jm97edzjaj18j0&quot; async=&quot;&quot;&gt;&lt;/script&gt;
</pre>
<p>移动宽带在 <code>&lt;head&gt;</code> 的网站原有 script 脚本中间还硬插了一段：</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;script src=&quot;http://112.4.23.122:8848/a_zdyjs.js?aorlu=aHR0cDovL3d3dy5jbGI2LmNvbS5jbi94bWxrZXkvaHRtbC9keXNqL28tdHQtdGFqcy5qcw==&amp;amp;adid=360523&amp;amp;tcca=MTM5NTE3NzE2NjU=&amp;amp;urip=100.65.241.248&amp;amp;stpt=0&amp;amp;edpt=0&amp;amp;orlu=aHR0cDovL2Jsb2cuam9iYm9sZS5jb20vMTExMDM4Lw==&amp;amp;spid=176150497705350&amp;amp;area=0&amp;amp;motn=1477554323&amp;amp;saas=134352896&amp;amp;p7arm=1&amp;amp;p8arm=0&amp;amp;psad=3232268039&amp;amp;atid=1&amp;amp;paat=0&amp;amp;aaid=0&amp;amp;isaa=0&amp;amp;envs=0&amp;amp;ckts=1493608314&amp;amp;type=2&amp;amp;teid=65459&amp;amp;acst=1&amp;amp;swvi=5277681751310447&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
</pre>
<p>连 CSS 也别想幸免，<code>&lt;/head&gt;</code> 结束也插入了一段，这里的 CSS 代码太长我就不全部贴出来了：</p>
<pre class="brush: css; title: ; notranslate">
&lt;style type=&quot;text/css&quot;&gt;
#tuia-customer{position:fixed;bottom:0;left:0;width:100%;}
#tuia-fubiao{position: fixed;right: 7.5px;top: 250px;overflow: initial;width: 75px; height: 75px; z-index: 2147483647;}
&lt;/style&gt;
&lt;style type=&quot;text/css&quot;&gt;
.tuia-media{position:relative;overflow:hidden;width:100%;max-width:100%}
.tuia-media,.tuia-media *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
.tuia-media .tuia-media-close{position:absolute;top:0;right:0;width:22.5px;height:22.5px;background-image:url(//yun.duiba.com.cn/static/jssdk/e9fa2ce7753ea10e0425f4c7e71d941b.png);background-repeat:no-repeat;background-position:100% 0;-webkit-background-size:15px 15px;background-size:15px 15px}
&lt;/style&gt;
......
</pre>
<p>至于 <code>&lt;/body&gt;</code> 结束之前插入的广告代码是这样的：</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;!-- END html --&gt;
&lt;div id=&quot;tuia-fubiao&quot;&gt;
&lt;div class=&quot;tuia-media&quot; id=&quot;TuiaMediaID_1493608316134&quot;&gt;&lt;div class=&quot;tuia-media-close&quot; style=&quot;background-image:url(https://yun.duiba.com.cn/upload/4UyUC1480924005775.png)&quot;&gt;&lt;/div&gt;
&lt;img class=&quot;tuia-media-pic&quot; src=&quot;https://yun.duiba.com.cn/tuia-media/img/82ejm1th2s.gif&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;tuia-customer&quot;&gt;
&lt;div class=&quot;tuia-media&quot; id=&quot;TuiaMediaID_1493608316116&quot;&gt;&lt;img class=&quot;tuia-media-pic&quot; src=&quot;https://yun.duiba.com.cn/tuia-media/img/qhszjuf9kr.gif&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;script src=&quot;http://yun.duiba.com.cn/static/jssdk/media-2.2.2.min.js&quot;&gt;&lt;/script&gt;
&lt;div style=&quot;display: none;&quot;&gt;
&lt;iframe src=&quot;http://www.clb6.com.cn/xmlkey/stat.html?zym=s95&amp;amp;sid=1261769958&quot; width=&quot;0&quot; height=&quot;0&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>面对这样被改的面目全非的网页源代码，我简直是无语到极点。移动宽带为了插广告使用这种下作的劫持方式，也难怪手机浏览器上很容易碰到被劫持后一些移动版网站显示错乱的问题了。</p>
<h2 id="temper-iframe">另一种流量劫持</h2>
<p>另外使用移动宽带在手机端上网还可能碰到一种比较常见和看起来稍微「良心」一点的劫持方式。</p>
<p>这是我用 Android Chrome 浏览器访问 <a href="https://sspai.com/" target="_blank">少数派</a> 网站时碰到的劫持情况，被劫持的网页代码变成这样：</p>
<pre class="brush: jscript; title: ; notranslate">
&lt;html&gt;
&lt;head&gt;
&lt;script&gt;var d=&quot;=iunm?=ifbe?=0ifbe?=cpez!je&gt;#c#!tuzmf&gt;#pwfsgmpx.z;!ijeefo&lt;#!sjhiuNbshjo&gt;1!upqNbshjo&gt;1!mfguNbshjo&gt;1!tdspmm&gt;op?=0cpez?=tdsjqu!tsd&gt;#iuuq;00223/5/34/233;99590b`ig`cpuupn/kt@beje&gt;471494'uddb&gt;NUN6OUF4O{F3OkV&gt;'vsjq&gt;211/76/352/359'tuqu&gt;1'fequ&gt;1'psmv&gt;bIS1dEpwM4O{dHGqMnOwcT:1ZXdwZX6ldn:q[B&gt;&gt;'bpsmv&gt;bIS1dEpwM4e4ez6kcHJ3MnOwcT6kcj:5cX&quot;;function i(_,__){_+=__;var $=&quot;&quot;;for(var u=0;u&lt;_.length;u++){var r=_.charCodeAt(u);$+=String.fromCharCode(r-1);}return $;} var c=&quot;ys[YlwbISucD:lfYOrM39ueIRuNT6peH2t'tqje&gt;287275596954112'bsfb&gt;1'q2bsn&gt;86'q3bsn&gt;1'q4bsn&gt;1'q5bsn&gt;6'q6bsn&gt;4'q7bsn&gt;2'bqqe&gt;1'ibtDpvou&gt;1'ibtXijufVtfs&gt;1'npuo&gt;2588665434'tbbt&gt;2454639:7'q8bsn&gt;2'q9bsn&gt;1'qtbe&gt;434337914:'buje&gt;2'qbbu&gt;1'bbje&gt;1'jtbb&gt;1'fowt&gt;1'dlut&gt;25:4745::6'uzqf&gt;3'ufje&gt;7656:'bdtu&gt;2'txwj&gt;6388792862421558#?=0tdsjqu?=0iunm?&quot;;document.write(i(d,c));&lt;/script&gt;
&lt;/head&gt;
&lt;body id=&quot;b&quot; style=&quot;overflow-y: hidden;&quot; rightmargin=&quot;0&quot; topmargin=&quot;0&quot; leftmargin=&quot;0&quot; scroll=&quot;no&quot;&gt;
&lt;div id=&quot;a&quot; style=&quot;border:0px;overflow:hidden;position:absolute;bottom:0px;width:100%;height:75&quot;&gt;
&lt;iframe src=&quot;http://www.clb6.com.cn/xmlkey/html/dysj/o-tt-1.html?spid=176164485843001&quot; width=&quot;100%&quot; height=&quot;100%&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;
&lt;iframe src=&quot;http://112.4.23.122:8848/a/spd?adid=360383&amp;amp;tcca=MTM5NTE3NzE2NjU=&amp;amp;urip=100.65.241.248&amp;amp;stpt=0&amp;amp;edpt=0&amp;amp;orlu=aHR0cDovL3NzcGFpLmNvbS90YWcvYW5kcm9pZA==&amp;amp;aorlu=aHR0cDovL3d3dy5jbGI2LmNvbS5jbi94bWxrZXkvaHRtbC9keXNqL28tdHQtMS5odG1s&amp;amp;spid=176164485843001&amp;amp;area=0&amp;amp;p1arm=75&amp;amp;p2arm=0&amp;amp;p3arm=0&amp;amp;p4arm=5&amp;amp;p5arm=3&amp;amp;p6arm=1&amp;amp;appd=0&amp;amp;hasCount=0&amp;amp;hasWhiteUser=0&amp;amp;motn=1477554323&amp;amp;saas=134352896&amp;amp;p7arm=1&amp;amp;p8arm=0&amp;amp;psad=3232268039&amp;amp;atid=1&amp;amp;paat=0&amp;amp;aaid=0&amp;amp;isaa=0&amp;amp;envs=0&amp;amp;ckts=1493634995&amp;amp;type=2&amp;amp;teid=65459&amp;amp;acst=1&amp;amp;swvi=5277681751310447&amp;amp;usgt=TW96aWxsYS81LjAgKExpbnV4OyBBbmRyb2lkIDYuMC4xOyBBU1VTX1owMEFEIEJ1aWxkL01NQjI5UCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCUyQyBsaWtlIEdlY2tvKSBDaHJvbWUvNTcuMC4yOTg3LjEzMiBNb2JpbGUgU2FmYXJpLzUzNy4zNg==&amp;amp;pushFlag=1&quot; style=&quot;display:none&quot;&gt;&lt;/iframe&gt;
&lt;img id=&quot;close&quot; onclick=&quot;closeAd()&quot; alt=&quot;Close&quot; src=&quot;http://112.4.23.122:8848/close.gif&quot; style=&quot;position:absolute;right:5px;top:5px;overflow:hidden;border:1px solid;border-color:white;background-color:#EFF7FE;width:12px;height:10px;font-family:System;cursor:hand;z-index:9999;&quot;&gt;
&lt;/div&gt;
&lt;div id=&quot;c&quot; style=&quot;border:0px;overflow:hidden;width:100%;height:100%&quot;&gt;
&lt;iframe name=&quot;cn&quot; src=&quot;http://sspai.com/tag/android?t=1493634994258&quot; frameborder=&quot;0&quot; width=&quot;100%&quot; height=&quot;100%&quot; scrolling=&quot;auto&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>这是最常见的 iframe 劫持方式，外面的广告代码套上源网站，只能说好歹还没有直接魔改源网站的代码，另外插入的广告代码同样来自 <code>112.4.23.122</code> 这个 IP 地址。</p>
<p>查询之后发现该 IP 地址是：江苏省南京市 全省共用出口 移动，很明显这些流量劫持行为是南京移动宽带内部人员为利益驱使而做的。</p>
<h2 id="process-temper">后续处理</h2>
<p>发现移动宽带的流量劫持行为之后，我首先与南京移动联系进行了投诉，不出所料移动客服又是一番先坚决不承认然后让提供技术证明的节奏，直到我威胁要投诉到工信部，移动才表态愿意处理此问题。</p>
<p>投诉之后的十几天手机访问一些 HTTP 的网站确实没见到广告劫持了，然而好景不长，前些天又在手机上看到了插入的广告，无奈我先在路由器上直接屏蔽了劫持代码中的 IP 地址和网站域名，而且最近马上要搬家换住处了，可能也不会继续用移动宽带了，因此就没有兴趣继续跟进此事咯。</p>
<p>当然目前最好的应对方式还是希望众多网站能尽快切换到全站 HTTPS 了，文章开头截图里被劫持的 伯乐在线 网站仍然在用 HTTP，国内移动互联网流量的大头 微信公众号 也没有切换到 HTTPS（我也碰到过公众号文章被劫持插入代码的情况）。</p>
<p>比较欣慰的是我写这篇文章的时候，少数派 网站看起来也已经使用 HTTPS 了，最后祝大家儿童节快乐 ^_^。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/cmcc-network-temper/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>考虑开启SRI防止七牛CDN HTTPS劫持</title>
		<link>https://zohead.com/archives/qiniu-https-tamper/</link>
		<comments>https://zohead.com/archives/qiniu-https-tamper/#comments</comments>
		<pubDate>Fri, 27 May 2016 14:48:28 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[CDN]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[SRI]]></category>
		<category><![CDATA[七牛]]></category>
		<category><![CDATA[云存储]]></category>
		<category><![CDATA[劫持]]></category>
		<category><![CDATA[证书]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1237</guid>
		<description><![CDATA[最近我在使用 Android 上的 Chrome 浏览器访问博客页面时发现一个奇怪的问题：博客页面底部有一个悬浮的叉，但又没有显示任何实际的内容。赶紧用 Chromebook 打开博客网页，将 User Agent 切换成 Android Chrome，这时可以看到网页里无端多了一个 iframe，该 iframe 地址为 http://dbcpm.com/locate_1/jiwei_MBpt.html，如下图所示： 由于我确定博客 VPS 后台并没有被入侵，因此初步估计是网页被万恶的运营商给劫持了，但又一想我的博客已经启用了全站 HTTPS，按说不会轻易遇到这种问题了。马上看看 Chrom [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>最近我在使用 Android 上的 Chrome 浏览器访问博客页面时发现一个奇怪的问题：博客页面底部有一个悬浮的叉，但又没有显示任何实际的内容。赶紧用 Chromebook 打开博客网页，将 User Agent 切换成 Android Chrome，这时可以看到网页里无端多了一个 iframe，该 iframe 地址为 <code>http://dbcpm.com/locate_1/jiwei_MBpt.html</code>，如下图所示：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442960/tampered-page.png" alt="博客被劫持效果" title=""></p>
<p>由于我确定博客 VPS 后台并没有被入侵，因此初步估计是网页被万恶的运营商给劫持了，但又一想我的博客已经启用了全站 HTTPS，按说不会轻易遇到这种问题了。马上看看 Chrome 浏览器上的地址栏标志，果然没有小绿锁了，浏览器控制台里也有 Mixed Content 报错：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442846/mixed-content-error.png" alt="Mixed Content 报错" title=""></p>
<p>可以看到浏览器拒绝加载 HTTP 的 JavaScript 文件，接着看看七牛 HTTPS 地址返回的数据是否正确：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442957/tampered-js.png" alt="七牛 CDN HTTPS 错误数据" title=""></p>
<p>这下立马发现返回的 JavaScript 代码不对了，开头是插入了 HTTP 形式的 JavaScript 文件地址，后面则看起来明显是广告一类的程序代码了。</p>
<p>难道是运营商做了 DNS 劫持导致我使用的七牛 CDN HTTPS 域名 <code>dn-zohead.qbox.me</code> 解析到了不正确的地址？如果是这样按说应该会出现 SSL 证书错误的，而且运营商只是为了插入广告代码而去搞 TLS 中间人攻击之类的感觉也不太合理。</p>
<p>考虑到另一种可能就是七牛 CDN 在从我的博客 VPS 地址回源的时候由于 DNS 污染之类的问题请求到了错误的数据，导致 HTTPS CDN 返回的数据也不对，这样还是登录到七牛后台管理，查看被劫持的 main.js 文件内容是否正确，下载下来对比却发现和我的博客源站内容是一致的，并没有被污染。</p>
<p>多次测试之后我发现如果再刷新页面七牛 HTTPS 劫持的问题可能又没了，而且在新标签页中打开被劫持的 HTTPS JavaScript 路径又能返回正确的数据了，这个时候通过 Chrome 调试工具看到的 HTTP 请求响应结果是这样的：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442862/normal-https-reponse.png" alt="正常七牛 CDN HTTPS 请求" title=""></p>
<p>而被劫持的 HTTP 请求响应结果则是：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442957/tampered-https-response.png" alt="被劫持的七牛 CDN HTTPS 请求" title=""></p>
<p>可以看到返回的 HTTP 头信息完全不同，而且多次刷新之后发现被劫持的 HTTPS 数据基本都来自 <code>211.142.22.13</code> 这台七牛的 CDN 服务器。查询之后发现这个 IP 地址是山西移动的（刚好我使用的是移动宽带），看起来只要浏览器是从 <code>211.142.22.13</code> 这台 CDN 服务器请求数据很可能得到的是被劫持的 JavaScript 代码，而如果七牛的 qbox.me 域名解析到的是其它 CDN 服务器地址则数据可能是正常的。</p>
<p>为了更好的重现这个问题，我们可以在 Linux 下先修改系统 hosts 文件使七牛的 qbox.me HTTPS 域名使用进行劫持操作的服务器，然后使用 wget 命令伪装 Android 移动设备以 HTTPS 地址从这台服务器请求 JavaScript 数据：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~$ wget --referer=&quot;https://zohead.com/&quot; --user-agent=&quot;Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36&quot; https://dn-zohead.qbox.me/test.js
--2016-05-27 00:30:37--  https://dn-zohead.qbox.me/test.js
Resolving dn-zohead.qbox.me (dn-zohead.qbox.me)... 211.142.22.13
Connecting to dn-zohead.qbox.me (dn-zohead.qbox.me)|211.142.22.13|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2391 (2.3K) 1
Saving to: ‘test.js’

100%[===========================================================================================================&gt;] 2,391       --.-K/s   in 0.002s  

2016-05-27 00:30:38 (1.18 MB/s) - ‘test.js’ saved [2391/2391]
</pre>
<p>上面使用 wget 的 <code>--user-agent</code> 参数伪装 Android Chrome 浏览器，使用 <code>--referer</code> 参数伪装从我的博客源站发起请求，而 <code>test.js</code> 同样是一个实际不存在的 JavaScript 地址，我们可以看看返回的数据：</p>
<pre class="brush: bash; title: ; notranslate">
(trusty)zzm@localhost:~$ head test.js 
var osrc =&quot;http://dn-zohead.qbox.me/test.js&quot;;osrc+=(osrc.indexOf('?')&gt;0?'&amp;':'?')+'_t='+(new Date().getTime());document.write('&lt;script type=&quot;text/javascript&quot; src=&quot;'+osrc+'&quot;&gt;&lt;/'+'script&gt;');function withjQuery(callback){if(typeof(jQuery)==&quot;undefined&quot;){var script=document.createElement(&quot;script&quot;);scrip ......
</pre>
<p>很明显这下又得到了被篡改的数据，我们可以试试把 HTTPS 地址改成一个实际存在的 JavaScript 文件并多次运行，你会发现会有一定的概率返回被篡改的数据，有的时候也能返回正确的数据。</p>
<p>另外如果你去掉 <code>--user-agent</code> 参数或者 <code>--referer</code> 参数可能也能得到正确的数据或者正确的 404 报错（对于不存在的 JavaScript 地址），因此我想到可能是劫持方为了不让自己这种龌龊的行径被很容易的发现，而对劫持做了一些限制，如果是直接请求地址（不通过源站 referer 请求）或者通过 PC 端浏览器请求地址则基本上都返回正确的数据。</p>
<p>这下我就可以单独确认 <code>211.142.22.13</code> 这个地址到底是不是真正的七牛服务器了，我们可以修改系统 hosts 文件，例如将我的七牛 HTTPS 域名 <code>dn-zohead.qbox.me</code> 直接改为 <code>211.142.22.13</code> ，然后通过 Chrome 浏览器访问一个七牛服务器上不存在的 JavaScript 地址，确认 HTTPS 证书是否正确。</p>
<blockquote>
<p><strong>提示</strong></p>
<p>从上面 wget 命令的测试结果来看，劫持方可能做了 User Agent 和 Referer 的限制，因此直接访问地址可能并不能看到劫持效果。 <br />
  这就需要将 Chrome 浏览器 User Agent 改为 Android Chrome，另外可以考虑在控制台中输入命令在网页上创建一个链接，并点击链接实现 Referer 跳转的效果，例如：</p>
<pre class="brush: jscript; title: ; notranslate">
var aaa = document.createElement('a');
aaa.innerHTML = 'testlink';
aaa.href = 'https://dn-zohead.qbox.me/ccc8.js'; document.body.appendChild(aaa);
</pre>
</blockquote>
<p>先看看进行劫持操作的 <code>211.142.22.13</code> CDN 服务器的 HTTPS 证书：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442931/qiniu-tampered-https.png" alt="被劫持的七牛 CDN HTTPS 证书" title=""></p>
<p>看起来 SSL 服务器证书是正确的，而且从截图的内容也可以看到返回的 JavaScript 代码也明显是被篡改过的。</p>
<p>然后再修改 hosts 文件去掉添加的域名地址条目，重新访问同样不存在的 JavaScript 地址，以确认正确的七牛 CDN 服务器的 HTTPS 证书：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442931/qiniu-normal-https.png" alt="正常的七牛 CDN HTTPS 证书" title=""></p>
<p>可以发现正常的七牛 CDN 服务器对于不存在的文件是可以正确返回 Document not found 错误的，而进行劫持操作的 CDN 服务器则可能会返回篡改过的 JavaScript 代码，而最要命的是这两个服务器的 HTTPS 证书是完全一致的。</p>
<p>而我使用 HTTPS 访问博客时由于 Mixed Content 问题会导致博客页面时有些功能不正常，而且本该被篡改插入的广告反倒没显示出来，用 Android Chrome 浏览器以 HTTP 方式访问博客多次刷新之后可以看到被劫持插入页面的广告，按说也可以根据 CNZZ 统计代码追踪看看，不过这个就没太大兴趣了：</p>
<p><img src="http://res.cloudinary.com/digwht2y0/image/upload/v1737442931/qiniu-cdn-https-ad.png" alt="被劫持插入的广告" title=""></p>
<p>至此七牛 CDN HTTPS 劫持的问题基本可以明确了：</p>
<ul>
<li>重点针对 JavaScript 文件；</li>
<li>并不是七牛 CDN 上 DNS 污染而回源数据不正确导致；</li>
<li>并不是所有七牛 CDN 地址都会返回篡改的数据；</li>
<li>重点针对移动浏览器，移动网络环境下更加明显；</li>
<li>对劫持做了一定的限制，防止被轻易发现；</li>
<li>进行劫持操作的服务器使用的是正确的七牛 HTTPS 证书。</li>
</ul>
<p>至于这种恶意 CDN HTTPS 劫持到底是七牛内部人士所为，还是七牛的 HTTPS 证书泄漏被运营商利用，还需要进一步的确认。提交工单之后七牛客服人员的初步解释是：</p>
<ul>
<li>qbox.me 域名被大量客户使用比较不稳定，建议迁移到 HTTPS 自定义域名，而 HTTPS 自定义域名是收费的；</li>
<li>使用 qnssl.com HTTPS 自定义域名的话则有做回源的验证，并且节点相对较多，应该不会有劫持情况的发生。</li>
</ul>
<p>然而我查看了七牛 CDN 后台数据之后还是基本可以确认并没有回源数据被污染的情况，因此七牛给的答复并不能让我满意。</p>
<p>由此也可以看出在这片神奇的土地上，我们的网络环境除了要面临 GFW 这个几乎众所周知的阻碍在其它方面又到底是如何的恶劣，网站主们即使是开启了全站 HTTPS 也难以幸免。就算是七牛所有 CDN 服务器数据都是干净的，也不能保证网络运营商不在中间干点 DNS 污染、TLS 攻击之类的坏事。</p>
<p>如果要解决这种问题我初步想到的就是为博客开启 Subresource Integrity（SRI）安全检查功能，虽然目前支持 SRI 功能的浏览器（目前主要是 Chrome 和 Firefox）并不多，但其还是可以帮助 Web 开发者尽量避免各种网站数据可能被第三方篡改的情况。</p>
<p>SRI 的相关介绍可以参考（第二篇中文文章介绍的比较详细）：</p>
<ul>
<li><a href="https://www.srihash.org/">https://www.srihash.org/</a></li>
<li><a href="https://imququ.com/post/subresource-integrity.html">https://imququ.com/post/subresource-integrity.html</a></li>
</ul>
<p>由于 SRI 需要对网页中所有请求外部资源的地方进行修改，一个个手工通过 openssl 命令和修改网页来做实在比较麻烦。</p>
<p>对于 WordPress 博客已经有人实现了 SRI 资源管理的插件 <a href="https://wordpress.org/plugins/wp-sri/">Subresource Integrity (SRI) Manager</a>，该插件可以自动为 WordPress 博客中引用的资源添加 SRI SHA-256 校验值，这样可以减少博客被各种 HTTP、HTTPS 中间人劫持攻击的机率。不过目前还是准备先测试看看此插件稳定性如何，后续再考虑为博客整体开启 SRI 功能咯。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/qiniu-https-tamper/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
