转载

从零开始学web安全(2)

上篇文章讲解了xss的一些基础知识,这篇文章继续研究学习。上篇文章提到了一些理论性的东西,看完估计感觉很快也忘了。简单回顾一下,讲了xss分类:存储型XSS,反射型XSS,DOM XSS。讲了几个简单的payload,也只是理论性的东西。这篇先不继续看理论了,先来尝试尝试如何使用payload~ 玩起~~

实战

理论的东西看了也很快就忘记了,于是我决定找个东西实际玩一玩~ 就从身边的东西,imweb博客入手好了。

仔细看了一下博客,最容易xss的似乎是文章里面的评论框,这个评论框是支持富文本的,当富文本一进来就意味着风险也一并进来了。

评论框的过滤规则一般有两类,第1类我们称为白名单,即:只允许使用白名单内的合法HTML标签,例如IMG。其它均剔除。 第2类我们称为黑名单,即:厂商会构建一个有危害的HTML标签、属性列表,然后通过分析用户提交的HTML代码,剔除其中有害的部分。

我们博客的评论框我测试了一下,应该是黑名单过滤的。

初探

对评论框还完全不了解,看看代码也是压缩了的,懒得去看压缩后的代码= = 直接用富文本试探好了~~

首先我提交了非常简单的一个payload

<img/src=@ onerror=alert(1) /> 

查看DOM如图所示:

从零开始学web安全(2)

有好消息有坏消息,坏消息是我们发现onerror以及它的属性值都被过滤了,但是也有好消息,我们发现直接提交html代码是不会被过滤的,这就为我们之后的xss提供了可能。Ok,继续试试一些常用的:

<script>alert(1)</script> <a href="javascirpt: alert(1)”></a> 

script毫无疑问是会被过滤的,这个我也只是随便试试。a标签当然不会被过滤,但是问题在于我们发现结果是这样的:

从零开始学web安全(2)

整个href及其之后的属性值都被过滤了,这个也在预料之中,我们可以简单的猜测一下原因,也许是:

  1. href 就被过滤了(这个想法后来想想基本不可能, href 要被过滤了正常链接怎么发?当然markdown可以)
  2. 代码里面去判断了 href 里面的值,发现里面有 这样的东西然后把这个href后面所有东西都过滤了,这个可能性无疑是最大的。

好吧,既然要过滤 ,那我找一些不用 的语法不就完了。继续试试,这回不用

<button onclick="alert(1);">xss</button> 

结果我们惊喜的发现, button 居然没有做任何过滤的展示了:

从零开始学web安全(2)

然而点击并没有任何反应,看了一下dom:

从零开始学web安全(2)

有点失落,发现 onclick 以及后面的属性值都被过滤了。这时候我突然想到之前我测试的 <img/src=@ onerror=alert(1) /> 这个payload的 onerror 也被过滤了,几乎是一样的情形。于是我们又得到了一个线索,可以推测过滤代码有这样一段逻辑,判断提交的评论里有没有on起始的属性,如果有的话,会把它过滤了。

梳理一下上面多次测试得到的线索:

  1. 富文本标签允许直接提交.
  2. script 被过滤了。
  3. on 开始的属性被过滤了,比如 onerroronclickonmouseover 等等,这个过滤规则直接废了很多payload。
  4. 被过滤了,这个也让很多payload失去了可能。

字符实体问题

继续尝试payload吗,还是思考一下上面的线索能给我们带来什么?发现线索3过滤 on 还是比较致命的,好像并没有办法绕开这个过滤。但是线索4似乎有机会啊!

这里先说一个简单的小知识,是我们后面成功xss重要的一步:

 在html标签属性的值里字符实体是会被转换成相对的字符的。这意味着下面这两个是等价的: <button onclick="javascipt:alert(1);">xss</button> <button onclick="javascipt:alert(1);">xss</button> 

有没有可能代码里面只是简单的判断了 ,对于字符实体并没有处理呢?

我重新构造了一个payload提交了一下:

<button test="javascipt:alert(1);">xss</button> 

提交之后查看dom,果然没有过滤!而且正确的解析出来了啊!

从零开始学web安全(2)

但是新的问题来了,只有一个 javascipt 有什么用,代码有了,但是这部分代码不会触发执行啊,因为所有 on 开始的属性都被过 滤了。这时候首先想到的是不用 onclick 类似的带 on 的属性一样能触发JS呢?

这时候,想到了@sogili 大神总结的这样一个构造,这个构造完美的避开了 on !利用 formaction 进行表单劫持!

<form id="test"></form><button form="test" formaction="alert(1)">X</button> 

结果评论展示成了这样:

从零开始学web安全(2)

我前面已经试过,button是不会被过滤的。不幸的是, form 在黑名单里面,查看DOM,变成了这样:

从零开始学web安全(2)

ok,到这一步的时候,有一个思路是怎么绕过 form 被过滤成字符串的代码。纠结了一下,我没有想到好的办法可行。但是页面中会不会本来就有现成的 form 可以用呢!直接把页面中现成的 formformaction 进行劫持是不是就可以了!

兴奋之余,我赶紧搜索了一下关键词 form ,果然找到一个 form 表单!

从零开始学web安全(2)

遗憾的是。。这个 form 表单没有 id 属性,原来有没有 id 也能影响到 hack 成不成功,只能说这里 form 表单没带 id 是运气太好了,因为 buttonform 属性是需要带上一个 id 的,没有 id 就做不了劫持了。

好吧,这个思路想下去我也没有想到太好的办法。。

重新整理一下思路,我们现在的进展是:

  1. 富文本标签允许直接提交.
  2. script 被过滤了。
  3. on 开始的属性被过滤了,比如 onerroronclickonmouseover 等等,这个过滤规则直接废了很多payload。
  4. 被过滤了,这个也让很多payload失去了可能。但是在button里用字符实体替换 里的字符可以绕过!
  5. button 没有被列入黑名单
  6. iframeform 等在黑名单里,会被过滤成字符串。

animate绕过

我们最大的进展就是线索4,这时候可能大家已经想到了,有 javascript 还不好办,直接上 a 标签不就完了!我当时也是这么想的,轻松用一个字符实体就可以顺利xss吗?情况没有预想的那么顺利,我直接用下面的payload:

<a href="javascript:alert(1);">test xss</a> 

不出意外,失败了。 href 一样被过滤光了啊。这时候得出下面两个推断:

  1. a 标签里似乎这个字符实体的问题并不存在,目测是对一些无伤大局的标签像button(因为on被处理了),才有字符实体的问题呢。
  2. 也许就真的把 href 整个过滤了。

情况2非常容易验证,直接提交一个正常的a链接就完了~测试发现推断1是正确的,推断2是错的。但是当时推断2给了一个nice的新想法。直接提交a标签不行,但是在svg里一样可以嵌套a标签啊!于是,尝试如下构造:

 <svg width="140" height="30" xmlns="http://www.w3.org/2000/svg">         <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)">             <rect height="30" width="120" y="0" x="0" rx="10"/>             <text fill="white" text-anchor="middle" y="20" x="60">test</text>         </a> </svg> 

svg 里尝试使用 a 标签,遗憾的是 xlink:href 里面的东西也被过滤光了。。如图:

从零开始学web安全(2)

好不容易发现的字符实体的问题在 href 相似的属性里并不存在。怎么办?

有没有办法在提交字符串的时候让 xlink:href 没有敏感的东西,后续再把它设置回去呢。答案是有的!

还是@sogili大神总结的, svg 里可以用 animate 去改变某个属性值,用到这里也一样,先看payload:

 <svg width="140" height="30" xmlns="http://www.w3.org/2000/svg">         <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="">             <rect height="30" width="120" y="0" x="0" rx="10"/>             <text fill="white" text-anchor="middle" y="20" x="60">hack</text>             <animate attributeName="xlink:href" begin="0" from="" to="javascript:alert(1)" /> </animate>         </a> </svg> 

hrefxlink:href 里面不存在字符实体的问题,我们先让 xlink:href 留空防止被过滤。但是其他大部分标签的属性都存在字符实体的问题, animate 也不例外!在 animate 里通过 to="j&#x61;vascript:alert(1)" 改变 xlink:href 的属性值,成功绕过了评论框的过滤!!成功XSS!见图:

从零开始学web安全(2)

从零开始学web安全(2)

总结

尝试的时候确实了解了很多的东西,开发的时候很多东西可能确实自己也没有注意到,很大程度都是因为安全意识不足。这次简单的hack让我尝试了不少好玩的东西~~

下期继续学习web安全~ 继续向@sogili 乌云@心伤的瘦子 学习~ 继续xss~

原文  http://imweb.io/topic/56b876a65c49f9d377ed8ef6
正文到此结束
Loading...