XSS,全称Cross Site Scripting,即跨站脚本攻击,是最普遍的Web应用安全漏洞。这类漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。需要强调的是,XSS不仅仅限于JavaScript,还包括flash等其它脚本语言。根据攻击代码的工作方式,XSS可以分为反射型的XSS、存储型的XSS和DOM型的XSS。
反射型的XSS是非持久化的,攻击者事先制作好攻击链接,需要欺骗用户自己去点击链接才能触发XSS代码,但是服务器中没有这样的页面和内容,一般容易出现在搜索页面。
存储型的XSS是持久化的,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,每当有用户访问该页面的时候都会触发代码执行。这种XSS非常危险,容易造成蠕虫,大量盗窃cookie。
DOM型的XSS是基于文档对象模型Document Objeet Model,DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口,它允许程序或脚本动态地访问和更新文档内容、结构和样式,处理后的结果能够成为显示页面的一部分。DOM中有很多对象,其中一些是用户可以操纵的,如uRI ,location,refelTer等。客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM XSS漏洞。例如服务器端经常使用document.boby.innerHtml等函数动态生成html页面,如果这些函数在引用某些变量时没有进行过滤或检查,就会产生DOM型的XSS。DOM型XSS可能是存储型,也有可能是反射型。
下面我列举的标签大部分是可以自动触发js代码的,无需用户去交互,大部分情况下我们也是希望是自动触发而不是等用户去触发。
标签定义 HTML 页面中的图像。
标签规定了用户可以在其中输入数据的输入字段。
onfocus 事件在对象获得焦点时发生:
竞争焦点,从而触发onblur事件:
input 标签的 autofocus 属性规定当页面加载时 元素应该自动获得焦点。可以通过autofocus属性自动执行本身的focus事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
使用details 标签的 open 属性触发ontoggle事件,无需用户去点击即可触发:
通过autofocus属性规定当页面加载时元素应该自动获得焦点,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
onscroll 事件在元素滚动条在滚动时触发。我们可以利用换行符以及autofocus,当用户滑动滚动条的时候自动触发,无需用户去点击触发:
//仅限火狐
//Chrome不行,火狐和IE都可以
//仅限于IE +WX:machinegunjoe666免费领取资料
标签定义文档与外部资源的关系。在无CSP的情况下才可以使用:
javascript: 这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行。当浏览器装载了这样的URL时,并不会转向某个URL,而是执行这个URL中包含的javascript代码,并把最后一条javascript语句的字符串值作为新文档的内容显示出来。
xss
//IE7以下
当空格被过滤了时,我们可以用 / 来代替空格:
也可以:
如果是html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号:
当括号被过滤的时候可以使用throw来绕过。throw 语句用于当错误发生时抛出一个错误。
显示结果
描述
实体名称
实体编号
空格
<
小于号
<
<
>
大于号
>
>
&
和号
&
&
"
引号
"
"
'
撇号
'(IE不支持)
'
但并不是所有的字符都有实体名称,但是它们都有自己的实体编号。
一个HTML解析器作为一个状态机,它从输入流中获取字符并按照转换规则转换到另一种状态。在解析过程中,任何时候它只要遇到一个 < 符号(后面没有跟 /符号)就会进入 标签开始状态(Tag open state) ,然后转变到 标签名状态(Tag name state) 、 前属性名状态(before attribute name state) ......最后进入 数据状态(Data state) 并释放当前标签的token。当解析器处于 数据状态(Data state) 时,它会继续解析,每当发现一个完整的标签,就会释放出一个token。
简单的说就是,浏览器对HTML解码之后就开始解析HTML文档,将众多标签转化为内容树中的DOM节点,此时识别标签的时候,HTML解析器是无法识别那些被实体编码的内容的,只有建立起DOM树,才能对每个节点的内容进行识别,如果出现实体编码,则会进行实体解码,只要是DOM节点里属性的值,都可以被HTML编码和解析。
所以在PHP中,使用htmlspecialchars()函数把预定义的字符转换为HTML实体,只有等到DOM树建立起来后,才会解析HTML实体,起到了XSS防护作用。
URL 解码URL编码是为了允许URL中存在汉字这样的非标准字符,本质是把一个字符转为%加上UTF-8编码对应的16进制数字。所以又称之为Percent-encoding。
在服务端接收到请求时,会自动对请求进行一次URL解码。
JavaScript 解码(只支持Unicode)当HTML解析产生DOM节点后,会根据DOM节点来做接下来的解析工作,比如在处理诸如
但是如果直接放进去标签的内容呢,不带转义字符呢,如下:
同样也是不会触发XSS的:
这涉及到了RCDATA的一个特殊的情况。即在浏览器解析RCDATA元素的过程中,解析器会进入“RCDATA状态”。在这个状态中,如果遇到“<”字符,它会转换到“RCDATA小于号状态”。如果“<”字符后没有紧跟着“/”和对应的标签名,解析器会转换回“RCDATA状态”,并不会进入“标签开始状态”的。这意味着在RCDATA元素标签的内容中,唯一能够被解析器认做是标签的就只有 或者 ,因此,在
另外还有一点要注意:我们从上面HTML的五类元素中还发现有一个原始文本元素
那么如何才能让里面的内容进行转义并执行弹窗呢,这里需要利用到XSS的一个黑魔法——“svg”,我们下文中会提及。
我们可以并将src或href属性中的内容进行URL编码,当HTML解析器对src或href中的字符完成HTML解码后,接下来URL解析器会对src或href中的值进行URL解码。
xx
下面给出几个实例。
testtest
注意,伪协议头 javascript: 是不能进行编码的。这里就有一个URL解析过程中的一个细节了,即不能对协议类型进行任何的编码操作,否则URL解析器会认为它无类型,就会导致DOM节点中被编码的“javascript”没有被解码,当然不会被URL解析器识别了。就比如说 http://www.baidu.com 可以被URL编码为 http://%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d,但是不能把协议也进URL编码:%68%74%74%70%3a%2f%2f%77%77%77%2e%62%61%69%64%75%2e%63%6f%6d 。
但是伪协议头 javascript: 可以进行HTML编码。
我们可以将DOM节点中的内容转化为 Javascript 编码。当HTML解析产生DOM节点后,会根据DOM节点来做接下来的解析工作,比如在处理诸如
testtest
test
但要注意,我们同样也不能对伪协议头 javascript: 进行 Javascript 编码。并且像圆括号、双引号、单引号这样的符号我们也不能进 Javascript 编码,但是能进行HTML编码。
对于八进制编码和十六进制编码,与 Unicode 编码还是有区别,像下面的XSS向量是不能直接执行的:
testtest
如下图,插入之后没有任何反应:
要想让他们能够执行我们要将他们放在DOM环境中,即DOM型的XSS。
测试代码:
test
以上情况很多都是出现在你搜索后,显示你所查询的关键字,变量 search 是一个可控点,当我们查询一个XSS攻击向量后,变量 search 就会被赋值为这个XSS向量,从而插入到div标签中触发XSS,如下所示:
test
+WX:machinegunjoe666免费领取资料
此时如果过滤了 <、>、'、"、&、% 等等这些字符的话,我们便可以用JavaScript编码的方法将XSS向量全部编码,即 的以下编码都可以弹窗:
// Unicode编码
\u003C\u0069\u0066\u0072\u0061\u006D\u0065\u0020\u0073\u0072\u0063\u003D\u006A\u0061\u0076\u0061\u0073\u0063\u0072\u0069\u0070\u0074\u003A\u0061\u006C\u0065\u0072\u0074\u0028\u0027\u0078\u0073\u0073\u0027\u0029\u003E\u003C\u002F\u0069\u0066\u0072\u0061\u006D\u0065\u003E
// 八进制编码
\74\151\146\162\141\155\145\40\163\162\143\75\152\141\166\141\163\143\162\151\160\164\72\141\154\145\162\164\50\47\170\163\163\47\51\76\74\57\151\146\162\141\155\145\76
// 十六进制编码
\x3c\x69\x66\x72\x61\x6d\x65\x20\x73\x72\x63\x3d\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29\x3e\x3c\x2f\x69\x66\x72\x61\x6d\x65\x3e
还有一种让八进制和十六进制编码的XSS攻击向量执行的方式便是将XSS向量放在某个能把字符串当做JavaScript代码来执行的函数里,比如eval()、setTimeout()、setInterval()等函数。如下示例:
testtest
或者也可以直接将一整段js代码编码后放入eval()函数中执行。
混合编码就是对一个XSS向量同时进行多种编码,如下示例:
test// 对javascript:进行HTML编码, 对alert("xss")进行URL编码
test
// 对javascript:进行HTML编码, 对alert进行Unicode编码
test
也可以利用解码顺序进行混合编码,如下示例:
test首先对“alert”进行JavaScript Unicode编码:
test
然后再对 \u0061\u006c\u0065\u0072\u0074 进行URL编码:
test
最后对标签中的 javascript:%5c%75...%37%34("xss") 整体进行HTML编码即可:
test
我们在上文HTML编码那里最后留了一个坑,即HTML的五类元素中,像
那如何绕过HTML原始文本元素进而执行HTML实体解码呢,这涉及到了
但是当在前面加上
这是为什么呢?
是因为
[CISCN2019 华东北赛区]Web2 这道题运用的就是这个知识点。
下面让我们来看一下XSS绕过的测试流程。
现实中,大多数的场所是用的黑名单来做XSS过滤器的,有三种方式绕过黑名单的测试:
暴力测试(输入大量的payload,看返回结果)根据正则推算利用浏览器bug(1)尝试插入比较正常的HTML标签,例如:、、、 等,来看一下返回页面的情况是怎样的,是否被HTML编码了,或者标签被过滤了。
版权声明:我们致力于保护作者版权,注重分享,被刊用文章【u0073故障码维修案例(这一次)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;
工作时间:8:00-18:00
客服电话
电子邮件
beimuxi@protonmail.com
扫码二维码
获取最新动态
