和反射性XSS的即时响应相比,存储型XSS则需要先把利用代码保存在比如数据库或文件中,当web程序读取利用代码时再输出在页面上执行利用代码。但存储型XSS不用考虑绕过浏览器的过滤问题,屏蔽性也要好很多。
存储型XSS攻击流程:
存储型XSS的白盒审计同样要寻找未过滤的输入点和未过滤的输出函数。
新建XssStorage.php文件,并加入以下代码
<span style="font-size:18px;">
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<html>
<head>
<title>XssStorage</title>
</head>
<body>
<h2>Message Board<h2>
<br>
<form action="XssStorage.php" method="post">
Message:<textarea id='Mid' name="desc"></textarea>
<br>
<br>
Subuser:<input type="text" name="user"/><br>
<br>
<input type="submit" value="submit" onclick='loction="XssStorage.php"'/>
</form>
<?php
if(isset($_POST['user'])&&isset($_POST['desc'])){
$log=fopen("sql.txt","a");
fwrite($log,$_POST['user']."\r\n");
fwrite($log,$_POST['desc']."\r\n");
fclose($log);
}
if(file_exists("sql.txt"))
{
$read= fopen("sql.txt",'r');
while(!feof($read))
{
echo fgets($read)."</br>";
}
fclose($read);
}
?>
</body>
</html>
</span>
这个页面采用POST提交数据,生成、读取文本模拟数据库,提交数据之后页面会将数据写入sql.txt,再打开页面时会读取sql.txt中内容并显示在网页上,实现了存储型xss攻击模拟。
打开页面,随意输入内容:
可以看到页面正常显示页面留言信息。当我们在Message中输入<script>alert('xss')</script>
时,页面成功弹窗 :
并且我们重启浏览器之后再加载该页面,页面依然会弹窗,这是因为恶意代码已经写入数据库中,每当有人访问该页面时,恶意代码就会被加载执行!
这就是所谓的存储型XSS漏洞,一次提交之后,每当有用户访问这个页面都会受到XSS攻击,危害巨大。
存储型XSS的执行位置通常不同于输入位置。我们可以看出,存储行XSS的数据流向是:
浏览器 -> 后端 -> 数据库 -> 后端 -> 浏览器。