前言

这一篇是 rblog/ez4cr 这两道 XSS 题目的学习。

搭 nextphp 的环境的时候踩了一些坑,有点难受。


Chrome XSS Auditor

XSS Auditor 是 Chrome 用来防范反射型 XSS 的一种机制,主要工作原理就是字符串匹配,在语法解析阶段,Chrome 会逐一扫描文档中的标签,然后检查这些标签中的属性,如果检查到危险的属性就会跟 URL 进行比较,如果 URL 中含有同样的危险数据,XSS Auditor 就会认为这是一个反射型 XSS,并加以拦截。

XSS Auditor 有两种模式,block 和 filter,block 模式下拦截会丢给你一个异常页面,filter 模式则会将它觉得恶意的代码替换掉。

Chrome 在 57 版本的时候将默认模式设置为了 block,在 74 版本又将默认模式设置回了 filter。开发者也可以通过:

X-XSS-Protection: 1; mode=block

这样子的 HTTP 返回头来设置 Chrome 的拦截模式。

一个拦截的栗子:

解析器解析:

<iframe src="x" onerror="alert(1)"></iframe>
  1. 依次检查标签 iframe 是否包含恶意属性,src/onerror

  2. 如果 src 不是以 javascript: 开头,则安全,放行

  3. onerror 中含有脚本,检查 URL 是否包含

  4. 如果出现在 URL 中,认为存在安全问题,将过滤:

    <iframe src="x" onerror="alert(1)"></iframe>
    
  5. 中止 iframe 标签检查

而实际上,XSS Auditor 的检查要更加简单粗暴一点,一个简单粗暴的例子如下:

看起来它并不在意你的标签是什么,也不在意你的事件是什么,这匹配也是很简单粗暴……

iframe 标签的 srcdoc 属性也很粗暴:

src 属性一样粗暴,不能是 javascript: 打头,在 script 标签里面的时候也不能有 GET 参数:

还有更简单粗暴的:

由于浏览器无法区分 URL 中的数据是不是真的填充到了页面中,所以甚至会把静态页面中的 JavaScript 代码给一刀切了,而在 filter 模式下,有时候就可以利用这一点来吃掉页面中本来有的 JavaScript 代码。

block 模式也有利用方式,比如之前 35C3 的题目,我们可以利用 XSS Auditor 来泄露用户的数据。

我说的肯定不够详细,大家可以自行探索。


编码

在 Web 应用的交互中,最主要的是两个地方的编码,URL 和 HTML 页面。

原来 script 标签也可以设置加载的 js 文件的编码。

浏览器对请求 URL 的编码有如下规则:

浏览器会按照编码对请求的 URL 进行编码。

HTML 页面的编码有三种设置方式:

HTML 会按照设置的编码对服务器的响应进行解码。

通过设置 Conteny-type 为 gbk 的方式好像绕不过 XSS Auditor,预期解究竟是什么呢?


赛题复现

bot 好像关了,我提交自己的 IP 都没有反应,所以这里只写下简单的思路。

rblog

因为后端进行了 JSON 编码,所以使用非 ascii 字符就可以绕过 XSS Auditor,所以给 iframe 加点中文句号绕过 XSS Auditor,再用 HTML 实体编码绕过 JSON 编码来闭合 script 标签。

因为使用的是 iframe,所以跳转需要使用 parent.location.href。

ez4cr

这题的非预期是因为 Cloudflare CDN 对 HTTP 协议进行了 upgrade,http 变成了 https 导致了页面和 URL 不一致,从而绕过了 XSS Auditor。腾讯云的 CDN 好像没有这种功能。


参考文章:

https://www.cnblogs.com/sevck/p/8868605.html

https://yanhaijing.com/web/2014/12/20/web-charset/

https://www.ibm.com/developerworks/cn/web/wa-lo-ecoding-response-problem/index.html