XSS跨站腳本
1.反射型
非持久化,需要用戶自己點擊才可以觸發
通常出現在搜索框
<?php
$id=$_GET[‘id‘];
echo $id;
?>
http://127.0.0.1/test/sc.php?id=<script>alert(1)</script>
2.存儲型
持久化,危害比較大
通常出現在個人信息和留言板處
//提交漏洞頁面
<form action="" method="post">
<input type="text" name="xss"/>
<input type="submit" value="test"/>
</form>
<?php
$xss=$_POST[‘xss‘];
mysql_connect("localhost","root","root");
mysql_select_db("test");
if($xss!==null){
$sql="insert into xss(id,s) values(‘1‘,‘$xss‘)";
$result=mysql_query($sql);
echo $result;
}
?>
//顯示數據庫查詢頁面
<?php
mysql_connect("localhost","root","root");
mysql_select_db("test");
$sql="select s from xss where id=1";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo $row[‘s‘];
}
?>
3.DOM型
類似於反射型,但是直接在前端輸出,而不經過後端
<?php
error_reporting(0);
$test = $_GET["test"];
?>
<html>
<input id="text" type="text" value="<?php echo $test;?>" />
<script type="text/javascript">
var text = document.getElementById("text");
document.write(text.value);
</script>
</html>
關於DOM型
<html>
<body>
<input id="id" type=‘text‘>
<script>
//var a=‘<script>alert(1)<\/script>‘;
var a="<img src=1 onerror=alert(1)>";
document.getElementById("id").innerHTML=a;
</script>
</body>
</html>
上面的代碼,如果是<script>alert(1)</script>不會觸發彈窗
如果是<img src=1 onerror=alert(1)>則會觸發彈窗
原理應該是(?)
瀏覽器對<script>標簽DOM操作時,會頁面渲染,不會再JS解析
4.觸發
如果我們可控的數據在標簽的屬性當中
<1>資源屬性
使用 javascript偽協議
基本上可以請求資源的HTML標簽內都可以使用src\href等
但是有的標簽已經不能觸發XSS,有的則可以
<html>
<script>
var lang = document.location.href.substring(document.location.href.indexOf("id="));
lang=lang.substr(3,);
document.write(‘<a href="‘+lang+‘">test</a>‘);
document.write(‘<iframe src="‘+lang+‘">‘);
document.write(‘<img src="‘+lang+‘">‘);//不能觸發
</script>
</html>
JS偽協議不區分大小寫,並且會自動實體解碼和進制解碼
javascript:alert(1)
JavascRipt:alert(1)
等等都可以觸發
<2>事件屬性
<html>
<script>
var lang = document.location.href.substring(document.location.href.indexOf("id="));
lang=lang.substr(3,);
document.write(‘<a href=1 onclick="‘+lang+‘">test</a>‘);
document.write(‘</br>‘);
document.write(‘<a href=1 onmouseover="‘+lang+‘">test1</a>‘);
</script>
</html>
事件不區分大小寫,引號可以不使用也可是是單引號或雙引號
<html>
<script>
var lang = document.location.href.substring(document.location.href.indexOf("id="));
lang=lang.substr(3,);
document.write(‘<a href=1 onmouseover="‘+lang+‘">test</a>‘);
document.write(‘</br>‘);
document.write("<a href=1 onmouseover=‘"+lang+"‘>test1</a>");
document.write(‘</br>‘);
document.write(‘<a href=1 onmouseover=‘+lang+‘>test</a>‘)
</script>
</html>
上面的三種都是一樣的
<3>普通屬性
想辦法構造新的屬性或者閉合標簽
5.HTMLENCODE
有些標簽具備HTMLENCODE功能
<html>
<textarea><img src=1 onerror=alert(1)></textarea>
<title><img src=1 onerror=alert(1)></title>
<iframe><img src=1 onerror=alert(1)></iframe>
<noscript><img src=1 onerror=alert(1)></noscript>
<noframes><img src=1 onerror=alert(1)></noframes>
</html>
剩下的,比如div標簽
<html>
<div><img src=1 onerror=alert(1)></div>
</html>
6.進制轉換
<1>HTML
HTML支持十進制和十六進制
圖片可以正常顯示
<2>CSS
CSS支持十進制和十六進制
<3>JS
JS支持八進制和十六進制
<html>
<script>alert(1)</script>
<script>eval("\141\154\145\162\164\50\62\51")</script>
<script>eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0033\u0029")</script>
</html>
進制方式對大小寫不敏感,後綴’;’也不是必須的,所以可以用常規字符、十進制編碼和十六進制編碼混合
如果給漢字編碼,則只能使用十六進制的unicode
7.源碼審計
<1>反射型和存儲型
查找在頁面輸出的變量,檢驗是否收到用戶控制,跟蹤傳遞過程,分析是否被過濾。
主要關註 $_SERVER,$_GET,$_POST,$_REQUEST查找輸出的變量,檢驗是否可控,查看是否被過濾print,print_r,echo,printf,sprintf,die,var_dump,var_export
主要出現在搜索框、文章發表、評論回復、留言、友情鏈接、資料設置等處
<2>DOM型
1. 查看用戶的某些輸入源
document.referer
window.name
location
2. 輸出
innerHTML
document.write
8.防禦
<1>反射型和存儲型
對用戶的輸入進行過濾
黑白名單輸入進行編碼
htmlspecialchars()
<2>DOM型
避免客戶端對文檔進行重寫、重定向或其他敏感操作
避免使用客戶端數據,這些操作盡量放在服務端使用動態頁面來實現
XSS跨站腳本