ASP/VBScript巧用CAPICOM实现随机数、Hash(MD5/SHA1)和Base64编解码

其实很早就想介绍这个Windows内置的ActiveX/COM组件,我前面有一篇文章介绍如何借用.NET Framework实现类似于SHA1和MD5哈希算法,如果大家对此感兴趣也可以看一下。

好,言归正传,今天我要介绍的是如何让VBScript利用Windows原生自带的CAPICOM组件来实现随机数、Hash(MD5/SHA1)以及Base64算法,当然在VBScript的世界里,这些算法都有免组件的纯代码实现,当然使用组件的好处就是代码简洁和运行效率的提高,所以我们不妨尝试一下。
既然今天介绍的主角是CAPICOM,当然我们要推荐参考微软的MSDN文档,大家不妨先大致浏览一番,可能大家很快发现下面这段提示:

CAPICOM is a 32-bit only component that is available for use in the following operating systems: Windows Server 2008, Windows Vista and Windows XP. Instead, use the .NET Framework to implement security features.

继续阅读

ASP/VBScript模拟实现PHP extract()函数将字典集合转换为对象

写过PHP的都知道,其有个extract()非常方便,可以便捷的将字典转换为变量,当然到ASP中则要受限很多,特别是VBScript脚本,本文叙述的就是一种转换的思路,可以实现类似的功能。

首先需要我之前公布的一个类DynamicObject(最新版本的),大家可以移步这里找到相应的代码和说明。

了解了DynamicObject类和其工作原理后,下面我就直接提供ASP版本的extract代码吧:

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
'
' ASP/VBScript Dictionary extract
' Author: WangYe
' For more information please visit
'     http://wangye.org/
' This code is distributed under the BSD license
'
' collection 集合或者字典,可以通过For Each访问的
'            Request.Form 或者 Request.QueryString
' specified  指定必须存在的属性,假如该属性不存在,将自动创建一个
' prefix     每个属性的前缀修饰
' callback   对于集合或者字典的每个元素(key-value)的值进行函数调用
'            函数原型:
'            Function filter(key, value)
'                filter = value
'            End If
'            最终值将以该函数返回的值为准
' 
Function extract(collection, ByVal specified, prefix, callback)
    Dim VarName, VarValue, DynObj, searchKey
    specified = "," & Replace(specified, " ", "") & ","
 
    Set DynObj = New DynamicObject
    For Each key In collection
        searchKey = "," & key & ","
        If InStr(1, specified, searchKey, 1)>0 Then
            specified = Replace(specified, searchKey, "")
            If Left(specified, 1) <> "," Then
                specified = "," & specified
            End If
            If Right(specified, 1) <> "," Then
                specified = specified & ","
            End If
        End If
 
        VarName = prefix & key
 
        VarValue = collection(key)
        If callback<>"" Then
            VarValue = GetRef(callback)(key, VarValue)
        End If
 
        DynObj.add VarName, VarValue, PROPERTY_ACCESS_READONLY
	Next
 
    specified_array = Split(specified, ",")
    Dim i
    For i = LBound(specified_array) To UBound(specified_array)
        If specified_array(i)<>"" Then
            DynObj.add prefix & specified_array(i), "", _
		PROPERTY_ACCESS_READONLY
        End If
    Next
    Set extract = DynObj.GetObject()
End Function

继续阅读

ASP/VBScript动态创建属性对象的工厂类(DynamicObject)

最近整理ASP/VBScript代码,发现过去的一个ASP实现的MVC框架,可惜是个半成品,效率也成问题,不过发现里面有些我写的代码,感觉还稍稍可以拿出来见人,于是今天作此文以记之。

说是ASP,其实和VBScript也脱不了干系,VBScript语言传承于Visual Basic,VB的语法灵活度已经不尽如人意了,VBS作为其子集可想而知。神马反射、自省等先进的技术,微软在.NET中才引入。作为被抛弃的技术,也不奢望微软能够提供支持,于是顽固守旧的程序员只有绞尽脑汁的去模仿实现一些类似的功能。

好吧,我承认很长一段时间我就是顽固守旧派中的一员,今天介绍的就是其中的一项功能,动态创建一个属性对象,属性对象姑且这么称呼,也就是说动态创建的对象只包含属性(Properties)。

继续阅读

ASP/JScript将字典对象(Scripting.Dictionary)存储到Application

最近要改进一个旧项目,项目采用ASP(JScript)编写,由于时间问题一直没有重构,所以还是ASP将就着,考虑到效率问题,准备把部分内容缓存起来,当然直接读写Application缓存不是很妥当的,遂采取缓存字典对象(Scripting.Dictionary)来实现。好了,一般会认为代码如下所示:

var key = "dict_cache"
var obj = Server.CreateObject("Scripting.Dictionary");
 
Application.Lock();
Application.Contents(key) = obj;
Application.Unlock();

偏偏事与愿违,如果你这样做的话,IIS会报“不允许的对象使用方式”错误,具体内容如下:

Application 对象 错误 'ASP 0197 : 80004005' 

不允许的对象使用方式 

/index.asp,行 12 

不能将具有单元模型行为的对象添加到应用程序的内部对象中。 

继续阅读

ASP/VBScript通过飞信实现发送短信和短消息功能(Fetion SMS)

前一段时间正好对电脑发送短信比较感兴趣,因为自己那款老掉牙的手机慢慢的输入文字再群发确实很不方便,于是想移动有没有开放短信接口什么的,上网搜索了有关短信发送的相关知识,找到了Demon的这篇关于《VBS短信飞信发送类(VBSFetion)》,原来是利用了移动的WAP飞信,然后模拟POST,实现短信或者飞信的发送,优点是发送免费,唯一遗憾的是貌似只能发给自己或者飞信好友。不过发送给自己倒是个不错的功能,可以实现一些监控报警类的功能。其实139邮箱那个短信发送到是可以发给任何人,只不过是按正常短信收费标准进行收费,而且主显号码是在你原先的号码上附加了一串长号,这点有点不爽。鉴于Demon在这一方面已经先行一步,我就利用其算法,改造了自己的一个VBScript类实现。

不过值得注意的是,所有POST或者GET发送的消息需要进行编码处理,在ASP中这点还是比较容易的,直接Server.URLEncode就可以了,但是在本机脚本WScript环境下却要费一番周折。网上查找了一下资料,这次仍然找到了Demon的解决方案《用VBS实现PHP的urlencode函数》。好了,基本上解码就分为ANSI版和UTF-8版,我将其改写如下:

继续阅读

ASP上传漏洞之利用CHR(0)绕过扩展名检测脚本

本文部分脚本具有攻击性,仅供学习研究用,请用在合法合理范围内,对造成的损失本人不承担责任,本人也不提供黑客攻击技术指导。

今天Demon提到了这个问题,正好想到之前看到的一篇文章《Automatic file upload using IE+ADO without user interaction – VBSscript》。这篇文章给出了本地无交互自动上传脚本的示例,正好今天可以借来一用,原脚本利用了InternetExplorer.Application组件,我改写了一下,用WinHttp.WinHttpRequest.5.1实现了类似的功能,关于这个组件更多的用法请参考《WinHttpRequest Object Reference》

继续阅读

ASP连接数据库“未找到提供程序.该程序可能未正确安装”问题

今天调试了基于Access数据库的ASP应用,没想到IIS7报错,提示“ADODB.Connection 错误 ‘800a0e7a’ 未找到提供程序。该程序可能未正确安装。”ASP连接数据库的连接字符串是Provider=Microsoft.Jet.OLEDB.4.0; Data Source=路径,采用的是OleDB方式连接,问题可能就出在OleDB方式连接这一环节上。

后来搜索网络得到了解决的办法。原来是自己装的64位Windows 7系统的原因,默认64位环境下,IIS应用程序池未启用32位应用程序,我们只需要启用一下就可以了。打开IIS 7,定位到“应用程序池”,然后选择使用OleDB方式连接数据库的程序池,然后将启用32位应用程序设置为True就可以了。

应用程序池启用32位应用程序.png 继续阅读

ASP/VBScript中CHR(0)的由来以及带来的安全问题

CHR(0)是个特殊的字符,当然在Visual Basic或者VBScript中可以直接用vbNullChar表示,从数值意义上来说这个字符就是数字0。该字符标识着字符串的结束,也称作null-terminated,这个给脚本编程尤其是ASP编程带来了一定的麻烦,很多人可能会问为什么要保留这个特殊字符,我们可以追溯到编写操作系统的语言之一C语言,学过C/C++的童鞋可能知道,在字符串中标识一个字符串结束靠的就是结尾的\0(NULL或者0),否则不能称作为字符串,只能说是字符串数组,任何对于字符串操作的函数如果传入的字符串丢掉了这个结束NULL字符,都有可能会出现异常。

char strbuf[] = "Hello"
// 等价于
char strbuf[] = {'H', 'e', 'l', 'l', 'o', '\0'}

字符串长度的判断函数简单的实现之一:

size_t strlen_a(const char * str) {
  size_t length = 0;
  while (*str++ )
    ++length;
  return length;
}

继续阅读

ASP/VBScript 利用.NET Framework实现PHP sha1() md5()

其实.NET Framework的一些库,ASP是可以直接借来用的,这点我在《ASP/VBScript访问并使用.NET Framework对象》文中已经做了简单的说明,今天正好又遇到一个借用.NET Framework实现某个特殊功能的例子。

在PHP中要计算文本的SHA-1其实很容易,直接使用sha1()这个函数就能轻松搞定了,但是在ASP中就杯具了,没有现成的函数,只能靠手写代码,包括md5()这些常用的哈希函数都要自己编码,好在已经有大牛帮我们写好代码了,我们只需要直接捡现成的用就可以了,比如说MD5就已经有不错的ASP/VBScript版本,关于不同语言的MD5实现可以参考在这里。好了,下面谈下比较棘手的SHA-1算法吧,你肯定说这个也有现成的ASP代码,是的,而且国内著名的ASP博客程序PJ-Blog已经内置了这种SHA-1算法了,那有什么好纠结的呢?PJ的SHA-1代码源于这里,这个实现代码其实是JavaScript版本的,因为IIS的ASP技术默认支持VBScript和JavaScript/JScript两种脚本语言,所以我们可以直接拿来和VBScript混合使用。似乎这样也没有什么问题,但是对于ASP这种古老的技术而言,性能一直是其最大的瓶颈,而ASP性能建议上提到,不要混用两种脚本语言,也就是说混用VBScript和JScript会导致服务器缓存两个脚本解释引擎,而且会导致上下文切换的开销,所以性能上就有所损耗了,由于初始配置的IIS是把VBScript作为默认脚本语言,再加上JScript的对象模型,所以和JScript比起来VBScript可能性能上要好一点。

好吧,下面我们要做的是搞个VBScript版本的SHA-1,在这里我偷懒了点,求助了万能的谷歌,然后找到了一篇文章《Replicating PHP’s sha1() in VBScript》,其中就提到了,借用.NET Framework的技术实现了VBScript版本的sha1,由于是通过Server.CreateObject实现的,所以代码比较简洁,性能上也应该说得过去,在这里我改写成类似PHP的sha1()函数:

继续阅读

ASP中Server.Execute和Execute实现动态包含(include)脚本的区别

最近打算尝试一下在ASP中实现MVC架构,肯定有人问我:ASP都淘汰了,为什么还研究?这点我也知道,自从微软放弃ASP 3.0转向ASP.NET后,ASP已经远远落后于和它几乎同时开始的PHP和JSP,开源比闭源的好处就像PHP和ASP一样,ASP说淘汰就淘汰,谁也救不了,但是值得注意的是ASP在中国市场还是蛮广泛的,尤其是一些中小企业的一些应用,简单的CMS不在话下,而且部署简单,在一些老旧的Windows系统上,不需要安装.NET Framework基本上就可以直接运行了,所以准备一个框架,还是有必要的,不过我这个是实验性框架,只是验证ASP究竟能不能实现类似PHP的MVC架构。

好了,说了这么多,下面直接转入正题吧。这个问题的缘由是因为我需要动态包含ASP文件,大家知道在ASP中只有一种include方法,那就是SSI(Server Side Include),基本上分为以下两种:

1
2
<!-- #include file="sample.asp" -->
<!-- #include virtual="sample.asp" -->

这两种基本上大家第一种用得多一些,#include virtual包含的是虚拟路径,一般虚拟目录会用得到。但是这两种都属于静态的,如果我们希望是动态包含,但不可以写成:

1
2
<!-- #include file="<%=MyVar%>" -->
<!-- #include virtual="<%=MyVar%>" -->

上面的写法是错误的,可以理解为,#include指令是在ASP启动脚本引擎执行ASP<% %>标记之间脚本之前执行的,也就是说#include不是ASP的工作,而是服务端程序,如IIS的翻译工作,所以就不会理会你的ASP代码了。

继续阅读