前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零开始学web安全(2)

从零开始学web安全(2)

作者头像
IMWeb前端团队
发布2019-12-04 12:18:34
5110
发布2019-12-04 12:18:34
举报
文章被收录于专栏:IMWeb前端团队

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

实战

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

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

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

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

初探

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

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

代码语言:javascript
复制
<img/src=@ onerror=alert(1) />

查看DOM如图所示:

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

代码语言:javascript
复制
<script>alert(1)</script>
<a href="javascirpt: alert(1)”></a>

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

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

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

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

代码语言:javascript
复制
<button onclick="alert(1);">xss</button>

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

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

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

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

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

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

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

代码语言:javascript
复制
 在html标签属性的值里字符实体是会被转换成相对的字符的。这意味着下面这两个是等价的:
<button onclick="javascipt:alert(1);">xss</button>
<button onclick="j&#x61;vascipt:alert(1);">xss</button>

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

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

代码语言:javascript
复制
<button test="j&#x61;vascipt:alert(1);">xss</button>

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

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

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

代码语言:javascript
复制
<form id="test"></form><button form="test" formaction="alert(1)">X</button>

结果评论展示成了这样:

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

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

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

遗憾的是。。这个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:

代码语言:javascript
复制
<a href="j&#x61;vascript:alert(1);">test xss</a>

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

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

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

代码语言:javascript
复制
 <svg width="140" height="30" xmlns="http://www.w3.org/2000/svg">
        <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="j&#x61;va&#x73;cript&#x3a;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里面的东西也被过滤光了。。如图:

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

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

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

代码语言:javascript
复制
 <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="j&#x61;vascript:alert(1)" /> </animate>
        </a>
</svg>

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

总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-02-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实战
    • 初探
      • 字符实体问题
        • animate绕过
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档