XSS漏洞:prompt.mi靶场通关

xss系列往期文章:

初识XSS漏洞-CSDN博客

利用XSS漏洞打cookie-CSDN博客

XSS漏洞:xss-labs靶场通关-CSDN博客

目录

第0关

第1关

第2关

第3关

第4关

第5关

第6关

第7关

第8关

第9关

第A关

第B关

第C关

第D关

第E关

第F关


上一篇文章给大家演示了经典的xss靶场xss-labs的通关文章,那么在本篇中我会学习+练习演示一个在线的xss靶场:prompt(1) to win - 0x0

那么现在开始ヾ(°∇°)ノ゙

首先在浏览器中访问该页面:

XSS漏洞:prompt.mi靶场通关_第1张图片

可以看出来这里页面和前面的xss-labs靶场的页面是不同的,这里直接将后端代码展示了出来,我们可以看到输入的参数在代码中的体现,好像是更加方便的观看了

我们刚点击进网站就直接在第0关,那么我们来看看这一关

第0关

我相信刚开始一定不会很难吧,我们直接闭合前面的标签,然后尝试传入弹窗代码

XSS漏洞:prompt.mi靶场通关_第2张图片

成功过关 

第1关

这里很轻松的就来到了第1关,我们直接尝试进行弹窗先来看看后端代码做了什么限制

XSS漏洞:prompt.mi靶场通关_第3张图片

从后端代码和输出的结果可以看到我们输入的内容被包裹在

中并且对我们输入的内容进行了过滤将所有的< / > 都过滤掉了

因此这里我们可以使用没有进行限制的弹窗代码来进行弹窗

XSS漏洞:prompt.mi靶场通关_第4张图片

成功过关 

第2关

现在来到了第2关,还是一样我们先试试弹窗看看有什么限制

XSS漏洞:prompt.mi靶场通关_第5张图片

从后端代码和输出的记过都可以看到这对我们输入的(和 = 进行了限制,无法使用事件on,并且结,现在就很头疼了既然要求要弹窗prompt(1)才可以过关,这里没有了(相当于直接把锁换了,这该怎么办的

这里我想到了使用反引号``因为它有时很可以起到与()一样的作用,那么来尝试一下

XSS漏洞:prompt.mi靶场通关_第6张图片

但是这里却没有成功

我们试试alert是可以成功弹窗的的:

XSS漏洞:prompt.mi靶场通关_第7张图片

那么既然无法使用``就只能想别的办法

解法1:编码

我们可以svg加上对()进行编码来绕过限制

XSS漏洞:prompt.mi靶场通关_第8张图片

解法2:模板字符串

因为本关将=也限制了,无法使用on事件,所以就不能使用html实体编码的形式绕过,所以本关就只能使用模板字符串来进行绕过。因为本关在 \n\ '; } catch (e) { return 'Invalid form data.'; } }

通过代码和注释可以看出来,题目构造post表单,我们需要输入的格式为formURL#formDataJSON

比如http://httpbin.org/post#{“name”:“Matt”},具体过程是先提取formURL构造form表单,formURL赋值给form标签中的action,然后post内容构造input标签。

我们想嵌入代码,经常能见到类似action=”javascript:alert(1)”的内容,但是后面还过滤了document.form[0].action内容,过滤了script和data。

如下图所示

XSS漏洞:prompt.mi靶场通关_第18张图片

但是过滤存在缺陷,由于存在子级tag,action 将会优先指向name为action的子tag。

所以我们在构造payload时,可以将input标签的name属性值设置为action,这样document.form[0].action指向的就不是form标签中的action了,因此过滤也就不起作用了。

Payload:

javascript:prompt(1)#{"action":"yps"}

XSS漏洞:prompt.mi靶场通关_第19张图片

成功过关 

第7关

现在来到了第7关,直接试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第20张图片

从代码和结果中都可以看出来这一关对输入的长度进行了限制,我们只能输入12个字符

但是想要弹窗就必须要输出、prompt(1),这个字符串就占9个字符,这里就有点头疼了

但是这里再看看代码发现了一个分割#的代码,我们可以利用这个来试着分多次传入参数就可以保证每次输入都小于12个字符了

">
或者
">

XSS漏洞:prompt.mi靶场通关_第21张图片

XSS漏洞:prompt.mi靶场通关_第22张图片

 成功过关

第8关

现在到了第8关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第23张图片

可以看到这里我们传入的值被放在一个console.log()中,并且可以在代码中看到,对\r \n < / 进行了过滤

所以需要绕过过滤规则逃脱出双引号或者本行。

这里过滤了两个换行符,所以用到了一个特殊的编码技巧:

U+2028,是Unicode中的行分隔符。
U+2029,是Unicode中的段落分隔符。
–> 在 js 中可当注释使用

现在徐璈利用换行来逃避前面的注释符,但是无法使用\n,需要使用]\u2028来进行换行

有了这个技巧我们就可以使用下面的代码进行弹窗:

XSS漏洞:prompt.mi靶场通关_第24张图片

XSS漏洞:prompt.mi靶场通关_第25张图片

成功过关

第9关

现在到了9关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第26张图片

可以看到我们输入的值被放在了h1中,然后对<后的第一个字符替换为了_

后面的toUpperCase()不仅转换英文字母,也转换一些Unicode字符,比如将ſ 传入就可以转换为 S ,这样就可以绕过。

直接构造<ſcript>prompt(1)不行,因为javascript对大小写敏感,,不识别PROMPT(1)。

所以我们可以使用标签在事件中对prompt进行编码。

payload为:

<ſvg/onload="prompt(1)"

XSS漏洞:prompt.mi靶场通关_第27张图片 

成功过关 

第A关

现在到了第A关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第28张图片

可以到这里对输入的字符进行了url编码,并且将输入的promt替换为了aler并且过滤了单引号。但因为他先替换prompt再进行单引号替换为空的操作,所以我们可以构造payload为:

promp't(1)

XSS漏洞:prompt.mi靶场通关_第29张图片

成功过关 

第B关

现在到了第B关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第30张图片

可以从输出的结果和代码中看到,这里对我们输入了内容进行了严格的过滤

第一个思路是利用js的一个特性进行绕过。在js中,键名相同,输出后值是后面的变量的值。

可以通过下面这个例子来理解

XSS漏洞:prompt.mi靶场通关_第31张图片 

 因此构造思路是构造 ","message":"prompt(1)",可是正则表达式中过滤了冒号,所以这种方法不可取,只能另想办法。

在js中,(prompt(1))instanceof"1"(prompt(1))in"1"是可以成功弹窗的(可以自己在console试一下),其中双引号里面的1可以是任何字符,这里的in或者instanceof是运算符,所以可以有这样的语法结构。

"(prompt(1))in"

XSS漏洞:prompt.mi靶场通关_第32张图片 

成功过关 

第C关

现在到了第C关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第33张图片

可以看到我尝试进行弹窗后,居然真的进行了弹窗,但是当我点击确定后却没有显示youwon,因此说明还是有问题的

从代码中我们可以看出本题修改了第十题的顺序问题,所以之前方法用不了了,只能尝试什么别的方法。所以只能试试编码或是函数,想到sql中有那种利用函数转换成字符的,尝试一下。

XSS漏洞:prompt.mi靶场通关_第34张图片

parselnt:解析一个字符串并返回指定基数的十进制整数,并且进制数的范围是2-26.

但是我们在转换prompt的时候,在26之前是没有数的,显示的都是NAN,
但是在26之后就有值了;这是因为他转换是由0-9+a-z组成的,而p是字母的第16位,
然后加上前面的10个字符,就等于26,所以才从第26位开始,
这里可能不好理解,就好比十六进制,他的最大的字母F,f拍在第6位
加上前面那个就是16进制为什么这里要写30进制,因为prompt最后一个字母是t
排在字母表的第20位置,加上前面的10个数就是30;如果使用小于30的数
就不包括了t,这样就不完整了。

因此我们构造下面的payload:

eval((630038579).toString(30))(1)

 XSS漏洞:prompt.mi靶场通关_第35张图片

第D关

现在到了第D关

这一关也是属于代码非常多的一关:

 function escape(input) {
    // extend method from Underscore library
    // _.extend(destination, *sources) 
    function extend(obj) {
        var source, prop;
        for (var i = 1, length = arguments.length; i < length; i++) {
            source = arguments[i];
            for (prop in source) {
                obj[prop] = source[prop];
            }
        }
        return obj;
    }
    // a simple picture plugin
    try {
        // pass in something like {"source":"http://sandbox.prompt.ml/PROMPT.JPG"}
        var data = JSON.parse(input);
        var config = extend({
            // default image source
            source: 'http://placehold.it/350x150'
        }, JSON.parse(input));
        // forbit invalid image source
        if (/[^\w:\/.]/.test(config.source)) {
            delete config.source;
        }
        // purify the source by stripping off "
        var source = config.source.replace(/"/g, '');
        // insert the content using mustache-ish template
        return ''.replace('{{source}}', source);
    } catch (e) {
        return 'Invalid image data.';
    }
} 

这里根据代码,我们可以看出必须满足一下要求:

  1. 首先,你的数据格式必须是json格式的

  2. 控制

  3. 闭合双引号

每个对象都会在其内部初始化一个属性,就是proto,当我们访问对象的属性时,如果对象内部不存在这个属性,那么就会去proto里面找这个属性。

那么基本上就是构造{"source":"'","__proto__":{"source":"onerror=prompt(1)"}},由于前面有非法字符',则会删除,但是在替换的时候由于过滤了",无法闭合,那么正好有一种特殊的替换方式

因此可以构造下面的payload:

{"source":"'","__proto__":{"source":"$`οnerrοr=prompt(1)>"}} 

XSS漏洞:prompt.mi靶场通关_第36张图片 

第E关

现在到了第E关,不管怎样,我们先试试进行弹窗

XSS漏洞:prompt.mi靶场通关_第37张图片

可以看到,这里后端代码将我输入的代码中的字符全部转换为了大写字符

后面的代码将//和字母换为data:,然后将`\、&、+、%和空白字符,vbs替换为_,所以不能内嵌编码后的字符,由于js大小写敏感,所以只能引用外部脚本。  

由于本题的输入全被转换成大写的,正常的payload是无法被解析,老实说这题的官方答案都无法成功执行,看解释的大概意思我猜是火狐浏览器是可以支持大写的base64的解析,然后精心构造一个大写的base64编码,解码后恰好可以达到上面的效果,便能够成功执行,但是我实验后是失败的,我看其他人的wp也都说失败了,不是很清楚具体原因是什么。

这里我直接从别人那些拿到了一个参考payload:

">