Friday 30 September 2016

Exploit CSRF via Non Standard HTTP Methods



CSRF in Non-Standard Methods

If you are into web application security or provide pen testing services, you would be aware of what CSRF is. As the name suggests, it is a vulnerability in applications where an application is not able to differentiate between a request from a legitimate user and a forged request from the attacker. Hence, the attacker can trick the victim (application user) while they are still logged into the application (i.e. during an active session), into submitting attacker specified request unknowingly to the application. The result is that the attacker can carry out unwanted transactions or events with the privilege of the victim.

Then are many ways of carrying out a cross site request forgery attack depending on the method used to send the request to the server.  The most common ones are generally those that use the GET and the POST HTTP methods respectively. Details around these are widely available. I will leave you to check this out using link below:


https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)


However, a site using other HTTP methods and can be affected by the CSRF as well. I carried out this interesting form of CSRF using PUT method in a vulnerable application that extensively used all kinds of HTTP methods.
In this article we’re going to evaluate how to exploit a CSRF vulnerability when the such unusual methods are involved.

 A standard CSRF via POST request:

Pre-requisites: The attacker should be familiar with the request structure and correct values, if any, to carry out the attack. The victim should be logged in with an active session for the attack to process successfully.
Below is the form that the attacker would put together to carry out CSRF if POST method was involved:
<html>
<body onload='document.DEMO.submit()'>

<form action='https://victim-site.com/api/add/billers' method='POST' name=’DEMO’>
       <input type='hidden' name='name' value='csrftest'>
       <input type='hidden' name='biller_ip' value='192.168.4.5'>

</form>
<b>Biller Added Successfully</b>
</body>
</html>

We are familiar with such requests. The above request form adds a biller to the user account.  In a real scenario, the attacker would hide all form elements from the victim behind another distracting page carrying out some unrelated function. However, she needs to provide correct Biller Name (e.g her billing agency) and Biller’s exact IP address.
Impact: In case of a banking application for example, the attacker could add her own biller name, Id/biller number and set Auto-pay to True, to add her bills to the victim’s account and let him pay the bills.

Nonstandard attack scenario: Using PUT and DELETE methods

Many applications these days make API calls and use specific web services which use methods such as PUT and DELETE and thus there is less chance of finding form based POSTS or GETS in a traditional way. Hence, for such JSON rich applications, the method of attack needs to be slightly different.

CSRF using PUT Request

Pre-requisite: To carry out CSRF via PUT requests, the website should allow cross origin resource sharing. (Otherwise, recent browsers would block these requests due to same origin policy rules). A simple way of identify requests/URLs that are attackable is when you get the below response to a normal request:

Access-Control-Allow-Origin: *      //CORS

Since most of the action events for my target used PUT/DELETE methods, I went ahead and found those of them vulnerable to CORS. Once that was done, it was a matter of formulating the attack request:
Below is a simple example I used to carry out CSRF for the add biller function discussed above that was originally submitted using PUT in the application:

<html>
<script>
function put() {
       var x = new XMLHttpRequest();
       x.open("PUT","https://victim-site.com/api/add/billers",true);
       x.setRequestHeader("Content-Type", "application/json");
       x.send(JSON.stringify({"name":"csrftest","regex":"192.168.8.34”}));
}
</script>
<body onload="put()">
IP Added to Billers
</body>
</html>

Figure below shows the above form as loaded in the victim browser while he was still logged into the application:
 The application responds with the message that request was successfully processed and biller added.
 I verified the Billers list to confirm that the test biller had indeed been added.
 
A common mistake that happens when porting JSON requests that use PUT method to traditional form format is that JSON can involve extensive parameters nested in a complex way. However, errors such as below can guide your way to correcting the request sequence for the attack:
 
These must be represented in the correct order and grouping for the attack to happen. Also, for other similar methods such as DELETE, minor tweak in above request should work. I would like to know if you have carried out CSRF for DELETE requests in your experience. If yes, please leave them in the comments below.









No comments:

Post a Comment