📜 ⬆️ ⬇️

Browsers and app specific security mitigation. Part 2. Internet Explorer and Edge

Internet Explorer & Edge


The purpose of this article is to review the specific, explorer protection mechanisms integrated into Internet Explorer and Edge browsers.


We decided to combine the review of IE and Edge security mechanisms into one article, because, firstly, both are products of the notorious Microsoft company, and, secondly, this approach allows us to track how the approach to protection has changed and, accordingly, the development of protection of these browsers. Well, also for the reason that IE and Edge have a common code base.


ie_success_story



Figure 1 - Development of security mechanisms in IE browser ( source )


We present these mechanisms in the form of a list. For IE, the list looks like this:



For Edge:



Within this article we will consider the following mechanisms:


  1. Isolated Heap & Memory Protection;
  2. MemGC;
  3. Sandbox implementation in IE and Edge;
  4. JIT Hardening.

Isolated Heap & Memory Protection & MemGC


One of the most common classes of vulnerabilities in the browsers in question, and in other browsers too, are UAF (use-after-free).


Any exploitation of UAF-vulnerabilities can be described in the form of the following scheme:


uaf_scheme
Figure 2 - UAF vulnerability exploitation scheme


Those. exploitation of UAF-vulnerabilities is done in 2 steps:


  1. Free operation - a condition is triggered under which the object's memory is freed, while a pointer to this object remains - “dangling pointer” or dangling pointer. It will be used in the future to refer to an already non-existent object, for example, to call its method or write some value.


  2. Realloc operation - memory is reallocated and the necessary values ​​are written to it. In place of the freed old object, a new one is created with the prepared data, which will be mistakenly interpreted as components of the old object - after its release.

For example, if an object's method is called after it is released prematurely, which makes it possible to occupy the freed memory and overwrite the pointer to the virtual function table, thus changing the address of the method that will be called. As a result, it can be used to transfer control to a given address.


An erroneous reading of data from an object that has already been released leaves it possible to take from the memory already timely values ​​attached there, for example, a pointer to a function in the code section of the relocated ASLR module, i.e. implement address leakage and - hereinafter - ASLR bypass


Consider the mechanisms by which protection against such vulnerabilities in IE and Edge browsers is performed.


Isolated Heap


The Isolated Heap protection appeared in IE along with the June 2014 update (MS14-035). Its main goal is protection against UAF vulnerabilities. Now, when allocating memory for an object, it is allocated not from the process heap, but from the special “isolated heap” (as the name implies):


one
Figure 3 - Using an isolated heap when creating a CImgElement element


Virtually all HTML and SVG DOM objects (CXXXElement) use an isolated heap. They are highly likely to have UAF vulnerabilities, so it is extremely important to isolate these objects.


Thanks to the introduction of a separate heap, an attacker has problems with the second step of exploiting UAF vulnerabilities, namely, reallocating memory and writing its own controlled values ​​or code to it, because such “convenient” objects as strings are allocated in another “heap” "And cannot be used to replace values ​​in a vulnerable object.


As can be seen in the figure below, a pointer to an isolated heap is stored in a global variable, the initialization of this heap occurs in the DllProcessAttach () function:


eleven
Figure 4 - Initialization of an isolated heap


If you track the XREFs to _g_hIsolatedHeap, you can see 2 functions-allocators that use it:


  1. _MemIsolatedAlloc() ;
  2. _MemIsolatedAllocClear() .

The second option calls HeapAlloc with the HEAP_ZERO_MEMORY flag, which should prevent exploitation of vulnerabilities that use uninitialized memory.


Despite the fact that the use of an isolated heap helps to reduce the probability of successful operation of UAF vulnerabilities, not everything is as good as it seems.


First, there are still objects that use a “bunch” of the process - for example, CStr. Secondly, there is a theoretical workaround associated with the fact that the implementation of an isolated “heap” is exactly the same as the “heaps” of the process (there is no check of object types when allocating memory to it), and also with the fact that the selected objects are stored in separate place.


Those. to bypass the Isolated Heap, the attacker must fulfill the following conditions:


  1. Find an object that is allocated in an isolated heap;
  2. This object should be approximately the same size as the exempted UAF object;
  3. The attacker should easily control the contents of this object.

The guys from ZDI in 2015 presented a report on Black Hat and paper [1], which offered several Isolated Heap circumvention techniques. They have one common basis, which just satisfies the conditions described above.


The difference between the technicians is only in the details, namely in the preliminary work with the "heap".


Consider the basic technique.


Bypass technique based on using another type of object (Type Confusion Bypass Techique)


As mentioned earlier, an isolated “heap” is exactly the same as the usual “heap” of the process, that is, when allocating memory, it does not take into account the type of object created. Because of this, the attacker has the option to fill the object being freed with an object of another type. Overwriting a freed object with an object of another type will result in a type confusion condition.


Such an object, in relation to which it is possible to create a type confusion condition, may be larger or even smaller than the size of the object with which we are going to overwrite the memory. This is an important fact that allows an attacker to control certain offsets within a reused object. For example, if we know that a UAF vulnerability occurs when a pointer is dereferenced, at offset 0x30, then all we need is to replace the object being freed with one that contains the value at offset 0x30, which we can control.


Thus, the sequence of actions is as follows:


  1. Trigger the condition of freeing the memory of the “attacked” object;
  2. Replace the object with another object using heap spray;
  3. Trigger the re-use of the attacked object.

PoC of this technology can be viewed from the guys from ZDI on github .


Memory Protection


If the implementation of the Isolated Heap makes life difficult for an attacker in the operation of the UAF in the second step, the step of reallocating and rewriting memory, then the following mechanism makes it difficult to perform the first step, namely, freeing the memory of the object. This protection is called Memory Protection .


The essence of this mechanism is that it prevents the release of a chunk of memory as long as it is referenced in the stack or in the register (as long as there are “dangling pointers”). This mechanism first appeared in IE with the July security update in 2014 (MS14-037). Check registers added in August 2014.


IE uses a CMemoryProtector object to keep track of the parts of memory that need to be freed. It is created for each thread, and a pointer to it is stored in TLS (thread local storage).


Initialization of this object is performed in the MemoryProtection :: CMemoryProtector :: ProtectCurrentThread () function (it is worth noting that during initialization all fields of the object are set to 0).


12
Figure 5 - ProtectCurrentThread() function


The CMemoryProtector object has the following structure (Figure 6) [2]


CMemoryProtector
Figure 6 - Structure of the CMemoryProtector object


The CMemoryProtector object consists of the following fields:


  1. BlocksArray is a structure of the SBlockDescriptorArray type, which contains information about the released memory areas (wait-list);
  2. IsForceMarkAndReclaim - a flag used to determine whether to call the Reclamation Sweep operation (more on this below);
  3. StackHighAddress is the largest stack address in the stream. Used for the mark operation of the area when sampling pointer values ​​from the stack;
  4. StackMarkerAddress is the largest stack address when the MemoryProtection::CMemoryProtector::ProtectCurrentThread() function is MemoryProtection::CMemoryProtector::ProtectCurrentThread() . It is used to determine whether the stack has been completely completed, and, consequently, whether the Reclamation Sweep operation will be performed (more on this below).

The SBlockDescriptorArray structure contains the following fields:


  1. Blocks is a list of freed sections (wait-list). Each wail-list element is a descriptor ( SBlockDescriptor ) containing information about the memory block: its base address, size, whether it is contained in an isolated heap or in a normal one.
  2. TotalSize is the total size of all exempt plots that are in a wait-list. Used to determine whether to perform a Reclamation Sweep operation;
  3. Count - the number of vacated areas in the Blocks list;
  4. Max Count - the maximum number of items in the wait-list;
  5. IsSorted - the flag that determines whether the Blocks list is sorted.

Memory Protection when freeing memory uses the MemoryProtection::CMemoryProtector::ProtectedFree() HeapFree() instead of HeapFree() .


 void __userpurge MemoryProtection::CMemoryProtector::ProtectedFree(void *a1@<ecx>, void *Dst, unsigned __int32 a3, void *a4) { void *v4; MemoryProtection::CMemoryProtector *v5; unsigned int v6; MemoryProtection::CMemoryProtector *v7; size_t Size; v4 = a1; if ( Dst ) { if ( MemoryProtection::CMemoryProtector::tlsSlotForInstance != -1 && (v5 = (MemoryProtection::CMemoryProtector *)TlsGetValue(MemoryProtection::CMemoryProtector::tlsSlotForInstance), (v7 = v5) != 0) ) { MemoryProtection::CMemoryProtector::ReclaimMemory(v5, v6); //(1) Size = 0; if ( MemoryProtection::SBlockDescriptorArray::AddBlockDescriptor(v7, Dst, v4 != MemoryProtection::g_heapHandles, &Size) ) { MemoryProtection::SAddressFilter::AddBlock((MemoryProtection::CMemoryProtector *)((char *)v7 + 32), Dst, Size); //(2) memset(Dst, 0, Size); } else { RaiseFailFastException(0, 0, 0); } } else { HeapFree(v4, 0, Dst); } } } 

ProtectedFree() function


ProtectedFree() with a certain frequency and under certain conditions carries out the procedure Reclamation Sweep (1). It is important to note that it is performed before the block to be released enters the Wait-List.


The essence of the procedure Reclamation Sweep:


  1. Checking the total number of memory plots located in the Wait-List, their total volume;
  2. If the total number of sites is greater than CMemoryProtector.BlocksArray.TotalSize or the total volume> = 100,000 bytes or the IsForceMarkAndReclaim flag is set , perform the freeing procedure for the blocks in the Wait-List.
    2.1. If there is a pointer to the memory block in the stack or in the register, then skip it;
    2.2. If there is no pointer to the memory block, then release it.

A pointer to a block of memory is considered as a pointer to the beginning of the block, and to any place inside it.


Several functions are responsible for the Reclamation Sweep procedure, which are called inside the MemoryProtection::CMemoryProtector::ReclaimMemory() conditions for starting this procedure are checked there too):



This function first sorts the chunks in order of increasing addresses. Then, it checks to see if there are pointers to these areas in the thread stack or in registers. In the event that such a pointer exists, MarksBlocks() marks such a block.



This function performs a simple bypass of the wait-list and frees all unlabeled areas of memory. The counter in the CMemoryProtection object CMemoryProtection also updated in the process.


After the Reclamation Sweep procedure, the block to be released is added to the wait-list and filled with zeros.


protectedFree_algo
Figure 7 - Algorithm of the ProtectedFree() function (source [1] )


It is worth noting that previously there was an unconditional procedure for freeing all areas of memory MemoryProtection::CMemoryProtector::ReclaimMemoryWithoutProtection() - this happened every time the mshtml!GlobalWndProc() function was mshtml!GlobalWndProc() as a result of receiving a message from the main stream window. But later this opportunity was removed.


Memory Protection is an extremely effective technique against UAF vulnerabilities, when the pointer to freed memory remains on the stack or in the register, since Memory Protection ensures that this block will remain in the wait-list until it is used again (when allocating memory ) and will be in the wait-list filled with zeros.


Memory Protection also reduces the likelihood of exploiting other UAF vulnerabilities that are not in the category described above. In this case, when the "hanging pointer" is neither in the stack nor in the register, the attacker must solve the following tasks:


1) Memory release delay


As described above, the release of memory can take place with some delay, until the Reclamation Sweep procedure is performed.


2) Uncertainty due to “garbage” in the stack


The memory block may remain in the wait-list during the Reclamation Sweep procedure, as it may happen that the stack stores a value that is equal to the address somewhere inside the block being released. It is not necessary that this value is a pointer, but Memory Protection will treat it that way.


3) The greater difficulty in determining the time when the release of a section of memory occurs.


The Reclamation Sweep procedure will be implemented only if the amount of memory in the wait-list exceeds 100,000 bytes. This may not happen until a really large block of memory is in the wait-list.


4) More complex heap manager behavior when freeing memory


Summarizing all of the above, it should be borne in mind that the memory block to be released first falls into the wait-list and is there until the wait-list volume exceeds 100,000 bytes, and only then it is released while there are no pointers on the stack or in registers. At the same time, it is impossible to predict the state of the heap after simultaneously releasing a large number of different-size memory areas from the wait-list.


Despite these difficulties, the same guys from ZDI have come up with several techniques for bypassing the Memory Protection mechanism [1] - some of them are obvious and simple, and some are not.


Consider them further.


Elementary technology


The most obvious solution is to use the so-called “memory pressure” to run the Reclamation Sweep procedure, i.e. it is necessary to allocate and then immediately free up memory of 100,000 bytes.


 //        ... //     //     wait-list var n = 100000 / 0x34 + 1; for (var i = 0; i < n; i++) { document.createElement("div"); } CollectGarbage(); // ,      … // 

But this approach will not relieve from all problems - we will solve the problem of delaying the release of memory, but we will not get rid of all the others. Together with our object many other objects will be freed, and in an unpredictable way. This indefinite behavior leads to a decrease in reliability when attempting to establish control over the contents of released memory.


Also, a second obvious solution was possible earlier - this is the use of an unconditional procedure for freeing all memory areas, which is carried out when the GlobalWndProc() function is GlobalWndProc() .


We can interrupt the exploit execution with a delay that is so large that a new call to the GlobalWndProc() function has exactly occurred, then Memory Protection will release all the blocks in the wait-list.


 function step1() { //    … ... //    //     ,  WndProc  , //    wait-list window.setTimeout(step2, 3000); } function step2() { //      … ... //   … //     ,  WndProc  , //   wait-list,     window.setTimeout(step3, 3000); } function step3() { //      … } 

This solution allows you to minimize the number of foreign objects that will be released along with ours. But it has its drawbacks - using setTimeout() creates an opportunity for the appearance of an additional unpredictable branch of code that is executed in the current thread. As a result, you can get unpredictable and unwanted heap modifications.


"Advanced" technology


The researchers did not stop there, thought and decided that to bypass Memory Protection, it is necessary to stabilize the wait-list — you need to build a sequence of such script actions in order to monitor and know the status of the wait-list. By creating such a sequence, we will be able to exploit UAF vulnerabilities.


To begin with, suppose we can allocate buffer A with a size of 100,000 bytes. Then we try to free this buffer. As a result, Memory Protection will put our buffer A in the wait-list, and the size of the wait-list will be exactly> = 100,000 bytes.


13
Figure 8 - The status of the wait-list after adding buffer A to it (source [1] )


Next, we again allocate and free buffer B of the size s we already need. During the ProtectedFree() call, Memory Protection will see that the size of the wait-list is such that it’s time to start freeing (actually freeing) its elements. After this procedure, our buffer of size s will be in the wait-list.


14
Figure 9 - The state of the wait-list after adding buffer B to it (source [1] )


It is possible that not all the sections from the wait-list will be released and leave it - some of them may have pointers on the stack (let's call these Wi ). But, first, we can safely say that their total size is much less than 100,000 bytes. Secondly, it does not matter what their total number and total size is for the next steps. We know for sure that as long as there are pointers on the stack, these sections will be in the wait-list.


So, at this stage, we know the approximate state of the wait-list and are ready to perform the desired actions with a “heap” for exploiting vulnerabilities.


Suppose we want to free a block of memory at address C. It is possible that even with the aim of triggering the UAF at this address. In order for the memory block at this address to be exactly freed, and to do it in a predictable way:


  1. Call ProtectedFree() for block C. Block C gets into the wait-list and is there along with blocks Wi and block B of size s ;
  2. We allocate memory for a large memory block D with a size of 100,000 bytes and immediately release it. Now this memory block falls into the wait-list, and the size of the wait-list becomes> = 100,000 bytes;
  3. We allocate memory for a block of memory E of size s and release it. After calling ProtectedFree() for block E , our desired block C and blocks B and D will fall under the Reclamation Sweep procedure and will be released.

15
Figure 10 - The final status of the wait-list (source [1] )


Now we bring the practice to this theoretical strategy. You need to define an object that allocates buffers of arbitrary size and releases them through ProtectedFree() . The guys from ZDI chose the CStr object - it has a dynamic size and can be allocated from outside. But you can always try to choose another object, good on ProtectedFree 1100 xrefs.


Also, analyzing MSHTML, they found that CStr uses the CElement::var_getElementsByClassName . You can reach it via the getElementsByClassName DOM method on any HTML element (which is exactly what you need).


At runtime, this method creates a CStr containing string data, which is passed as the getElementsByClassName parameter, and then deletes this CStr .


getElementsByClassName
Figure 11 - Function code CElement::var_getElementsByClassName


Thus, one call to getElementsByClassName can achieve the goal of allocating and freeing an arbitrary size buffer.


One small limitation is that the minimum buffer size with string data that we can pass to getElementsByClassName is 0x28 bytes. Therefore, CStr takes 0x28 * 2 + 6 = 0x56 bytes (two bytes per character, plus 6 additional bytes).


 var oDiv1 = document.createElement('div'); // /   ProtectedFree   string1 oDiv1.getElementsByClassName(string1); // ... // /   ProtectedFree   string1 oDiv1.getElementsByClassName(string1); // ... // /   ProtectedFree   string2 oDiv1.getElementsByClassName(string2); 

Thus, using the technique described above, an attacker can determine any pattern he needs for allocating and freeing memory on the heap. The complexity of the Memory Protection behavior when freeing memory is eliminated.


For the sake of interest, it is highly recommended to read in [1] as far as possible, by using the Memory Protection mechanism of work, bypassing ASLR.


Memory Garbage Collector (MemGC)


The following mechanism, which we consider, can be called a successor of Memory Protection. It is called Memory Garbage Collector (MemGC), and was introduced in the new Edge engine in Win10. Subsequently appeared in IE11.


The goal of implementing MemGC is the same as that of MP, protection against exploits like UAF.


The guys from Microsoft write [3] that MemGC works in the same spirit as MP, but also scans the “heap”, in addition to the stack and registers, for references to protected object types.


But, of course, they are a little cunning, and the difference is not only in the additional viewing of the heap, but also in the implementation. Let us consider it in more detail [4].


MemGC uses a separately managed heap called the MemGC Heap (straightforward name). It is used to allocate memory to objects and garbage collection - in fact, the same Reclamation Sweep operation, only those memory areas that are not referenced in the MemGC Heap are also released. MemGC Edge JavaScript- Chakra ( JS-, ). , .


, Microsoft Chakra. , .


, MemGC, , «» ( Segments ), «» ( Pages ) 4096 . , ( Blocks ), , , :


MemGC_Heap_Diagram_V2
12 – MemGC Heap ( [4] )


EdgeHTML/MSHTML DOM , , MemGC. MemGC «», Isolated Heap, , .


Those. , MemGC Isolated Heap, Memory Protector, UAF- ( 1, ).


MemGC :


  1. ;
  2. ;
  3. « » (Garbage Collector).

.


1. .


MemGC EdgeHTML, , MemGC, , edgehtml!MemoryProtection::HeapAlloc<1>() edgehtml!MemoryProtection::HeapAllocClear<1>() , , , chakra!MemProtectedHeapRootAlloc() .


MemGC_HeapAlloc
13 – MemoryProtection::HeapAlloc<1>()


chakra!MemProtectedHeapRootAlloc() (chunk) (Block) «» (Bucket), “root”. “Root”-, MemGC, / , (directly referenced) « ».


2. .


, edgehtml!MemoryProtection::HeapFree() , , , chakra!MemProtectHeapUnrootAndZero() .


MemGC_HeapFree
14 – MemoryProtection::HeapFree()


chakra!MemProtectHeapUnrootAndZero() (Block), , «root». «root» , « » , MemGC .


3. (Garbage Collection)


, , «root» , , chakra!MemProtectHeap::Collect() . « » Reclamation Sweep, “root” , . Reclamation Sweep ( chakra!Memory::Recycler::ThreadProc ), chakra!Memory::Recycler::StartConcurrent() .


– . , «root»- ( chakra!Memory::Recycler::BackgroundResetMarks() ).


, «root»- (.. , ), . chakra!Memory::Recycler::ScanImplicitRoots() chakra!MemProtectHeap::FindRoots() ). , . , , .


, ( ….), [5].


, MemGC IE , Edge, mshtml.dll.


, MemGC Memory Protection:


  1. MemGC , «» , , , – .. «»;


  2. MemGC , «» ( , ZDI :) );


  3. , Reclamation Sweep, , Memory Protection, . .


  4. MemGC UAF , .

MemGC, ( , ) .


Sandbox


, – «», . , , .


IE 7 Windows Vista, Protected Mode. , IE10 Win8, Protected Mode – Enchanced Protected Mode (EPM).


, EPM .


Architecture


IE Edge «» Loosely-Coupled IE (LCIE) , 8 IE. . -, . , Low Integrity Level IE AppContainer – Microsoft — Edge. Windows.


sandbox
15 — Sandbox IE Edge ( [6] )


Windows ACL – access control lists – .


DACL (discretionary access control list – ), (ACE – access control entries): (, , ..). (access token) , SID- – : , .., DACL .


Microsoft , .. MIC – mandatory integrity control – ; .. integrity level – « » ( , « » ). , , . .


Nameless
16 — Integrity Level IE


. RCE IE, , , , - .


AppContainer Windows. , , , . , , , , . , . SID- , “capabilities”, internetClient, location microphone, .


, ACE DACL, , SID «ALL APPLICATION PACKAGES». , , .


1
17 —


, , , , ( “Program Files” SID). , Mark Yanson [6], , , , .


:


  1. -, , ;


  2. , , , , , .

capcom.sys, . «» :


CtD6L38XYAA2krC.jpg_large
18 — capcom


: SMEP, , . , .


Another example. Windows 10 dismhost.exe (Disk Cleanup), , . DLL %TEMP%, . , , .


Chakra JIT Hardening


JS Microsoft — IE 11 Edge – Chakra, JS . JS- JIT (just-in-time) , JS- , web-.


, JIT . , . :



JIT , .



JIT , xor, – “ constant blinding ”. ROP- , – “ insert NOPs ”.


Constant blinding


? , , – .


ROP-, VirtualProtect(addr, size, flags, oldflags). Windows, -, .. , . : , , , .


x64, WinAPI fastcall, – rcx, rdx, r8 r9, – . , , : pop R + ret. rcx rdx , r8 r9 . “pop R”, R – x64 r8 — r15, pop – REX , , ret . , , :


 81 C0 41 58 00 00 add eax, 5841h ___________________________________________ 41 58 pop r8 00 00 add byte [rax], al 

: rax - , , , . , ...


:



Insert NOPs


JIT- , .


 0000 mov rax, 2B5C990h 000A cmp rsp, rax 000D jg loc_2AE0034 0013 mov rdx, 500790h 001D mov rcx, 990h 0027 mov rax, 7FEF3435450h 0031 jmp rax 0034 ; --------------------------- 0034 0034 loc_2AE0034: 0034 mov rax, 23D61A8h 003E inc byte ptr [rax] 0040 jnz loc_2AE0049 0046 mov byte ptr [rax], 0FFh 0049 0049 loc_2AE0049: 0049 mov [rsp+20h], r9 004E mov [rsp+18h], r8 0053 mov [rsp+10h], rdx 0058 mov [rsp+8], rcx 005D push rbp 005F mov rbp, rsp 0062 sub rsp, 10h 0066 push rdi 0068 push rsi 006A push rbx 006C sub rsp, 38h 0070 xor eax, eax 0072 mov [rbp-8], rax 

NOP- .


 0000 mov rax, 33CC990h 000A cmp rsp, rax 000D jg loc_3160035 0013 mov rdx, 326890h 001D mov rcx, 990h 0027 mov rax, 7FEF3435450h 0031 jmp rax 0034 ; --------------------------- 0034 nop 0035 0035 loc_3160035: 0035 mov rax, 2FAC1A8h 003F inc byte ptr [rax] 0041 jnz loc_316004A 0047 mov byte ptr [rax], 0FFh 004A 004A loc_316004A: 004A mov [rsp+20h], r9 004F mov [rsp+18h], r8 0054 mov [rsp+10h], rdx 0059 mov [rsp+8], rcx 005E push rbp 0060 mov rbp, rsp 0063 sub rsp, 10h 0067 push rdi 0069 push rsi 006B push rbx 006D sub rsp, 38h 0071 xor eax, eax 0073 mov [rbp-8], rax 

34h. .


 0034 nop dword ptr [rax] 0037 nop dword ptr [rax+00h] 003B xchg ax, ax 

NOP-, .


, .


JIT & CFG (Control Flow Guard)


— CFG Windows 8.1. [8].


, JIT- , , , , , — , .


, CFG, , — rax , . : JIT ROP, rsp , , rsp , , rax — , ( vtable!), add byte [rax], al . .


 mov rax, [rdi] ; this->vtable mov rbx, [rax+208h] ; ptr = vtable[idx] mov rcx, rbx ; _QWORD call cs:__guard_check_icall_fptr mov rcx, rdi ; this 

JIT- JS. WARP Edge, JIT- JS [9].


Conclusion


– IE Edge — , . , — . , , . , , .



  1. https://www.blackhat.com/docs/us-15/materials/us-15-Gorenc-Abusing-Silent-Mitigations-Understanding-Weaknesses-Within-Internet-Explorers-Isolated-Heap-And-MemoryProtection-wp.pdf
  2. https://securityintelligence.com/understanding-ies-new-exploit-mitigations-the-memory-protector-and-the-isolated-heap/
  3. https://blogs.technet.microsoft.com/srd/2016/01/12/triaging-the-exploitability-of-ieedge-crashes/
  4. https://www.blackhat.com/docs/us-15/materials/us-15-Yason-Understanding-The-Attack-Surface-And-Attack-Resilience-Of-Project-Spartans-New-EdgeHTML-Rendering-Engine-wp.pdf
  5. https://github.com/zenhumany/hitcon2015
  6. https://www.blackhat.com/docs/asia-14/materials/Yason/WP-Asia-14-Yason-Diving-Into-IE10s-Enhanced-Protected-Mode-Sandbox.pdf
  7. http://users.ics.forth.gr/~elathan/papers/ndss15.pdf
  8. https://habrahabr.ru/company/dsec/blog/305960/
  9. https://472ac6bb-a-62cb3a1a-s-sites.googlegroups.com/site/bingsunsec/WARPJIT/JIT%20Spraying%20Never%20Dies%20-%20Bypass%20CFG%20By%20Leveraging%20WARP%20Shader%20JIT%20Spraying.pdf

The authors



')

Source: https://habr.com/ru/post/311616/


All Articles