ES6中的模板字符串和新XSS Payload

www.96kaifa.com | 2016-10-30 |

摘要:*本文原创作者:Sunnieli,本文属FreeBuf原创奖励计划,未经许可禁止转载
众所周知,在XSS的实战对抗中,由于防守方经常会采用各种各样严格的过滤手段来过滤输入,所以我们使用的XSSPayload也会根据实际情况作出各…...

*本文原创作者:Sunnieli,本文属FreeBuf原创奖励计划,未经许可禁止转载

众所周知,在XSS的实战对抗中,由于防守方经常会采用各种各样严格的过滤手段来过滤输入,所以我们使用的XSSPayload也会根据实际情况作出各种各样的调整,最常见的如避免括号,避免引号,避免关键字等,以绕开过滤函数的检查,从而成功将代码注入到网页中运行。

在传统的XSS Payload变形中,常用的无非有以下几种:

1. 使用String.fromCharCode来避免关键字,如String.fromCharCode(97,108,101,114,116,40,49,41);

2. 使用URL编码来避免括号的识别,如location=’alert%281%29’;

3.使用正则对象的特点来避开引号,如alert(/1/);

在多年的研究中基本上传统的变形手段都被研究的差不多了,很难找到创新的绕开手段。

然而,近几年ECMAScript新版本的不断发展和推行,在带来了各种激动人心的语言特性的同时,也不可避免地带来了一些新的安全挑战。本文中所说的模板字符串,便是ECMAScript 6草案中的一种新特性。

如MDN中所述,模板字符串(Template literals)允许嵌入表达式,并且支持多行字符串和字符串插补特性。基本语法为以下几种:

Clipboard Image.png

其中第一行为最基本用法,即使用反引号 (‘`’) 来代替普通字符串中的用双引号和单引号。第二行为多行字符串用法,即反引号中文本可以直接接受换行而不必使用\n换行符来强制换行。

第三行则为模板字符串的最核心用法,即反引号中的${expression}占位符中expression可以为任意的JavaScript表达式,甚至为模板字符串。第四行则为使模板字符串变强大的最主要原因,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以在通过该函数对模板字符串来进行操作处理。

在了解了以上知识后,我们不难发现,对于一个最简单的XSS Payload:alert(‘A’)来说,我们可以利用上述例子第一行的知识,使用“`”来代替引号,即成为alert(`A`)。之后,使用第四行的标签用法,我们可以直接去除括号,写成 alert `A`。最后,由于ECMAScript 6中支持直接用码点(code point)来表示Unicode字符,即直接写成”反斜杠+u+码点”。因此为避免alert关键字被识别,我们可以使用Unicode字符来替换alert几个字符,将payload写成\u0061\u006c\u0065\u0072\u0074`A`。此时最终的payload已经完全见不到alert关键字,括号,以及引号了。

测试结果如下:

Clipboard Image.png

以上的方法经测试,在最新版本的Chrome,Firefox以及Edge浏览器中均可以执行。我们可以看出,ES6的新方法给我们带来便利的同时,也给XSS字符的安全监测带来了新的挑战。