首页
论坛
课程
招聘
[调试逆向] [原创]VBScript Scripting Engine初探
2021-3-4 16:49 2973

[调试逆向] [原创]VBScript Scripting Engine初探

2021-3-4 16:49
2973

近来分析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。例:

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——SAFEARRAYSAFEARRAYBOUND结构定义如下:

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。创建完成:

 

 

为数组元素赋值则直接将该元素所在内存偏移传递给vbscript!AssignVar

 


 

下面来看看二维数组(Dim stu_name(2,3))创建过程:

 

 

可以看到数组各维大小于内存中并列存储,之后调用VAR::PvarGetTypeVal逐一读取为rgsaboundcElements字段赋值:

 

 

各维大小于内存中由最高维——>最低维存储,故读取时首先计算出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——判断类型值是否为0x4A0x0C

 

 

之后与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 参阅链接


第五届安全开发者峰会(SDC 2021)议题征集正式开启!

最后于 2021-3-7 20:01 被erfze编辑 ,原因:
收藏
点赞2
打赏
分享
最新回复 (4)
雪    币: 15766
活跃值: 活跃值 (13728)
能力值: (RANK:75 )
在线值:
发帖
回帖
粉丝
Editor 活跃值 2021-3-4 18:06
2
0
感谢分享!
雪    币: 547
活跃值: 活跃值 (273)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guangzisam 活跃值 2021-3-5 14:53
3
0
真有闲心,静下来研究技术
雪    币: 8870
活跃值: 活跃值 (4136)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
erfze 活跃值 9 2021-3-5 17:41
4
0
guangzisam 真有闲心,静下来研究技术
在校学生一枚
雪    币: 362
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
GeaC 活跃值 2021-3-20 12:15
5
0
分析的不错
游客
登录 | 注册 方可回帖
返回