XSS

1,152 阅读5分钟

前言

XSS (Cross Site Script)跨站脚本攻击。攻击者往Web页面里插入恶意js代码,当别的用户浏览该页时,嵌入其中的js代码会被执行,从而达到恶意用户目的。

XSS 分类

  • 1、反射型XSS:服务端未对用户输入进行过滤直接返回客户端用户输入的含有恶意代码内容给页面,服务端未进行存储,反射型XSS容易出现在搜索页面或文章标题处。
  • 2、存储型XSS:恶意代码是存储在服务器中的,如在添加、修改个人信息或发表文章等地方,加入恶意代码,如果后台没有过滤或过滤不严,那么这些代码将储存到服务器中,当有用户访问该页面的时候都会触发代码执行,这种XSS非常危险,容易造成蠕虫,盗窃用户cookie。
  • 3、DOM型XSS:基于文档对象模型(Document Objeet Model)DOM的一种漏洞。允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果成为页面的一部分。DOM中一些对象是用户可以操纵的,如uRI ,location,refelTer等。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。

XSS 漏洞原理

  • 1、反射型XSS

经过后端,不经过数据库,攻击者在URL中插入XSS代码,服务端将URL中的XSS代码输出到页面上,攻击者将带有XSS代码的URL发送给用户(经过短网址处理后不好识别),用户打开后受到XSS攻击。

  • 示例1

打开Firefox输入url:http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case01-Tag2HtmlPageScope.jsp

当我们输入 hello ,页面返回 "hello" :
当我们输入 test ,页面返回 "test" :
以上都为正常的输出,测试一下js代码? 如我们输入<script>alert('xss')</script>
可以看到浏览器成功弹窗,说明我们的js代码成功被执行了。

  • 示例2

http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case03-Tag2TagStructure.jsp?userinput=textvalue 我们继续换Case03-Tag2TagStructure.jsp为例练习:

可以看到我们在URL中输入的参数在text框中回显,查看其源代码:
我们想办法在其展示的地方插入我们的js代码: http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case03-Tag2TagStructure.jsp?userinput="><script>alert('xss')</script>
"><script>alert('xss')</script>,我们用"以闭合value属性 ,用>闭合input标签,使其没有语法错误,然后插入任意我们想要达到目的js代码。右键查看其源代码:

  • 示例3

我们继续换Case05-Tag2Frameset.jsp为例练习: http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case05-Tag2Frameset.jsp?userinput=textvalue

查看其源代码可以看到,我们在页面输入的值被用于frame标签 的src属性值
这里我们可以直接往frame标签src属性里传js代码 http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case05-Tag2Frameset.jsp?userinput=javascript:alert('xss');
查看其源代码
也可以闭合当前frame">,再插入一个含有js代码的新frame,注意:利用的是上一个src属性的闭合标签">,此处不用再输入闭合标签。 http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case05-Tag2Frameset.jsp?userinput="><frame name=frame3 id=frame3 src="javascript:alert('xss');
查看其源代码

  • 示例4

http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case06-Event2TagScope.jsp?userinput=textvalue

闭合img标签 src属性,使用事件如:onMouseOver、onerror等触发js代码。 http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case06-Event2TagScope.jsp?userinput=a" onMouseOver="document.title=document.domain; 这里使用的是img onMouseOver触发js代码,将光标移动到图片上,浏览器标题变更为我们服务器IP地址。
查看其源代码
这里使用的是img onerror触发js代码,浏览器标题变更为我们服务器IP地址。 http://192.168.60.50:8080/wavsep/active/Reflected-XSS/RXSS-Detection-Evaluation-GET/Case06-Event2TagScope.jsp?userinput=a" onerror="document.title=document.domain;" style="display:none 我们把错误图标隐藏起来,加上style="display:none

  • 示例5

  • 总结

反射型XSS,在地址栏里的参数,比如page,被传递到服务器端,再输出到客户端。 那么我们在防范XSS时,我们可以在服务器端对传入的参数进行过滤,来防范这类攻击。将输入参数里可能造成跨站的特殊字符例如<, >,&等过滤掉。 1、自定入filter对HTML字符实体编码处理。 2、apache commons-text工具类StringEscapeUtils转义参数。 3、使用 Jsoup 对参数中的XSS进行过滤。

  • 2、存储型XSS

经过后端,经过数据库,攻击者在页面上插入XSS代码,服务端将数据存入数据库或文件中,当用户访问到存在XSS漏洞的页面时,服务端从数据库或文件中取出数据展示到页面上,导致XSS代码执行,达到攻击效果。

  • 3、DOM型XSS

不经过后端,攻击者在URL中插入XSS代码,前端页面直接从URL中获取XSS代码并且输出到页面,导致XSS代码的执行,攻击者将带有XSS代码的URL发送给用户,用户打开后受到XSS攻击。 我们可以使用javascript通过这个DOM接口对网页里的各个元素实现动态的操作。如:改变元素的宽度,高度,或改变网页元素的内容。但是在这些操作背后,也同样存在安全问题,可能导致XSS的发生。

  • 示例1

http://192.168.60.50:8080/wavsep/active/DOM-XSS/DXSS-Detection-Evaluation-GET-Experimental/Case03-InjectionInToVariableBeingAssignedToDomXssSinkEval.jsp?userinput=textvalue 页面无输出

查看其源代码:原来是接收用户输入,并直接交由eval()函数计算,我们知道如果参数是一个表达式,eval() 函数将执行表达式。如果参数是js语句,eval()将执行 js 语句。
我们直接传入最简单的js代码: http://192.168.60.50:8080/wavsep/active/DOM-XSS/DXSS-Detection-Evaluation-GET-Experimental/Case03-InjectionInToVariableBeingAssignedToDomXssSinkEval.jsp?userinput=javascript:alert(123)

  • 示例2

http://192.168.60.50:8080/wavsep/active/DOM-XSS/DXSS-Detection-Evaluation-GET-Experimental/Case03-InjectionInToVariableBeingAssignedToDomXssSinkEval.jsp?userinput=javascript:document.title=document.domain

可能触发DOM型XSS的属性

document.referer属性 window.name属性 location属性 innerHTML属性 documen.write属性