跨站脚本攻击(Cross-Site Scripting,XSS)是一种常见的网络安全漏洞,它允许攻击者将恶意脚本注入到网页中,其他用户在浏览这些页面时,可能会执行这些恶意脚本,从而导致各种安全问题,如窃取用户信息、会话劫持等。
产生原因:
XSS漏洞其实就是一个前端漏洞,产生的根本原因是未对用户输入进行充分验证和过滤,导致恶意用户能够将恶意脚本注入到网页中,使其在其他用户浏览页面时执行。
接下来我们来看一个简单的代码案例(pikachu反射型XSS代码):
$html='';
if(isset($_GET['submit'])){
if(empty($_GET['message'])){
$html.="<p class='notice'>输入'kobe'试试-_-</p>";
}else{
if($_GET['message']=='kobe'){
$html.="<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";
}else{
$html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>";
}
}
}
--------------------------------------------------------------------------
<div id="xssr_main">
<p class="xssr_title">Which NBA player do you like?</p>
<form method="get">
<input class="xssr_in" type="text" maxlength="20" name="message" />
<input class="xssr_submit" type="submit" name="submit" value="submit" />
</form>
<?php echo $html;?>
</div>
$html
是一个用来存储输出内容的变量。在表单提交后,根据用户的输入生成不同的反馈消息,并存储在$html
变量中。
此处我将代码分为两个部分,前半部分是根据获取的用户输入进行$html
的赋值,当$_GET['message']
获取的数据不为空时,$html
变量中的都会带有$_GET['message']
获取到的用户的数据。紧接着在后半部分也就是HTML结构部分存在PHP代码块 <?php echo $html; ?>
用来输出根据用户输入生成的消息,这些消息被存储在$html
变量中,能够在当前的网页中直接显示来自客户端输入的数据,因为这段代码没有对用户输入进行任何过滤或转义处理;这就给了恶意用户可乘之机,攻击者可以通过输入恶意的HTML或JavaScript代码来利用这个漏洞,执行未经授权的操作或窃取用户信息。
常见的payload:
1.弹出警告框:
<script>alert('XSS');</script>
2.打印到控制台:
<script>console.log('XSS');</script>
3.改变页面内容:
<script>document.body.innerHTML = 'Hacked!';</script>
4.通过表单字段触发脚本:
<input type="text" value="XSS" onfocus="alert('XSS');">
payload有很多,笔者此处只举出四个比较简单常用的。
XSS分类:
①反射型XSS(Reflected XSS)
反射型XSS(Reflected XSS)是跨站脚本攻击的一种类型,通常发生在Web应用程序立即处理并反射回用户输入的情况下,这种攻击的特点是恶意脚本没有存储在服务器上,而是通过一些途径(如URL参数)传递并在用户浏览器中执行,所以不会产生持久性的影响。
此时以pikachu靶场中的xss漏洞页面为例子做个演示:
1.发现一个搜索框,随意输入数据后发现输入的数据会在当前页面中显示。
2.这个时候我模拟恶意用户,可以尝试在搜索框中输入相关的HTML或JavaScript恶意代码进行攻击,随便在上述的payload中选一个。
<script>alert("XSS")</script>
此时页面产生弹窗,攻击成功
②存储型XSS(Stored XSS):
攻击者将恶意脚本存储在服务器端,例如在论坛帖子、评论、用户资料等地方,当其他用户访问时,恶意脚本会从服务器端加载并执行,对用户造成攻击。
以pikachu靶场中的存储下XSS界面为例子进行演示:
1.发现当前页面有一个留言板,这个时候我们随意输入一个数据并进行提交,发现当前留言列表中会显示刚才输入的数据'1'。
2.此时我模拟恶意用户,将恶意代码输入留言板中并提交
<script>alert("XSS")</script>
这个时候留言列表中多了一条留言,但是却没有显示留言内容,原因就是因为我们输入的留言为一段简单的javascript代码,那么此时浏览器引擎就会将该代码进行执行,从而进行弹窗。
这个时候我们可以通过分析源码查看存储型XSS的相关特征:
$html='';
if(array_key_exists("message",$_POST) && $_POST['message']!=null){
$message=escape($link, $_POST['message']);
$query="insert into message(content,time) values('$message',now())"; //存入数据库
$result=execute($link, $query);
if(mysqli_affected_rows($link)!=1){
$html.="<p>数据库出现异常,提交失败!</p>";
}
}
可以看到该存储型XSS是将用户输入的内容与当前事件一起存入数据库中;
<div id="xsss_main">
<p class="xsss_title">我是一个留言板:</p>
<form method="post">
<textarea class="xsss_in" name="message"></textarea><br />
<input class="xsss_submit" type="submit" name="submit" value="submit" />
</form>
<div id="show_message">
<br />
<br />
<p class="line">留言列表:</p>
//数据库中读取留言数据在页面中显示
<?php echo $html;
$query="select * from message";
$result=execute($link, $query);
while($data=mysqli_fetch_assoc($result)){
echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'>删除</a>";
}
echo $html;
?>
</div>
接着用户在访问时从数据库中读取相关的留言数据,然后在页面中显示,所以当我们插入恶意代码后,这串代码就会被存放到数据库中,接着每个来访问这个页面的用户都会受到我的攻击语句影响,所以存储型的XSS为持久攻击,危害也更大。