xss 漏洞注入原理

什么是xss

xss全称跨站脚本(Cross Site Scripting),为避免与层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故缩写为xss。这是一种将任意 Javascript 代码插入到其他Web用户页面里执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能,在HTML页面里嵌入恶意代码。当用户浏览访问时,这些潜入在HTML中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的,如 cookie窃取等。

题外话:上古互联网中xss漏洞利用可以说是横行猖獗各种盗号钓鱼网页广告等,现在的防护越来越完善xss漏洞作用越来越小,基本都是配合其他的方式来钓鱼了~

xss漏洞注入原理

页面的参数可被用户可控输入且不做防护或防护不完全造成的,恶意用户在参数中的构造好payload(恶意参数)嵌入到页面中,页面把恶意代码解析后造成危害

以下使用xss-labs靶场以及实战业务中的部分代码来进行讲解xss漏洞注入原理

第一关

image.png

可以看到页面中的test字符串是url中的name参数控制的

image.png

第一关源码分析

image.png

第一关的源码中$str = $_GET["name"]的变量$str就直接拼接(php中字符串拼接是使用.来进行拼接字符串与其他语言的+号同理)在了h2标签里

image.png

htmlh标签都是支持其他标签的嵌套,所以我们这里可以直接传输一个<script>alert(1)</script>标签过去即可完成xss的注入

image.png

第二关

image.png

方框中输入字符串并提交

image.png

发现传参改变的是页面源码中input标签的value元素的属性,那么这个属性就是用户可控的

这里构造的payload是"><script>alert(1)</script>

image.png

可以看到payload中的">把页面源码的input标签给闭合了,使用"value元素的属性给闭合再跟着的>input标签给闭合掉,这样浏览器解析器就认为input标签已经结束,后面再执行payload中的<script>alert(1)</script>这样就完成了xss的注入

第二关源码分析

image.png

第二关源码这里$str拼接的有这这两个地方

一个是在h2标签还有一个是input标签

h2标签使用了htmlspecialchars函数来对$str字符串进行了过滤image.png

把在h2标签的$str的字符串中的特殊字符转换成HTML实体编码

image.png

这样可以避免h2标签这里的字符串拼接不被用户注入的payload形成xss攻击

但是input标签里没有这个函数去过滤,所以触发xss的是input这个位置

第三关

image.png

第三关源码分析

image.png

第三关这里给两个参数都使用了htmlspecialchars函数进行过滤

image.png

再来看看htmlspecialchars这个函数

image.png

将特殊字符转换为HTML实体

既然过滤了特殊字符,那就不使用特殊字符就好

构造的payload'onmouseover='alert(1)'//

image.png

成功注入并没有被过滤掉

这里的payload'onmouseover='alert(1)'//原理和第二关差不多,因为这里的标签使用的是'使用所以使用'把前面的value元素进行闭合,再添加一个事件元素onmouseover鼠标触碰事件,当鼠标指针触碰到这个input标签就会触发属性中的js代码,然后再使用//注释掉后面多余的单引号

image.png

第七关

image.png

第七关源码分析

image.png

第七关源码里使用了strtolower把接收到的参数全部替换成小写

image.png

然后再使用str_replace函数把script, on, src, data, href等关键词替换成空

image.png

最后把结果拼接到input标签的value元素的属性里

这里绕过其实很简单,因为str_replace这种替换的函数都只会替换一边,替换后就不会再继续检测是否还存在关键词了,所以可以使用双写来进行绕过

image.png

所以payload是"oonnmouseover="alert(1)"//,因为过滤掉了on,所以双写on就可以绕过了

image.png

业务源码实战

这里源码用的是jsp,因为逻辑跟靶场都差不多就直接放上来了

源码分析

image.png

这里使用requests.getParameter("tableId")来获取参数值,然后再使用replaceAll<>"'\][+],这些字符都给过滤成空,最后赋值给变量tableId,然后这个tableId的变量被直接作用在html标签的id元素里

image.png

经过测试然后防火墙还把javascript script alert 空格 () 等敏感词给过滤成空了

结合上面靶场的训练

构造出的payload

%22%0a%0d+onmouseover%3d%22alalertert%60a%60%22%0a%0d//

url解码后的样子

image.png

使用"闭合inputid元素后再使用url编码后的换行符%0a%0d来代替空格进行绕过然后再添加onmouseover事件参数alert再进行双写绕过,过滤了()就使用飘点来代替括号最后再使用//来注释掉后面的代码

这样xss就注入成功,鼠标触碰这里的input框即可弹出

image.png