-
-
[原创]Internet Explorer漏洞分析(三)[上]——VBScript Scripting Engine初探
-
发表于: 2021-3-7 17:44 1019
-
Internet Explorer漏洞分析(三)[上]——VBScript Scripting Engine初探
1 2 3 4 5 | 1. 本文一共 1514 个字 28 张图 预计阅读时间 10 分钟 2. 本文作者erfze 属于Gcow安全团队复眼小组 未经过许可禁止转载 3. 本篇文章是文章Internet Explorer漏洞分析(三)[下]——CVE - 2014 - 6332 的前置知识,对vbscrip.dll组件进行逆向分析,以及VBScript数据类型,数组,VarType函数,LenB函数详细分析,并介绍VBS脚本调试技巧 4. 本篇文章十分适合漏洞安全研究人员进行交流学习 5. 若文章中存在说得不清楚或者错误的地方 欢迎师傅到公众号后台留言中指出 感激不尽 |
近来分析Internet Explorer历史漏洞,遂对VBScript脚本解析引擎进行研究,具体环境如下:
- OS版本:Windows 7 Service Pack 1
- Internet Explorer版本:8.0.7601.17514
- vbscript.dll版本:5.8.7601.17514
0x01 变量
VBScript中仅有一种数据类型——Variant。其结构定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | typedef struct tagVARIANT { union { struct { VARTYPE vt; WORD wReserved1; WORD wReserved2; WORD wReserved3; union { LONGLONG llVal; LONG lVal; BYTE bVal; SHORT iVal; FLOAT fltVal; DOUBLE dblVal; VARIANT_BOOL boolVal; VARIANT_BOOL __OBSOLETE__VARIANT_BOOL; SCODE scode; CY cyVal; DATE date; BSTR bstrVal; IUnknown * punkVal; IDispatch * pdispVal; SAFEARRAY * parray; BYTE * pbVal; SHORT * piVal; LONG * plVal; LONGLONG * pllVal; FLOAT * pfltVal; DOUBLE * pdblVal; VARIANT_BOOL * pboolVal; VARIANT_BOOL * __OBSOLETE__VARIANT_PBOOL; SCODE * pscode; CY * pcyVal; DATE * pdate; BSTR * pbstrVal; IUnknown * * ppunkVal; IDispatch * * ppdispVal; SAFEARRAY * * pparray; VARIANT * pvarVal; PVOID byref; CHAR cVal; USHORT uiVal; ULONG ulVal; ULONGLONG ullVal; INT intVal; UINT uintVal; DECIMAL * pdecVal; CHAR * pcVal; USHORT * puiVal; ULONG * pulVal; ULONGLONG * pullVal; INT * pintVal; UINT * puintVal; struct { PVOID pvRecord; IRecordInfo * pRecInfo; } __VARIANT_NAME_4; } __VARIANT_NAME_3; } __VARIANT_NAME_2; DECIMAL decVal; } __VARIANT_NAME_1; } VARIANT; |
其中VARTYPE
可参阅[Microsoft Docs——VARIANT Type Constants]https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f。例:
1 2 3 4 5 6 7 8 9 | '显式声明 Dim Name,Age, Hex ,Pi Name = "Ethon" Age = 27 Hex = &h80000000 Pi = 3.1415926 '隐式声明 Hello = "ABC123" |
赋值对应函数为vbscript!AssignVar
,于该函数处设断,查看其参数:
0x400C
表示VT_VARIANT
:
判断pvargSrc—>vt
值(具体数值可自行分析,不赘述),若均不满足,执行如下语句:
简单来说,即VariantCopyInd(&pvarDest, pvargSrc)
——>copy pvarDest
to pvarg
:
隐式声明变量其pvarg
全为零:
0x02 数组
数组存储结构由SAFEARRAY
定义:
1 2 3 4 5 6 7 8 | typedef struct tagSAFEARRAY { USHORT cDims; USHORT fFeatures; ULONG cbElements; ULONG cLocks; PVOID pvData; SAFEARRAYBOUND rgsabound[ 1 ]; } SAFEARRAY; |
其中各字段含义可参阅[Microsoft Docs——SAFEARRAY]https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearray ,SAFEARRAYBOUND
结构定义如下:
1 2 3 4 | typedef struct tagSAFEARRAYBOUND { ULONG cElements; LONG lLbound; } SAFEARRAYBOUND, * LPSAFEARRAYBOUND; |
数组定义及赋值操作:
1 2 3 4 5 6 | Dim stu_name( 3 ) stu_name( 0 ) = "Alan" stu_name( 1 ) = "Susan" stu_name( 2 ) = "Lisa" stu_name( 3 ) = "Mary" |
VBS中数组下标由0开始,数组元素个数为n+1(Dim array_name(n)
)。另一种定义数组方法:
1 2 3 | Dim stu_name stu_name = Array( "Alan" , "Susan" , "Lisa" , "Mary" ) |
对应函数为vbscript!MakeArray
:
传递给函数的参数有二——cDims
对应维数,VAR
对应n。cDims
应介于1-64:
先来看一维数组的创建:
为rgsabound
结构各字段赋值:
之后则直接调用SafeArrayCreate
函数进行创建,各参数含义可参阅[Microsoft Docs——SafeArrayCreate]https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate 。创建完成:
为数组元素赋值则直接将该元素所在内存偏移传递给vbscript!AssignVar
:
下面来看看二维数组(Dim stu_name(2,3)
)创建过程:
可以看到数组各维大小于内存中并列存储,之后调用VAR::PvarGetTypeVal
逐一读取为rgsabound
中cElements
字段赋值:
各维大小于内存中由最高维——>最低维存储,故读取时首先计算出v3
变量指向最低维大小所在内存偏移,之后递减。创建完成:
Redim
语句用于重新定义数组大小:
1 2 3 4 5 6 7 8 | '定义一维动态数组 Dim MyArray() '重新定义该数组大小 ReDim MyArray( 3 ) MyArray( 0 ) = "A" MyArray( 1 ) = "B" MyArray( 2 ) = "C" MyArray( 3 ) = "C" |
再次调用vbscript!MakeArray
过程如下:
而在重新定义时加上Preserve
关键字用于保留之前元素:
1 2 3 4 5 6 7 8 9 | Dim MyArray() ReDim MyArray( 3 ) MyArray( 0 ) = "A" MyArray( 1 ) = "B" MyArray( 2 ) = "C" MyArray( 3 ) = "D" ReDim Preserve MyArray( 5 ) MyArray( 4 ) = "E" MyArray( 5 ) = "F" |
其对应vbscript!RedimPreserveArray
函数:
为psaboundNew
各字段赋值完成后传递给SafeArrayRedim
函数:
0x03 可用于调试时函数
IsEmpty(var)
对应vbscript!VbsIsEmpty
,其第三个参数对应var
。一例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!doctype html> <html lang = "en" > <head> < / head> <body> <script LANGUAGE = "VBScript" > dim a a = &h1234 IsEmpty(a) < / script> < / body> < / html> |
IsObject(var)
对应vbscript!VbsIsObject
,同样,其第三个参数对应var
。一例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!doctype html> <html lang = "en" > <head> < / head> <body> <script LANGUAGE = "VBScript" > dim a a = &h1234 IsObject(a) < / script> < / body> < / html> |
在调试时可借助这两个函数以确定变量值或内存位置。
0x04 VarType函数
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!doctype html> <html lang = "en" > <head> < / head> <body> <script LANGUAGE = "VBScript" > dim a a = &h1234 VarType(a) < / script> < / body> < / html> |
VarType
对应vbscript!VbsVarType
,其调用GetVarType
函数获取类型值并完成赋值操作:
参数1用于存储类型值,参数2为VarType
参数:
GetVarType
函数调用PvarGetVarVal
——判断类型值是否为0x4A
或0x0C
:
之后与0x09
进行比较,若不是则直接返回对象进而获取vt
值:
由VbsVarType
函数完成最终赋值给参数1操作:
0x05 LenB函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!doctype html> <html lang = "en" > <head> < / head> <body> <script LANGUAGE = "VBScript" > On Error Resume Next Dim length,a a = 1.12345678901235 length = LenB( "Hello" ) length = LenB(a) < / script> < / body> < / html> |
该函数用于返回存储字符串字节大小,其对应vbscript!VbsLenB
。参数为字符串时,该函数先是call VAR::BstrGetVal
,返回pbstrVal
:
之后call cbLengthBstr
返回长度:
参数为变量时, VAR::BstrGetVal
函数调用VAR::PvarConvert
,将其内容转换为字符串:
之后再进行计算:
cbLengthBstr
函数功能仅是读取字符串存储位置之前4字节内容,该内容为字符串长度:
0x06 参阅链接
- [Microsoft Docs——SAFEARRAY structure]https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-safearray
- [Microsoft Docs——VARIANT structure]https://docs.microsoft.com/en-us/windows/win32/api/oaidl/ns-oaidl-variant
- [Microsoft Docs——VARIANT Type Constants]https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-oaut/3fe7db9f-5803-4dc4-9d14-5425d3f5461f
- [Microsoft Docs——SafeArrayCreate]https://docs.microsoft.com/en-us/windows/win32/api/oleauto/nf-oleauto-safearraycreate
- [Microsoft Docs——DECIMAL structure]https://docs.microsoft.com/en-us/windows/win32/api/wtypes/ns-wtypes-decimal-r1
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!