LWDW!

Learn the work from doing the work🍺

《试图了解XSS注入,却发现了奇妙的基础问题!》
Posted on 2017-09-26

啧,现在的轻小说起名真是浮夸【瞄】

web安全,xss注入,blablabla......相关的博文看了不少,感觉相当单纯,不就是<script>嘛!转义嘛!结果自己尝试时又是喜闻乐见地发现,注入还没看多少,基础问题暴露一堆。

注入入口 and 渲染方式

xss注入实现的攻击,总的来说是:

  1. 通过某种方式将需要执行的代码注入到服务器所存储的数据中
  2. 其他客户端从服务器拿到数据渲染时,执行了注入其中的代码

从某种意义上讲,这两步需要成功匹配,才能实现注入

耿直注入

最容易想到的注入入口就是input输入框,在这里就涉及到一个小知识点:input输入框中的内容(value属性值)是转义后的值。记好这一点嗯嗯。

确定从 input 进行注入后,需要考虑的就是客户端的渲染方式了——咱尝试了以下几种方式:

  1. 首先很想当然的,想通过设置 dom元素的**innerHTML**属性进行渲染,然而…不行!innerHTML的确会非常耿直的把标签啥的直接当作节点插入,但是插入后不会执行<script>内的内容,所以咱的脚本成功进入了客户端,却未被执行,可惜可惜。
  2. 通过**appendChild()**方法,是可以的!
  3. Jquery的**append()**方法也是通过innerHTML渲染,但它会试图找到script标签,将其通过eval()执行,所以当然是可以的。要是用这种方法渲染用户可以决定的字段,简直是二五仔啊!

防范?

所以就像所有博文都会告诉你的防范方法:转义 <>,将其变为html字符实体,于是可喜可贺可喜可贺,这种方法可以毁灭性的摧毁用<script>字符串进行注入的想法,以上三种渲染方式都不会中招。

当然,道高一尺魔高一丈嘛,接下来博文就会告诉你,你可以用 unicode码 来表示 <>,于是咱就迫不及待的在输入框中输入了伪装后的代码,然而它们却...直接被渲染出来了…没错,上面提到了,input输入框中的内容(value属性值)是转义后的值,你以为我是unicode码,其实我被已经转义啦(dio脸)!所以如果你想通过unicode码伪装,恐怕需要自己手动为请求数据赋值,比如从控制台手动请求接口。

套路注入

假设我们已经成功用unicode码发出了请求,结果是......并没有卵用?嗯?这和博文上说的不一样啊。根据粗浅的研究,似乎是因为咱是node服务器啊,unicode码在node环境下已经被表示为符号形式了?然后直接被上文的防范措施干掉了。不过似乎对于php服务器,unicode码是可以保持它原本的样子,成功绕过上文的防范成功注入。

套路防范

那么我们的解决方法是…没错,继续转义,这次要干掉的是 \,而在这里又意识到个很好笑的问题,因为咱不懂PHP,就试图在js中还原该场景。js中如何匹配字符串中的 \ ?正则应该是 /\\/g,因为 \是本身就是用于转义特殊符号的嘛,那我们可以转义的字符串呢?是这样的"i want to replace \\",这时才意识到这是个大乌龙啊!前面就说过了unicode码,如"\u003c"(<),一旦在node环境中作为字符串出现,会被直接解释为"<",根本轮不到咱插手啊【扑通】。总之,经过一通令人窒息的操作之后,才真切意识到:我们输入的字符,代码执行时所“看到”字符(手动比喻),和输出的字符,很多时候是不一样的。


咱大胆的假设!如果假设真的有除了咱以外的人看这篇水文,会不会有种偏题的感觉?xss都没讲完啊喂,什么img标签onerror注入url注入都没讲诶!emmmmme可是咱在学习时的确会遇到这种“偏题”的情况,咱正是试图用水文的形式记录下这诡异的思路,而不是总结一遍早有无数博文总结的要点【蛤你就是懒】,就是这样!溜了溜了【逃】