IE漏洞的除錯心得
在除錯漏洞的過程中,個人感覺最棘手的就是ie瀏覽器的漏洞和flash player的漏洞了。這裡打算記錄一下學習過程中的心得(主要是基於uaf類),以方便新人學習。
首先,ie漏洞與眾不同的是,程式的執行流程是由攻擊者控制的。poc中的js指令碼反應到mshtml中的c++程式碼決定了程式的執行流程,所以對於ie漏洞來說仔細研究poc非常的關鍵。此外就是除錯ie漏洞需要對ie本身有很強的瞭解,這也是我寫這篇博文的動機,如果完全不清楚ie背後的機制,那麼ie漏洞根本沒法去調。
除錯IE漏洞的關鍵點:執行流程
CMarkup代表整個HTML樹結構
CMarkup::CreateElement——>
mshtml!CreateElement——>
CXXXElement::CreateElement
tips:1.解構函式在windbg裡直接用符號是斷不下來的,需要找到函式地址,最好是在call free上下斷。
元素物件統一繼承自CElement。
0x00偏移:虛表(dword),對此處求ln會得到符號
0x08偏移:是引用計數?
0x14偏移:對應的CTreeNode物件的指標
0x24偏移:Tag (byte),0x58script 0x10body 0x2fhead
建立函式:CXXXElement::CreateElement(通用斷點:監視型別mshtml!CreateElement [call eax]、監視記憶體CElement::CElement [堆分配傳來的eax])
釋放引用函式:CXXXElement::Release(通用斷點:CBase::PrivateRelease 棧上arg_1 eax是虛表)
釋放函式:CBase::SubRelease(CElement::~CElement)(通用斷點CBase::SubRelease的jmp路徑 ecx為要釋放的物件指標)
DOM物件均為CTreeNode類的例項。
0x00偏移:對應的元素物件的指標(dword)
0x04偏移:指向父節點的CTreeNode(dword)
0x16偏移:指向此node的起始CTreePos
0x20偏移:指向此node的結束CTreePos
0x40偏移:引用計數?
建立函式:CTreeNode::CTreeNode(建構函式)(eax:緩衝區地址 edi:所屬物件型別)
釋放引用函式:CTreeNode::Release的if分支(通用斷點:CTreeNode::Release的if分支 [待釋放的edx],在比較處eax引用計數)
釋放函式:CTreeNode::Release的另一if分支(通用斷點:CTreeNode::Release的另一if分支 [待釋放的edx],在比較處eax引用計數)
CTreePos物件是一一對應於CTreeNode物件的,主要是用於構成dom樹的結構
0x00偏移:key
0x10偏移:上一個CTreePos物件(dword)
0x14偏移:下一個CTreePos物件(dword)
0x18偏移:引用計數,為0就會被釋放(dword)
0x20偏移:對應的CTreeNode(dword)
釋放函式:CMarkup::FreeTreePos
通用斷點原則
IE中兩類重要的物件:元素物件和DOM物件
IE中每一個元素標籤都對應一個c++物件,這些類的總基類是CElement
每個元素物件都在DOM樹中,但是聯入資料結構的是CTreePos物件
IE瀏覽器使用引用計數來跟蹤物件的生命期,引用計數數=指向物件的指標,就是說每當增加一個指標指向它引用計數就加1。
解除引用元素物件的函式都為如下,這個方法的呼叫執行關係如下(基於IUnknown)
-
- CXXXElement::Release ——>
- CElement::Release——>
- CElement::PrivateRelease——>
- CBase::PrivateRelease
如果可以監視所有的IE元素建立、DOM元素建立、IE元素釋放、DOM元素釋放,那麼漏洞出在哪裡將一目瞭然
對於一個元素標籤,比如Object標籤。那麼對應的就是CObjectElement::CreateElement,這個函式的呼叫關係如下
元素物件建立的完整路徑
- CDocument::createElement——>
- CDocument::CreateElementHelper——>
- CMarkup::CreateElement——>
- mshtml!CreateElement——>
- CXXXElement::CreateElement——>
- HeapAlloc+CElement::CElement
CTreeNode::SetElement(CXXXElement*);將DOM物件與元素物件關聯起來
CTreeNode表示一個節點,CTreePos表示一個節點的標記。dom樹就是由CTreePos表示的二叉樹。
如果一個物件的指標計數為0,那麼就會被垃圾清理釋放掉
CTreeNode類的成員,來自IE5洩露原始碼
// Class Data CElement* _pElement; // The element for this node CTreeNode* _pNodeParent; // The parent in the CTreeNode tree // DWORD 1 BYTE _etag; // 0-7: element tag BYTE _fFirstCommonAncestorNode : 1; // 8: for finding common ancestor BYTE _fInMarkup : 1; // 9: this node is in a markup and shouldn't die BYTE _fInMarkupDestruction : 1; // 10: Used by CMarkup::DestroySplayTree BYTE _fHasLookasidePtr : 2; // 11-12 Lookaside flags BYTE _fBlockNess : 1; // 13: Cached from format -- valid if _iFF != -1 BYTE _fHasLayout : 1; // 14: Cached from format -- valid if _iFF != -1 BYTE _fUnused : 1; // 15: Unused SHORT _iPF; // 16-31: Paragraph Format // DWORD 2 SHORT _iCF; // 0-15: Char Format SHORT _iFF; // 16-31: Fancy Format
CTreeNode::CTreeNode(CTreeNode *pParent,CElement *pElement)這個建構函式的第一個引數是父CTreeNode節點,第二個引數是所屬的Element物件。其中第二個引數往往為0。
如何跟蹤CTreeNode::CTreeNode物件的建立?
斷下CTreeNode::CTreeNode函式後,eax就是分配的記憶體地址。
第一個引數為父節點CTreeNode物件的地址,第二個引數恆為0
可以在call ~的下一條,mov esi,eax下斷,這時CTreeNode已完成初始化,讀eax就可知道是屬於哪個元素
DOM樹是由CTreePos組成的一個splay tree。
如圖所示就是一個CxxxElement::CreateElement,上面已經說過了這是由mshtml!CreateElement呼叫的。我們可以看到呼叫了HeapAlloc函式後,eax的值沒有改變直接傳遞到了CElement的建構函式——CElement::CElement中。實現了分配空間+初始化記憶體的操作。
對mshtml!CElement::CElement+0x48下斷可以通用的監測物件建立的內容。
這張圖是mshtml!CreateElement函式的關鍵部分,注意符號給出的CTagDesc *型別的常量,這是一個指標陣列經過movzx eax,byte ptr [edi+1];shl eax,4;計算偏移得出CxxxElement::CreateElement的地址,然後呼叫過去。指標陣列如下:
CTreeNode::Release可以獲取到所有的CTreeNode的釋放過程,edx是上面直接傳遞過來的CTreeNode物件的地址。對這個值監視即可獲得所有CTreeNode物件的釋放
<html> <head> <title>DOM 教程</title> </head> <body> <h1>DOM 第一課</h1> <p>Hello world!</p> </body> </html>
mshtml!CHtmlElement::CreateElement mshtml!CHeadElement::CreateElement mshtml!CBodyElement::CreateElement mshtml!CHeaderElement::CreateElement mshtml!CParaElement::CreateElement
下斷元素建立
1:020> bl 0 e 6a23480f 0001 (0001) 1:**** mshtml!CElement::CElement ".echo 物件地址;r eax;gc" 4 e 6a234be7 0001 (0001) 1:**** mshtml!CreateElement+0x41 "ln eax;gc" 1:020> g (6a23d088) mshtml!CHtmlElement::CreateElement | (6a23d0d8) mshtml!CHtmlElement::`vftable' Exact matches: mshtml!CHtmlElement::CreateElement = <no type information> 物件地址 eax=06131fd8 (6a23d359) mshtml!CHeadElement::CreateElement | (6a23d3a8) mshtml!CHeadElement::`vftable' Exact matches: mshtml!CHeadElement::CreateElement = <no type information> 物件地址 eax=06154fd8 物件地址 eax=05f6afd0 (6a2465fa) mshtml!CBodyElement::CreateElement | (6a246648) mshtml!CBodyElement::CBodyElement Exact matches: mshtml!CBodyElement::CreateElement = <no type information> 物件地址 eax=0302dfd0 (6a254c88) mshtml!CHeaderElement::CreateElement | (6a254ce0) mshtml!CHeaderElement::`vftable' Exact matches: mshtml!CHeaderElement::CreateElement = <no type information> 物件地址 eax=0628efd0 (6a257e72) mshtml!CParaElement::CreateElement | (6a257ec0) mshtml!CParaElement::`vftable' Exact matches: mshtml!CParaElement::CreateElement = <no type information> 物件地址 eax=05d83fd8
IE漏洞除錯的目的:
從crash到漏洞產生原因
找到發生UAF的物件
找出物件的分配、釋放、重利用的時機
對應到poc的js語句中
推斷出UAF的本質成因
補丁對比!!!找出本質成因最好的辦法
相關文章
- js斷點除錯心得2016-04-21JS斷點除錯
- Web除錯工具Charles使用心得2017-12-21Web除錯
- 漏洞分析中常用的堆除錯支援2016-06-21除錯
- IE, FF, Safari前端開發常用除錯工具2009-03-12前端除錯
- 推薦:IE6 前端除錯神器 SPOON!2013-04-09前端除錯
- Win32除錯API學習心得(一) (轉)2007-11-27Win32除錯API
- win32除錯API學習心得(三) (轉)2007-08-16Win32除錯API
- Win32除錯API學習心得(二) (轉)2007-08-16Win32除錯API
- IE console.log 除錯狀態2018-12-25除錯
- Windbg在應用層除錯漏洞時的應用2016-07-25除錯
- IE 頁面不正常顯示 錯誤指令碼不報錯 指令碼除錯相關2014-01-04指令碼除錯
- 防止低版本IE瀏覽器遇到console除錯報錯程式碼2017-03-22瀏覽器除錯
- 除錯篇——除錯物件與除錯事件2022-03-02除錯物件事件
- JAVA反序列化漏洞完整過程分析與除錯2020-08-19Java除錯
- RPC使用 IE出錯2005-12-05RPC
- CTF中做Linux下漏洞利用的一些心得2016-06-04Linux
- Android Studio: 除錯的技巧與心得 | AndroidDevSummit 中文字幕視訊2019-12-09Android除錯devMIT
- Windows windbg kernel debug 雙機核心除錯 - USB3.0 除錯 USB除錯 除錯線2021-01-02Windows除錯
- Flutter Tools的除錯2019-11-16Flutter除錯
- chrome的除錯技巧2018-12-25Chrome除錯
- ABAP巨集的除錯2018-03-17除錯
- 除錯 CSS 的方法2016-09-06除錯CSS
- DLL的除錯 (轉)2007-12-14除錯
- 【前端除錯】- 斷點除錯的正確開啟方式2023-01-04前端除錯斷點
- IsDebuggerPresent的反除錯與反反除錯2022-04-07除錯
- 22 真機除錯bug(除錯包)2017-04-17除錯
- gdb除錯命令小結_與多檔案除錯_遠端除錯2013-10-11除錯
- nginx 錯誤除錯2021-05-20Nginx除錯
- rac錯誤除錯2016-04-20除錯
- Python 程式碼除錯—使用 pdb 除錯2019-12-26Python除錯
- Mobile Web 除錯指南(2):遠端除錯2014-05-20Web除錯
- Flutter的命令列除錯2019-11-05Flutter命令列除錯
- Pycharm的斷點除錯2018-07-27PyCharm斷點除錯
- go除錯的問題。2017-05-11Go除錯
- dig的命令除錯2007-12-08除錯
- python迴圈刪除漏洞2018-08-09Python
- 前端除錯2019-03-04前端除錯
- gdb除錯2020-12-27除錯