X-Requested-With導致CSRF失敗


  在漫漫滲透之路中,眼前一亮的發現一個站。Referer字段沒有檢查,POST參數中的動態token也沒有檢查,這不是帶一波CSRF的節奏嘛。但是遇到一個之前我沒遇到的問題導致我CSRF失敗,這個問題或許很簡單,但是我是一個小白,大牛看到就不要噴我了。

  首先我在Burpsuite當中生成了CSRF的POC,發現不行。經過與原始請求對比發現HEADER中少了一個字段,而這個字段就是CSRF成敗與否的關鍵。下面開始不啰嗦上真正知識點。

  在原來站中這個請求是一個POST的Ajax異步請求。於是在HTTP報文的head頭里面就有了這個字段:X-Requested-With: XMLHttpRequest。 服務器明顯檢查了這個字段,帶有的這個字段就會成功,否則就會302重定向到登錄頁面。於是我構造了一個利用xmlhttprequest 夠早了一個POC。

#注釋內容(python是最好的語言,至少在我心中如此):

"""

xmlhttprequest帶cookie的方案:

var xhr = new XMLHttpRequest();    
xhr.open("POST", "http://xxxx.com/demo/b/index.php", true);    
xhr.withCredentials = true; //支持跨域發送cookies 

xmlhttprequest設置head頭字段:

xhr.setRequestHeader("POWERED-BY-MENGXIANHUI", "Approve");  
xhr.setRequestHeader("Content-Type", "application/xml");  

""" 

於是我想這樣可以了吧,然后就發起了新的Ajax請求准備CSRF,但是在Burp中看到,沒有字段。

原因:X-Requested-With: XMLHttpRequest在跨域請求中會被去掉(如果跨域配置允許時候可以帶着,看配置)。

然后我手動強制加上了這個字段:

xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");  

這個時候我發現,原來的報文變成了OPTION包,而不是POST請求報文。

原來這是跨域訪問的一種安全檢查機制:

首先發起OPTION對目標服務器進行測試,看看這種訪問是否安全

在頭部字段會出現下面三個

Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with
Origin: null(跨域Ajax去掉X-Requested-With,帶上這個)

當收到服務器端的響應允許后才發送正式POST或者GET請求。

這叫做預檢報文,如何不觸發預檢報文,有三個同時滿足的必備條件(三項均成立才行):

1. 只能是Get、Head、Post方法
2. 除了瀏覽器自己在Http頭上加的信息(如Connection、User-Agent),開發者只能加這幾個:Accept、Accept-Language、Content-Type……
3. Content-Type只能取這幾個值:
  application/x-www-form-urlencoded
  multipart/form-data
  text/plain

 

或許有相關的解決辦法,我后面研究研究繼續搞。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM