xss反射型和存储型
1、反射型
在一个请求中,攻击者可以控制用户提交的数据,服务端未经过严格过滤检查,将数据写入响应的html文档中,使得数据中的payload被用户的浏览器解析为脚本执行。
(1)响应
- 响应头部字段content-type,包含text/html,将响应体部作为html文档解析
- 需要是非ajax交互,如果是ajax则浏览器不会默认解析,而是由脚本处理
- 响应可能是.jsp,.php,.aspx,也可能是接口类型或者伪静态.html等
(2)请求
- 需要是非ajax形式发出,具体来说就是点击链接发出,或者表单请求,又都可以是get或post请求方法,具体的形式由服务端请求地址接收参数的编程方法决定。
- 触发场景可以是基于社工手段,使用户直接点击链接访问。或者访问受攻击者控制的网站,受脚本被动的由url跳转,或者提交表单。
(3)解析为脚本
- 用户的数据在响应体部中,是动态嵌入的形式,对于用户浏览器接收而言,并不区分哪些是静态数据,哪些是动态数据。如果嵌入的数据包含敏感字符,破坏html文档结构,就可以解析出脚本被执行。
- 攻击者构造payload时,需要考虑脚本执行场景。参考:浏览器执行js脚本 - 挖洞404 - 博客园 (cnblogs.com)
- 用户输入数据写入响应html中,有几种输出点类型:
- html一般元素的内容部分
- html特殊元素的内容部分
- html注释之中
- html的一般属性中
- html的特殊属性中
- script的内容部分
- 构造payload的思想是:
- 尽量构造外部脚本,以实现几乎所有的脚本代码,而无需后续再验证过滤和防火墙
- 尽量构造ajax实现用户浏览器与攻击者的持久连接,可以长期控制
- 具体构造,判断当前点是否可以直接利用,如果不行,则关闭当前结构,再进行判断。关闭属性值,关闭开始标签,关闭当前标签,关闭html注释等
(4)补充
- title标签之间不能嵌套其他任何标签,不执行
- head标签是可以嵌套body、img等体部标签的
- textarea标签内部不能嵌套任何标签,会将其作为普通文本
- script标签之间是不能嵌套任何标签的
- style标签之间是不能嵌套任何标签的,不解析
- noscript标签也不能嵌套其他标签
1.1 防护
(1)编码
- 输出到各处时,结合输出点类型进行编码
- 一般场景是进行html实体编码,包括元素属性值、元素事件中的字面量、元素包含的文本
- 对于script内的脚本的字面量,进行js转义编码,即添加\前缀
- 某些方案中,对元素的地址属性值中的敏感字符,会使用url编码,即%编码。比如a的href、form的action、script的src、link的href等
- 是OWASP提供的一套java编码的api,可以选择编码方式对不同html输出参数进行不同编码。防止xss
(2)cookie添加httponly标志,以避免脚本读取
(3)一些响应字段的设置
XSS(跨域脚本攻击)应对之道 | XSS (lmlphp.com)
1.2 测试步骤
从业务场景来说,反射型xss是前端提交参数,服务端直接返回。
典型的是查询业务的查询条件回显,其次,一些404\500\自定义异常页面,也可能包含参数。
(1)初始判断
- 状态码并不严格要求是200,404和500等也有可能
- 需要存在参数,一般是url的直接参数和请求体部参数,路径参数也有可能
- 响应类型必须是html,即响应content-type必须包含text/html关键字
- 响应体部长度必须大于0,不能为空
(2)逐参数测试,响应体部是否包含参数
- 一般是设置为abx、zaz这种短小、不包含敏感字符、且在响应中不固定包含的关键词
- 另一种情况,是设置为包含敏感字符或特殊的,以使响应为异常状态而包含关键词作为提示,比如500、404、防火墙或搜索未发现、参数异常提示
(3)如果包含返回,则分析输出点类型。
(4)测试常用敏感字符的过滤情况
'"<>\/
一般,网站过滤和防火墙针对的也是这些字符。而这里测试,可以排除payload包含被过滤的敏感字符,从而减少无意义的测试请求
(5)结合输出点类型、敏感字符过滤情况、脚本执行场景,构造payload进行测试
注意,https站点下无法引入http的js文件。
(6)进一步利用,比如读取cookie转发
2、存储型
xss反射型和存储型具有很大的类似性,都是payload作为数据被服务端直接写入响应的html文档中。
存储型的漏洞防护,与反射型完全相同。
具体来说,可以分为几处不同:
(1)从业务上来说,反射型多见于直接查询,而存储型是先攻击者存储到服务端数据库,再被其他用户请求
(2)从测试上来说,反射型是在一个请求中进行,分析请求中的参数与对应响应的包含返回。存储型是在两个请求中进行,分析第一个请求中的参数,与第二个请求包含该参数资源的响应。
(3)从危害上来说,存储型和反射型能够实现的功能并没有区别,但是存储型更容易被其他用户触发。