XSS跨站脚本

1.反射型

非持久化,需要用户自己点击才可以触发

通常出现在搜索框

<?php

    $id=$_GET['id'];
    echo $id;

?>

http://127.0.0.1/test/sc.php?id=<script>alert(1)</script>

2.存储型

持久化,危害比较大

通常出现在个人信息和留言板处

//提交漏洞页面
<form action="" method="post">  
    <input type="text" name="xss"/> <input type="submit" value="test"/> </form> <?php $xss=$_POST['xss']; mysql_connect("localhost","root","root"); mysql_select_db("test"); if($xss!==null){ $sql="insert into xss(id,s) values('1','$xss')"; $result=mysql_query($sql); echo $result; } ?>
//显示数据库查询页面
<?php
    mysql_connect("localhost","root","root"); mysql_select_db("test"); $sql="select s from xss where id=1"; $result=mysql_query($sql); while($row=mysql_fetch_array($result)){ echo $row['s']; } ?>


3.DOM型

类似于反射型,但是直接在前端输出,而不经过后端

<?php  
    error_reporting(0);
    $test = $_GET["test"];  
?> <html> <input id="text" type="text" value="<?php echo $test;?>" /> <script type="text/javascript"> var text = document.getElementById("text"); document.write(text.value); </script> </html>

关于DOM型

<html>

<body>
<input id="id" type='text'> <script> //var a='<script>alert(1)<\/script>'; var a="<img src=1 onerror=alert(1)>"; document.getElementById("id").innerHTML=a; </script> </body> </html>

上面的代码,如果是<script>alert(1)</script>不会触发弹窗

如果是<img src=1 onerror=alert(1)>则会触发弹窗

原理应该是(?)

浏览器对<script>标签DOM操作时,会页面渲染,不会再JS解析

4.触发

如果我们可控的数据在标签的属性当中

<1>资源属性

使用 javascript伪协议

基本上可以请求资源的HTML标签内都可以使用src\href等

但是有的标签已经不能触发XSS,有的则可以

<html>
<script> var lang = document.location.href.substring(document.location.href.indexOf("id=")); lang=lang.substr(3,); document.write('<a href="'+lang+'">test</a>'); document.write('<iframe src="'+lang+'">'); document.write('<img src="'+lang+'">');//不能触发 </script> </html>

JS伪协议不区分大小写,并且会自动实体解码和进制解码

javascript:alert(1)
JavascRipt:alert(1)

等等都可以触发

<2>事件属性

<html>
<script> var lang = document.location.href.substring(document.location.href.indexOf("id=")); lang=lang.substr(3,); document.write('<a href=1 onclick="'+lang+'">test</a>'); document.write('</br>'); document.write('<a href=1 onmouseover="'+lang+'">test1</a>'); </script> </html>

事件不区分大小写,引号可以不使用也可是是单引号或双引号

<html>
<script> var lang = document.location.href.substring(document.location.href.indexOf("id=")); lang=lang.substr(3,); document.write('<a href=1 onmouseover="'+lang+'">test</a>'); document.write('</br>'); document.write("<a href=1 onmouseover='"+lang+"'>test1</a>"); document.write('</br>'); document.write('<a href=1 onmouseover='+lang+'>test</a>') </script> </html>

上面的三种都是一样的

<3>普通属性

想办法构造新的属性或者闭合标签

5.HTMLENCODE

有些标签具备HTMLENCODE功能

<html>
<textarea><img src=1 onerror=alert(1)></textarea> <title><img src=1 onerror=alert(1)></title> <iframe><img src=1 onerror=alert(1)></iframe> <noscript><img src=1 onerror=alert(1)></noscript> <noframes><img src=1 onerror=alert(1)></noframes> </html>

剩下的,比如div标签

<html>
<div><img src=1 onerror=alert(1)></div> </html>

6.进制转换

<1>HTML

HTML支持十进制和十六进制

图片可以正常显示

<2>CSS

CSS支持十进制和十六进制

<3>JS

JS支持八进制和十六进制

<html>
<script>alert(1)</script> <script>eval("\141\154\145\162\164\50\62\51")</script> <script>eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0033\u0029")</script> </html>

进制方式对大小写不敏感,后缀’;’也不是必须的,所以可以用常规字符、十进制编码和十六进制编码混合

如果给汉字编码,则只能使用十六进制的unicode

7.源码审计

<1>反射型和存储型

查找在页面输出的变量,检验是否收到用户控制,跟踪传递过程,分析是否被过滤。

主要关注 $_SERVER,$_GET,$_POST,$_REQUEST查找输出的变量,检验是否可控,查看是否被过滤print,print_r,echo,printf,sprintf,die,var_dump,var_export

主要出现在搜索框、文章发表、评论回复、留言、友情链接、资料设置等处

<2>DOM型

1. 查看用户的某些输入源

document.referer

window.name

location

2. 输出

innerHTML

document.write

8.防御

<1>反射型和存储型

对用户的输入进行过滤

黑白名单输入进行编码    

htmlspecialchars()

<2>DOM型

避免客户端对文档进行重写、重定向或其他敏感操作

避免使用客户端数据,这些操作尽量放在服务端使用动态页面来实现

猜你喜欢

转载自www.cnblogs.com/zmqqq/p/10780197.html