Auteur Sujet: [FireEye]The EPS Awakens  (Lu 2865 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne igor51

  • Admin
  • Mega Power Members
  • *****
  • Messages: 10419
[FireEye]The EPS Awakens
« le: mars 23, 2017, 21:00:54 »
The EPS Awakens

On September 8, FireEye     href="/content/fireeye-www/en_US/blog/threat-research/2015/09/attack_exploitingmi.html">published
  details about an attack exploiting zero day vulnerabilities in
  Microsoft Office (  href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2545">CVE-2015-2545)
  and Windows (  href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2546">CVE-2015-2546).
  The attack was particularly notable because it leveraged PostScript to
  drive memory corruption in a way that had never been seen before. The
  exploit used similar strategies as browser exploits in common
  languages such as JavaScript and Flash, but PostScript served as an
  overlooked attack vector that is powerful and convenient in Office.


 

Following the release of the patch for CVE-2015-2545, FireEye
  notified Microsoft of a way to bypass the patch. Microsoft not only
  fixed the bypass, but proactively hardened code throughout the
  Encapsulated PostScript (EPS) filter. The updates were quietly
  released on November 10 (Patch Tuesday).


 

At around 10:00AM in Japan on November 26 (around close of business
  the day before Thanksgiving in the U.S.), threat actors launched a
  spear phishing campaign. The emails contained document attachments
  that exploited a previously unknown EPS vulnerability. But there was a
  catch: the vulnerability was proactively patched in the Microsoft
  update released two weeks earlier.


 

The spearphishing emails to FireEye EX customers were blocked in the
  wild. FireEye appliances detect the exploit as
  Exploit.Dropper.docx.MVX and Malware.Binary.Docx.


 

In the first part of this blog series, we summarize recent threat
  group activity using this exploit and provide complete technical
  details of the vulnerability. Stay tuned for part two wherein we
  outline the operational details of the attack.


 

Activity Summary


 

In late November and early December of 2015, FireEye observed
  multiple spear phishing campaigns exploiting a previously unknown
  Microsoft Office EPS vulnerability (detailed below) and Windows local
  privilege escalation vulnerability CVE-2015-1701. Over the course of
  several days, known and suspected China-based advanced persistent
  threat (APT) groups sent phishing emails containing malicious Word
  attachments to Japanese and Taiwanese organizations in the financial
  services, high-tech, media and government sectors respectively.


 

These attachments exploited a silently patched user-mode Microsoft
  EPS vulnerability (similar to Microsoft EPS use-after-free
  vulnerability CVE-2015-2545) and subsequently used CVE-2015-1701 to
  obtain SYSTEM level access to compromised machines. Following
  successful exploitation of each vulnerability, the exploit shellcode
  deployed either the IRONHALO downloader or the ELMER backdoor. FireEye
  currently detects IRONHALO as Trojan.IRONHALO.Downloader and ELMER as Backdoor.APT.Suroot.


 

Vulnerability Details – Encapsulated PostScript dict copy Use-After-Free


 


 


 

In the form dict1 dict2
  copy, the copy operator copies all of the elements from
  the first operand (dict1) into the second operand
  (dict2).     href="http://www-cdf.fnal.gov/offline/PostScript/PLRM2.pdf">The
    PostScript Language Reference Manual (PLRM), as cited in Figure
  1, states that the copy operator does not affect elements remaining in
  the second operand. For example, if dict1 contained
  an element under key k1, and dict2 contained
  elements under keys k1 and k2, then the operation
  dict1 dict2 copy should
  overwrite the element under k1, but should not affect the
  element under k2.


 

However, Microsoft’s EPS deviates from this standard. In Microsoft’s
  implementation, the copy operator iteratively deletes all
  key-value entries from the dict2 internal hash
  table. Then, it deletes the hash table itself, and allocates a new
  one. Finally, it copies elements from dict2 into
  dict2. This deletion process is depicted in Figure 2.


 


 


 

Using the dict1 dict2 copy
 
operation while enumerating dict2 with forall
 
causes a use-after-free. During each iteration of the
  forall loop, dict2 dereferences a pointer
  (ptrNext) to push the next key-value pair onto the operator stack.
  When copy deletes the next key-value pair, ptrNext becomes
  stale. The next iteration of the forall loop will then push
  objects from the stale pointer onto the operator stack.


 

In an attack scenario, the attacker can allocate memory under the
  stale pointer. The attacker can then supply data that the
  forall enumerator reads as a key-value pair. In the appendix,
  we include a minimized PoC that shows how to allocate a string under
  the stale pointer and forge a key-value pair.


 

Full Read and Write Development


 

The attacker gains access to memory by forging a string.
  Specifically, the attacker places a forged key-value pair under the
  stale ptrNext, and the key-value pair points to a forged string. The
  attacker uses a hardcoded address (130e0020h) in the forged key-value
  pair, and sprays memory at the address with PostScript strings. Figure
  3 shows the PostScript that creates the sprayed string object, and the
  layout of the string in memory.


 


  /fakestr
    <28000e1358000e13bebafeca41414141414141414141414141414141030000004141414141414141414

    1414124000e1300000000ffffff7fbebafeca41414141414141414141414141414141414141414141414

    14141414100000000ffffff7f> def


 


  0:000> dd 130e0000
  130e0000  00000000
    00000000 00000000 00000000
  130e0010  00000000 00000000
    00000000 00000000
  130e0020  130e0028 130e0058 cafebabe
    41414141
  130e0030  41414141 41414141 41414141 00000003

    130e0040  41414141 41414141 41414141 130e0024
  130e0050 
    00000000 7fffffff cafebabe 41414141
  130e0060  41414141
    41414141 41414141 41414141
  130e0070  41414141 41414141
    00000000 7fffffff


 


  Figure 3: The attacker's sprayed PostScript string


 

Each PostScript string object allocates a buffer to store the actual
  contents of the string. The address and size of this buffer is stored
  within the string object. In the attacker’s forged string object, the
  address of the buffer is 0, and the size of the buffer is 0x7fffffff.


 

Return-Oriented Programming


 

Once the attacker has forged a string with size 0x7fffffff, they can
  use the string to freely read and write process memory. The attacker
  uses this capability to search for ROP gadgets and build a ROP chain.


 


  0:000> dd /c 1 130e1032
  130e1032 
    60e2b53a      // retn_gadget
  130e1036  60e2b53a      //
    retn_gadget
  130e103a  00000000
  130e103e 
    00000000
  130e1042  60e69f80      // stack_pivot_gadget

    130e1046  60e398cd      // set_eax_gadget, eax = 0xd7

    130e104a  00000000
  130e104e  00000000
  130e1052 
    00000000
  130e1056  777e5695      // ntcreateevent_gadget+0x5,
    NtProtectVirtualMemory
  130e105a  130e3000      // shellcode
    starts here
  130e105e  ffffffff
  30e1062  130e0200

    130e1066  130e0204
  130e106a  00000040
  130e106e  130e0208


 


  0:000> u 60e2b53a
  EPSIMP32+0xb53a:

    60e2b53a c20c00          ret     0Ch
  0:000> u
    60e69f80
  EPSIMP32!RegisterPercentCallback+0x2234e:

    60e69f80 94              xchg    eax,esp
  60e69f81
    c3              ret
  0:000> u 60e398cd

    EPSIMP32+0x198cd:        // ecx = 130e1000, eax = 0xd760e398cd
    8b4114          mov     eax,dword ptr [ecx+14h]
  60e398d0
    c3              ret
  0:000> u 777e5695

    ntdll!NtCreateEvent+0x5:
  777e5695 ba0003fe7f      mov    
    edx,offset SharedUserData!SystemCallStub
  777e569a
    ff12            call    dword ptr [edx]
  777e569c
    c21400          ret     14h


 


  Figure 4: Attacker's ROP chain


 

The ROP chain, shown in Figure 4, uses a few known tricks to bypass
  security products. First, the ROP chain skips 5 bytes past the
  beginning of ntdll!NtCreateEvent. This would bypass any hooks placed
  on the beginning of the routine (and is known as “hook hopping”), but
  the real purpose of this offset is to pass over an instruction that
  sets eax. This allows the attacker to specify their own parameter in
  eax, and call an arbitrary system call instead of NtCreateEvent. The
  attacker chooses the system call NtProtectVirtualMemory, which marks
  the attacker’s shellcode as executable. Since the system call numbers
  differ between environments, the attacker reads the correct value for
  eax from the ntdll!NtProtectVirtualMemory function (which is the
  user-mode function that is normally used to call the
  NtProtectVirtualMemory syscall).


 

To transfer execution to the ROP chain, the attacker forges a file
  type object. Within the forged file type object, the attacker modifies
  the bytesavailable function pointer to point to a pivot (Figure 5).
  Then, when the attacker uses the forged object in PostScript, it calls
  the pivot and transfers execution to the ROP chain. When the ROP chain
  is complete, it returns into the attacker’s shellcode.


 


 


 


  Figure 5: bytesavailable operator with the
    forged file type object

 
 


 

Shellcode


 

Once the ROP chain finishes and returns to the attacker’s shellcode,
  the shellcode loads a DLL that exploits CVE-2015-1701 to elevate the
  process to SYSTEM. The CVE-2015-1701 exploit is based on published
  source code from GitHub. Once the shellcode process has SYSTEM
  privileges, it will execute further payloads to be discussed in part
  two of this series.


 

Acknowledgements


 

Thank you to Wang Yu, Dan Regalado and Junfeng Yang for their
  contributions to this blog.


 

Appendix
 Simplified PoC


 


  %% Create dict2 and fill it with
  %%  several
    key-value pairs
  /dict2 5 dict def
  dict2 begin

    /k1 1000 array def
  /k2 1000 array def
  …
  dict2 end


 


  %% Create dict1 and fill it with
  %%  one
    key-value pair under k1
  /dict1 3 dict def
  dict1
    begin
  /k1 1000 array def
  dict1 end


 


  %% Begin forall enumeration on dict2
  dict2
    {
       …
      % Destroy dict2’s internal
    hash-table,
      %  freeing all key-value pairs
     
    dict1 dict2 copy
      …
      % Create a new string to
    overwrite the
      % freed key-value pair k2.
      % The
    string contains a forged key-value pair
      44 string

        0
    <00000000ff0300000005000000000000000000002000e01303000000000000000000000044444444>
    putinterval
      % Next iteration of the loop uses
    stale.
      % ptrNext, which points into the above
    string,
      %  and reads a forged key-pair
      …

    } forall


Source: The EPS Awakens

Tags: