1. Introduction
What I want to learn recently after completing the changes, the POC and utilization ideas of this vulnerability have been published in the meager section of the ancient river, however, before reading an article on the ancient river, I will analyze the cause of the vulnerability and record my own analysis process.
2. experiment environment
Operating System: win8.1 x86 RTM
Browser: Internet Explorer 11 32 bits (patch to kb2909921)
Vulnerability Number: CVE-2014-0321
Microsoft Patch: MS14-012
3. Vulnerability Analysis 3.1. Analyze crash3.1.1. run the POC and view the crash
Run the POC directly and check the status after the crash
The reason for the crash error is that test dword ptr [ECx + 24 h], 30000 h ds: 0023: 41414165 = ???????? Invalid memory space is referenced. View the context of the crash.
In crash, ECx comes from parameter 1 -- ECx when the function ctreenode: computeformatshelper is used (Review windows x86 call conventions ). So where exactly does parameter 1 come from. Further backtracking of the parent function:
At this time, the ECX has not changed, and the parent function is traced back again:
Through mov ECx and dword ptr [EBP + 8], we can know that the ECX at the crash position comes from cinsertspliceundo: setdata parameter 1 [EBP + 8]. Cinsertspliceundo: setdata call ctreenode: getcharformathelper, as shown in:
3.1.2. Release reusable Object Types
The parent function of cinsertspliceundo: setdata is csplicetreeengine: insertsplice. Through Ida, it is found that the first parameter is struct ctreenode *. Therefore, struct ctreenode * is reused after release, as shown in:
Therefore, set a breakpoint at cinsertspliceundo: setdata to check whether parameter 1 has been released when entering the function. If no breakpoint is released, further track the release location.
3.2. Track debugging and analyze the causes of vulnerabilities 3.2.1. Prepare for debugging
Enable the page heap function of gflags.exe.
3.2.2. Locate the release location of the object
Set a condition breakpoint and break the function when you enter cinsertspliceundo: setdata.
Bu mshtml! Cinsertspliceundo: setdata "r $ T0 = 0;. foreach (V {k}) {. If ($ spat (\" V \ ", \" * mshtml! Celement: replacenode * \ ") {r $ T0 = 1;. Break};. If ($ T0 = 0) {GC }"
When cinsertspliceundo: setdata is disconnected for the first time, observe parameter 1:
Setdata is broken for the first time. At this time, the object has not been released, so a breakpoint is set for the object release process.
Bu NTDLL! Rtlfreeheap ". If (POI (esp + 0xc) = 06a9efa0) {}. else {GC }"
No problems found through tracking ...... Another ctreenode object is found to be released and placeholder, and the second call to setdata, as shown in
Due to the role of page heap, after the object is released, it does not have a placeholder. Heap backtracing is performed on the object to view the released location.
The document. Write ("") in JS is visible by cfastdom: cdocument: trampoline_write, which causes the object to be released.
3.2.3. Observe the function Execution Process
Based on the above analysis, add a breakpoint next time
Bu mshtml! Cfastdom: chtmlelement: trampoline_replacenode
Bu mshtml! Cfastdom: cdocument: trampoline_write
Bu mshtml! Cinsertspliceundo: setdata "r $ T0 = 0;. foreach (V {k}) {. If ($ spat (\" V \ ", \" * mshtml! Celement: replacenode * \ ") {r $ T0 = 1;. Break};. If ($ T0 = 0) {GC }"
Check the call tracing when the service is disconnected. The call process is obvious. You can obtain the following information through the breakpoint status:
- IE internal through mshtml! Ceventmgr: dispatchevent listens for events and then uses mshtml! Ceventmgr: Dispatch distributes events and distributes them to corresponding event listeners for processing.
- IE internal through jscript9! JS: javascriptexternalfunction: externalfunctionthunk parse and process JS statements in HTML
- When executing the replacenode statement, ie triggers the onerror event internally and executes its callback function, document. Write (""); which causes a ctreenode object to be released.
3.2.4. Release and reuse of verification objects
Based on the above analysis, the next debugging sets the following breakpoint, verifies the execution process, and determines the released object
Bu mshtml! Cfastdom: chtmlelement: trampoline_replacenode
Bu mshtml! Cfastdom: cdocument: trampoline_write // you can trace the release process of an object.
Based on Stack backtracking, for mshtml! Csplicetreeengine: insertsplice + 0x11fa breakpoint, further Tracking Analysis Reuse
Let's take a look at parameter 1 (object) when you enter setdata twice.
The specific debugging process is as follows:
Bu mshtml! Cfastdom: chtmlelement: trampoline_replacenode
Bu mshtml! Cfastdom: cdocument: trampoline_write // you can trace the release process of an object.
Set snapshotsTo release the observed object. The following describes how to release an object based on the previous object release record of page heap.
Conditional breakpoint:
Bu NTDLL! Rtlfreeheap "r $ T0 = 0;. foreach (V {k}) {. If ($ spat (\" V \ ", \" * mshtml! Cmarkup: destroysplaytree * \ ") {r $ T0 = 1;. Break};. If ($ T0 = 0) {GC }"
The above breakpoint settings are not very good, it takes a lot of time, it is better to track step by step
Bu mshtml! Cmarkup: destroysplaytree + 0x811
Through the tracking and snapshot recovery functions, we found that the destroysplaytree was broken four times, of which 3rd were released and reused objects.
Status before the object is released:
It can be seen that the creation process and size of the ctreenode Node object (0x60)
Status of the released object:
Set the following breakpoint to track the status after the onerror callback function is executed.
Bu mshtml! Csplicetreeengine: insertsplice + 0x11fa
After tracking to the following locations, you can find that the reused object is passed to cinsertspliceundo: setdata as a parameter.
3.2.5. Memory placeholder
The ctreenode object is document. Write (""); after it is released, the memory is occupied immediately,
The actual size is 0x60. Because the create user mode stack trace database function cannot be used for heap backtracking, The placeholder process cannot be tracked when page heap is enabled. However, with POC, we can see that the object has been stably occupied.
3.2.6. Summary
The effect of this vulnerability is to make a stable placeholder for the ctreenode node objects reused after release. However, because the released object has low controllability and is difficult to access in Javascript, it is quite difficult to use it.
4. Vulnerability Exploitation
This vulnerability is very difficult to exploit. Recently, we are preparing to take the time to try to write exp based on the ideas provided by the ancient river. Please refer to the link to learn how to exploit this vulnerability.
5. References
[1] CVE-2014-0321-exploiting ie11 on Windows 8.1 32 bits:
Http://weibo.com/p/1001603732980651659108
Cause Analysis of CVE-2014-0321 Vulnerability