返回首页
当前位置: 主页>Script>

Microsoft Windows Scripting Encoder加密算法的研究

时间:2007-05-14 12:04来源: 作者: 点击:
过 去很长时间以来,在网页中使用的脚本是明文的,这不仅造成了脚本的知识产权无法保护,也带来了一些安全问题:一些没有经验的 ASP (指 Active Server Pages ,下同)管理员可能会把一些关键的代码直接写入 ASP 页面中,而这些代码一旦由于某种原因被居心不良的用户
  

去很长时间以来,在网页中使用的脚本是明文的,这不仅造成了脚本的知识产权无法保护,也带来了一些安全问题:一些没有经验的ASP(指Active Server Pages,下同)管理员可能会把一些关键的代码直接写入ASP页面中,而这些代码一旦由于某种原因被居心不良的用户看到,其后果可想而知。针对这种情况,Microsoft公司在推出Microsoft Internet Explorer的同时在其Scripting虚拟机中引入了一种新的技术:Script Encoding。这种技术通过加密叫本来避免上面提到的那些问题。

然而有意思的是,Microsoft在推出Script Encoder的同时,在其文档中又特别提到:

 

注意,这种编码只能防止别人在无意中查看到您的代码,并不能防止蓄意黑客查看您的编码内容及其方法。

 

这句话显然是说,如果愿意的话,破解经过编码的脚本并不需要花费太大的力气。我们不妨推测一下Microsoft引入编码脚本的目的:防止那些初级用户看到代码,而对于那些有能力破解经过编码的脚本的用户而言,与其破解编码脚本,不如自己去写。这意味着,事实上如果有人想看到经过Script Encoder加密的脚本的原始内容,并不需要花费太多的功夫,尽管根据Microsoft提供的资料,经过加密的脚本是由单独的脚本引擎执行的。

考虑到Microsoft所声称的:Script Encoder可以防止脚本被随意篡改——即使微小的变化也可以导致整个编码代码块无法运行——以及并不阻止有预谋的黑客查看脚本,我们不妨作一个这样的假设:Microsoft使用了一种很简单的加密算法(几乎可以肯定不是非对称加密算法,因为那样会很慢,而且也确实没有必要),而这种算法还能够检验数据的完整性(或者配合数据完整性检验算法,如MD5SHA1等等)。

 

我们不妨以Microsoft提供的例子[2]做一下编码操作:

<SCRIPT LANGUAGE="JScript">

//Copyright? 1998. ZYX Productions. All rights reserved.

//**Start Encode**

//Your script here

</SCRIPT>

结果:

<SCRIPT LANGUAGE="JScript.Encode">

//Copyright? 1998. ZYX Productions. All rights reserved.

//**Start Encode**#@~^GgAAAA==@#@&z&IW!DPkmMrwDP4+M+@#@&tAYAAA==^#~@</SCRIPT>

(由于排版原因发生折行,黑体字部分实际上是一行)

 

根据Microsoft的技术文档,Jscript.Encode是由单独的虚拟机[3]执行的,也就是说,并不存在解密的过程。

 

进行一番实验:

编码前

编码后

Foo

#@~^CwAAAA==@#@&sGK@#@&UgEAAA==^#~@

Fou

#@~^CwAAAA==@#@&sG!@#@&WAEAAA==^#~@

FooFoo

FooFoo

#@~^GAAAAA==@#@&sGKsKW@#@&sKGsKW@#@&1QQAAA==^#~@

经过观察,不难看出,@#@&代表回车这一结论(并且,由于实际使用的是Windows文本而不是UnixMac文本,我们可以暂时假定@#代表CR@&代表LF)。并且,文字所处的位置对于编码的结果有影响(注意到第一个FooFoo变成了sGKsKW,而第二次它变成了sKGsKW)。

为了进一步了解编码算法,我们编码200个小写字母a,其结果是[注,折行仅仅是为了排版,正常编码中没有折行]:

 

#@~^zAAAAA==CmlCmlmllmlmClmlClmlCCmllmClmllmCClmlmlClCCmlClmClmlCCmllCCmlClmCmlCmlmllmlmClmlClmlCCmllmClmllmCClmlmlClCCmlClmClmlCCmllCCmlClmCmlCmlmllmlmClmlClmlCCmllmClmllmCClmlmlClCCmlClmClmlCCmllCCmlClmCmlCmlml@#@&30sAAA==^#~@

  

仔细观察上面的文字,可以看出a对应3种形式,C,m,l. 并且,这形式和文字的位置有关系,并且,如上面用下划线标出的,这密文每64字节重复一次。经过试验发现,Script Encoder并不编码中文,对于那些“特殊字符”,也只是做类似CRLF的编码方式的处理。这样,Script Encoder编码处理的脚本中,只有ASCII 32~ASCII 126,以及ASCII 9TAB符)被编码,这编码与一个长度为64的线性表有关。个人推测,对于ASCII 9的编码的目的在于加强编码的强度,因为通常脚本编写人员写的代码中ASCII 9的出现频率很高。这样,无论Microsoft Script Encoder采用了什么样的加密算法,我们都可以用替换编码法来等效。

C=1, m=2, l=0, 我们可以得到a的编码表:

 

1, 2, 0, 1, 2, 0, 2, 0, 0, 2, 0, 2, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0, 2, 1, 0, 2, 0, 0, 2, 1, 1, 0, 2, 0, 2, 0, 1, 0, 1, 1, 2, 0, 1, 0, 2, 1, 0, 2, 0, 1, 1, 2, 0, 0, 1, 1, 2, 0, 1, 0, 2

 

通过实验发现,事实上对于所有的字符,编码表是完全相同的。基于以上的事实,我们可以构造下面的程序:

 

char EncoderTable[64] = {1, 2, 0, 1, 2, 0, 2, 0, 0, 2, 0, 2, 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0, 2, 1, 0, 2, 0, 0, 2, 1, 1, 0, 2, 0, 2, 0, 1, 0, 1, 1, 2, 0, 1, 0, 2, 1, 0, 2, 0, 1, 1, 2, 0, 0, 1, 1, 2, 0, 1, 0, 2}; // 替换索引

char SubTable[128][3] = {....}; // 替换表

int Encode (char c)

{

   static int nPosition=0;

   nPosition++;

   nPosition%=64;

   if(!IsSpecial(c)){

     return (SubTable[c][EncoderTable[nPosition]]);

    }

   else {return ProcessSpecial(c);}

}

int作为返回类型的主要原因是有时需要返回两个字节。ProcessSpecial函数用来处理那些特殊字符。SubTable可以通过对整个字符集编码得到。

通过将4个字符加上用于凑齐64字节的某个特定字符,容易得到Microsoft Script Encoder的编码集:(ASCII 932-126

d7i P~, "Ze JEr a:[ ^yf ]Yu ['L BvE `cv #b* eMC _Q3 ~SB OR  R c z&J

!TZ Fq8  +y &f2 c*W *Xl v+ G{F %0R ,1O )l= iIp @!@!@! 'x{ @*@*@*

g_Q @$@$@$ b)z A$~ Z/; f9G 23A sow M!V Cu_ q(& 9Bx |Fn SJd H\t

1Hg r6} nKh p}5 I]" ?j U KP: ji` .#j   q (po 5eI }t\ $,] -w' TDY

7?% {m| =|# lCm 48( m^1 N[9 +n 0W6 oLT t44 krb L%N 3V0 Vs^ :hs xU      WGK

w2a ;5$ D.M /dk YOD E;! \-7 hAS 6aX XzH y".      `P uk- 8N) U=?

从这个编码集我们可以看出,@ < >也像CRLF这些特殊字符一样进行了特殊的编码处理(这不难理解,因为@用于表示特殊字符)。而< >这两个字符进行特殊编码,个人猜想是为了便于脚本虚拟机的设计。

 

以上就是Microsoft Script Encoder使用的加密算法。从这个编码算法来看,它本身并没有防止篡改的功能。加密后文本的前12字节和最后12字节是为脚本虚机提供信息的。经过分析发现,对于已经试验过的脚本来说,开头的#@~和最后的#~@都是一样的。根据这个情况,我们可以推测它们是脚本开始、结束的实际标志。经过试验发现,#@~后面的字符随脚本的长度变化,而最后12字节中#~@前面的内容随脚本的内容而变化。据此可以推测头部的12字节包含的是脚本的长度信息,而最后12字节包含的是脚本的校验信息。这些信息的编码方法还有待研究。

 

通过分析Microsoft Script Encoder的加密机制,可以得到下面的结论:

(1)              Microsoft在文档中提到的那样Microsoft Script Encoder使用的加密算法并不是一种强加密算法。因此,它并不能提供特别可靠的安全。但对于一般的应用来说,由于算法简单、效率高,可以满足应用。这提示我们,实现一个系统的时候,应该选择最符合实际需要的算法,而不一定是最“安全”或者“高效”的算法。

(2)              通过结合长度、校验和信息,可以增强本来没有反篡改能力的替换算法的性能,使其具有反篡改能力。这种方法,在实际设计应用系统的时候无疑是非常有用的。

(3)              根据本文提供的加密算法,可以很容易地写出Microsoft Script Encoder的解密程序。限于篇幅,本文对于解密算法不再赘述。


 

[1] 根据Microsoft的许可协议,用户不能对Microsoft软件产品实施逆向工程。本文仅仅通过对Microsoft Script Encoder的行为进行分析,并不违反许可协议。

[2] Microsoft Script Encoder中文版提供的文档有误。Microsoft Script Encoder开始编码标记应该是//**Start Encode,而不是中文版文档中所说的//**开始编码。

[3] 技术文档如此。虽然没有拆过Script Encoder,然而我个人认为这似乎没有必要。

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发布者资料
admin 查看详细资料 发送留言 加为好友 用户等级:注册会员 注册时间:2007-05-18 01:05 最后登录:2010-11-21 11:11
推荐内容
热点内容