细品某语义waf的xss防护(4)

问题背景

假设攻击场景如下

1
2
3
4
5
6
7
8
9
10
漏洞输出位置在JS环境中,如下面3种场景

<script>
var a="用户输出可控位置"; // 1

func("用户输出可控位置"); // 2

eval("用户输出可控位置"); // 3

</script>

在这个场景下,验证厂商的安全防护策略

分析思路

  • 判断支持哪几种引号的闭合
  • 对每类攻击场景单独测试,根据拦截情况推测安全防护策略

分析过程

判断支持哪几种引号的闭合

现代的Javascript支持三种方式表示字符串

1
2
3
var a='xx'
var a="xx"
var a=`xx`

因此同一个攻击场景会因为字符串写法细分成三类。

测试payload是否被拦截

1
2
3
`-alert(1)-`   没有拦截     说明不支持拦截 var a=``-alert(1)-``;  这种攻击
"-alert(1)-" 拦截
'-alert(1)-' 拦截

小结:

  • 支持单引号、双引号,不支持反引号

  • 不支持防护下面的攻击场景

    1
    2
    3
    var a=`用户输出可控位置`;
    func(`用户输出可控位置`);
    eval(`用户输出可控位置`);

单独测试

  • var a=”用户输出可控位置”;

    1
    2
    ";xxx.alert(1);//   拦截
    ";xxx.xxalert(1);// 不拦截

    小结:

    • 解析js && 存在”对象.函数()”形式或者”函数()”函数形式的函数调用 && 函数名在黑名单中 则拦截
  • eval(‘用户输出可控位置’);

    漏洞利用时,如果不闭合引号

    1
    2
    3
    4
    5
    6
    self["xxxx"](1)    拦截
    selxfxx["alert"](1) 不拦截
    selfxx["alert"](1) 拦截
    self.xxx(1) 不拦截

    说明安全策略可能是:函数调用 && 形式为"对象[属性]()" && 对象名在黑名单中 (前缀匹配)

    漏洞利用时,如果闭合引号,就和func('用户输出可控位置')攻击场景一样了

    小结:

    • 解析js && 存在”对象.函数()”形式或者”函数()”函数形式的函数调用 && 函数名是否在黑名单中 则拦截 (之前测试<svg/onload="用户输出点">场景得出结论,在这里也适用)
    • 解析js && 函数调用 && 形式为对象[属性]() && 对象名在黑名单中 (前缀匹配) 则拦截
  • func(‘用户输出可控位置’);

    1
    2
    a='-alert(1)//   拦截
    a='-alert(1)- 拦截

    小结: 解析js && 存在”对象.函数()”形式或者”函数()”函数形式的函数调用 && 函数名在黑名单中 则拦截

不能解释的奇怪现象

  • 测试过程中 ";alert(') payload 被拦截

    按照我的经验,";alert(') payload无论对应到哪一类攻击场景都不会是正确的js语法,因此不应该被语义waf拦截。

    虽然 “;alert(‘) payload在下面场景下可以弹框

    1
    2
    3
    <script>
    var a="用户输出'); // var a="";alert(')');
    </script>

    但是几乎不可能有开发写出上面的代码。

    所以,有两个问题:

    1. 这个payload是否有对应的漏洞场景?
    2. 如果有对应的漏洞场景,对应的漏洞代码会长什么样?

总结

  • 可能的安全策略:
    • 解析js && 存在”对象.函数()”形式或者”函数()”函数形式的函数调用 && 函数名在黑名单中 则拦截
    • 解析js && 函数调用 && 形式为对象[属性]() && 对象名在黑名单中 (前缀匹配) 则拦截
  • 有一些payload被拦截的原因目前无法解释