XSS Game

过年期间玩了一下国外的一个 XSS GAME,收获颇丰,记录一下学习过程。本人对于 JavaScript 以及前端的理解不深,水平也不高,如果文章有疏漏之处,还请师傅们斧正。

Introduction

所有题目的目标都是实现alert(1337)即可,有着不同的难度

Area 51


题目源代码如上,题目代码比较简单,首先对用户传入的 debug 参数进行关键字过滤转换,对于!-/#&;%符号都会被下划线替代,然后创建一个 template 标签,标签的 HTML 内容为我们传入的内容,最后在一个 div 中,把构建好的 template 标签输出在一个注释当中。

所以我们的主要得绕过注释符的限制,由于中的>进行转义。所以基本上我们可以“直接“闭合的思路是行不通的。

首先我们需要知道 HTML 解析顺序,首先先解析 HTML 部分代码,再用 JS 解释器 JS 代码,JS解释器会边解释边执行,对于 innerHTML 会使用 HTML parser 解析其中的代码。本题会利用到一些 HTML parser 的知识,建议配合 W3 文档 The HTML syntax ,不想看英文的话也可以凑合凑合看看本菜之前写的 关于 HTML 编码 的水文。

Easy Version

我们先来看看第一个简单的版本,当时由于出题者比较疏忽,并没有过滤&#;,导致了我们可以用 HTML 实体编码进行绕过,直接闭合注释进而实现 alert ,例如,在没有过滤&#;的情况,我们可以这么做:

1

使用 HTML 编码将我们的 payload 进行编码绕过

-->

但是这里我们并不能直接传入 HTML 编码绕过,得需要加一个 img 标签利用其属性进行绕过,为什么呢?

因为这里其实有两次 HTML 解码的操作,第一个是template.innerHTML,第二个是pwnme.innerHTML,第一个解码操作会直接把我们传入的参数进行解码,并且对其中的<>进行转义,也就是说,实际上第一个得到的是如下内容:

-->

在第二步渲染的时候就自然不可能闭合注释了,只能得到如下代码:

 

-->

所以当我们借助 img 属性进行绕过的时候,第一步得到的实际上是:

1

HTML parser不会将 title 属性内的字符串进行转义,所以第二步当直接输出到页面的时候

">1 

-->

然后当 HTML parser 解析这段代码时,首先由Markup declaration open state ,中间的代码

DEBUG: