基于Gadgets绕过XSS防御机制

                

这篇文章是之前对CCS 2018 Code-Reuse Attacks for the Web Breaking Cross-Site Scripting Mitigations via Script Gadgets 的阅读笔记,最近整理资料发现放了挺久,于是稍做了一些整理和扩展发了出来。

0x00 背景

这篇论文主要考虑在可以注入任意HTML代码(例如富文本编辑器等应用)的条件下,利用JavaScript库中的一些代码片段(Gadget)来绕过常见的XSS防御机制,包括WAF、浏览器的XSS Filter、HTML Sanitizers、Content Security Policy等。

其中WAF考虑对请求值和返回值进行处理的正则匹配型或者字符匹配型WAF,HTML Sanitizers是则指DOMPurify这种基于DOM解析的XSS过滤器,Content Security Policy则主要考虑启用unsafe-evalstrict-dynamic的情况。

0x01 简单例子

和二进制攻击中的Gadget作用类似,本文中的Gadget是指可能被恶意利用的代码片段,下面以一个简单的例子来说明:

var button = document.getElementById("mbutton");
button.innerHTML = button.getAttribute("data-text");

在这段代码中,取出了Id为mbutton的元素,并将data-text的值赋到了该元素的innerHTML属性。这是一些库中为了实现类似Tooltip等效果常用的一种方式,但在存在这种代码片段的时候,只要构造如下的元素,就可造成XSS攻击。

<button id="mbutton" data-text="">abutton>

0x02 Gadget分类

论文中把可利用的Gadget分为五类,具体如下:

字符串操作

这种Gadget主要是指对字符串的操作,一个字符串在经过操作后可能变为造成攻击的字符。

例如Polymer中的一段代码dash.replace(/-[a-z]/g, (m) => m[1].toUpperCase()),这段代码会把以连字符构成的字符串变为大写,例如像inner-h-t-m-l这种字符串处理后会变成innerHTML。大部分WAF是对请求值和返回值做匹配,而此时传入的是inner-h-t-m-l而不是innerHTML,那么就有可能造成绕过。

元素创建

这种Gadget是像document.createElement(input) document.createElement("script") jQuery("<" + tag + ">") jQuery.html(input) 这种直接创建的标签甚至script的代码片段。当输入一定程度可控时,则可利用这种Gadget。

函数创建

这种Gadget是指创建函数的代码段,比如Underscore.js中发现的一段代码:

source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
var render = new Function(
settings.variable || 'obj', '_', source);

这种Gadget会间接执行构造的代码段,在一定条件下可造成攻击。

JavaScript代码执行

这种Gadget主要是指类似eval这种会直接执行传入代码的代码段,例如:

eval(input);
inputFunction.apply();
node.innerHTML = "prefix" + input + "suffix";
scriptElement.src = input;
node.appendChild(input);

表达式解析

很多前端框架都提供了自己的模版引擎,有着丰富而强大的功能,这种Gadget就是框架中对模版表达式解析执行而造成的问题。例如Aurelia框架中可以用下面这段代码来触发一个代码执行。

0x03 例子

例一

论文中提及的例子很多,本文选取其中一个在jQuery Mobile中的Gadget来介绍:

if (myId) {
    ui.screen.attr("id", myId + "-screen");
    ui.container.attr("id", myId + "-popup");
    ui.placeholder
        .attr("id", myId + "-placeholder")
        .html("");
}

这个Gadget会提取data-rolepopup的元素,获取其id中的内容,并调用.html,那么就可以构造一个如下的PoC:

<div data-role=popup id='-->
<script>alert(1)</script>'>
div>

在这个PoC中,没有

你可能感兴趣的:(基于Gadgets绕过XSS防御机制)