摘要:ASP是开发网站应用最快最有效的工具,但是ASP从开始应用到现在一直受到众多漏洞、后门的困扰,其安全问题不容忽视。本文介绍了ASP常见的漏洞及防范措施,防范SQL注入式攻击的方法。本文对于ASP动态网站的开发和维护提供了较好的防漏洞和防攻击的方案。
关键字:ASP;漏洞;注入式攻击
ASP(Active Server Page)是Microsoft公司推出的动态网页开发技术,目前日趋成熟完善。ASP是服务器端脚本编写环境,使用它可以创建和运行动态、交互的Web服务器应用程序。使用ASP可以组合HTML页、脚本命令和ActiveX组件以创建交互的Web页和基于Web的功能强大的应用程序。
ASP脚本是一系列按特定语法(目前支持Vbscript和Jscript两种脚本语言)编写的。当客户端的最终用户用Web浏览器通过Internet来访问基于ASP脚本的应用时,Web浏览器将向Web服务器发出HTTP请求。Web服务器分析、判断出该请求是ASP脚本的应用后,自动通过ISAPI接口调用ASP脚本的解释运行引擎(ASP.DLL)。ASP.DLL将从文件系统或内部缓冲区获取指定的ASP脚本文件,接着就进行语法分析并解释执行。最终的处理结果将形成HTML格式的内容,通过Web服务器“原路”返回给Web浏览器,由Web浏览器在客户端形成最终的结果呈现,这样就完成了一次完整的ASP脚本调用。若干个有机的ASP脚本调用就组成了一个完整的ASP脚本应用。
现在很多网站特别是电子商务方面的网站,在前台上大都用ASP来实现。以至于现在ASP在网站应用上很普遍。 ASP是开发网站应用的快速工具,但是有些网站管理员只看到ASP的快速开发能力,却忽视了ASP安全问题。ASP从一开始就一直受到众多漏洞,后门的困扰,包括密码验证问题,IIS漏洞等等都一直使ASP网站开发人员心惊胆跳。 因此有必要对ASP的常见漏洞有个全面的认识,并采取相应的对策。
1 .ASP常见的漏洞及解决方法
1.1绕过验证直接进入ASP页面的漏洞
漏洞描述:如果用户知道了一个ASP页面的路径和文件,而该文件需要经过验证才能进去,但是用户直接输入这个ASP页面的文件名,就有可能绕过验证。如在IE中输入如下代码:http://serverURL/search.asp?page=1
这样就可能看到了只能是系统管理员才能看到的页面。当然为了防止这种情况也会在search.asp的开头加个判断,如判断session(“system_name”)是否为空,如果不为空时就能进入,这样上面的url请求就不能直接进入管理员页面了。但是这种方法同样也存在漏洞,如果攻击者先用一个合法的帐号,或者在本机上生成一个session,如session(“system_name”)=“admin”,因为session不为空,同样也能绕过验证直接进入管理员页面。
解决方法:在需要验证的ASP页面开头处进行相应的处理。如可跟踪上一个页面的文件名,只有从上一页转进来的话才能读取这个页面。
代码如下:
如果本页来源不是index.asp则返回index.asp
xxx=request.servervariables("HTTP_REFERER")
if xxx<>index.asp then
Response.redirect"index.asp"
end if
1.2 ACCESS mdb数据库有可能被下载的漏洞
漏洞描述:在用ACCESS做后台数据库时,如果有人通过各种方法知道或者猜到了服务器的ACCESS数据库的路径和数据库名称,那么就能够下载这个ACCESS数据库文件,这是非常危险的。如:如果ACCESS数据库book.mdb放在虚拟目录下的database目录下,那么在浏览器中打入:
http:// someurl/database/book.mdb
如果book.mdb数据库没有事先加密的话,那book.mdb中所有重要的数据都掌握在别人的手中。
解决方法:
(1)为数据库文件名称起个复杂的非常规的名字,并把它放在几层目录下。所谓“非常规”,打个比方:如有个数据库要保存的是有关书籍的信息,不要把他起个“book.mdb”的名字,起个怪怪的名称,比如d34ksfslf.mdb,再把他放在如./kdslf/i44/studi/ 的几层目录下,这样黑客要想通过猜的方式得到ACCESS数据库文件就难上加难了。
(2)不要把数据库名写在程序中。有人喜欢把DSN写在程序中,如:
DBPath = Server.MapPath("cmddb.mdb")
conn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath
假如被拿到了源程序,ACCESS数据库的名字就一览无余,因此建议在ODBC里设置数据源,再在程序中这样写:
conn.open “shujuyuan”
(3)使用ACCESS来为数据库文件编码及加密。首先在选取“工具->安全->加密/解密数据库”,选取数据库(如:employer.mdb),然后按确定,接着会出现“数据库加密后另存为”的窗口,存为:employer1.mdb。接着employer.mdb就会被编码,然后存为employer1.mdb。
要注意的是,以上的动作并不是对数据库设置密码,而只是对数据库文件加以编码,目的是为了防止他人使用别的工具来查看数据库文件的内容。接下来为数据库加密,首先打开经过编码了的employer1.mdb,在打开时,选择“独占”方式。然后选取功能表的“工具->安全->设置数据库密码”,接着输入密码即可。为employer1.mdb设置密码之后,接下来如果再使用ACCEES数据库文件时,则ACCESS会先要求输入密码,验证正确后才能够启动数据库。
不过要在ASP程序中的connection对象的open方法中增加PWD的参数即可,如:
param=”driver={Microsoft Access Driver (*.mdb)};Pwd=yfdsfs”
param=param&”;dbq=”&server.mappath(“employer1.mdb”)
conn.open param
这样即使他人得到了employer1.mdb文件,没有密码是无法看到employer1.mdb的。
1.3 code.asp文件会泄漏ASP代码
漏洞描述:在微软提供的ASP1.0的例程里有一个.asp文件专门用来查看其它.asp文件的源代码,该文件为ASPSamp/Samples/code.asp。如果把这个程序上传到服务器,而服务器端没有任何防范措施的话,就可以很容易地查看他人的程序。如:
code.asp?source=/directory/file.asp
不过这是个比较旧的漏洞了,相信现在很少会出现这种漏洞。
下面这命令是比较新的:
http://someurl/iissamples/exair/howitworks/code.asp?/lunwen/soushuo.asp=xxx.asp
最大的危害莫过于asa文件可以被上述方式读出,数据库密码以明文形式暴露在黑客眼前。
解决方法:对于IIS自带的show asp code的asp程序文件,删除该文件或者禁止访问该目录即可。
1.4inc文件泄露问题
漏洞描述:当ASP的主页正在制作且没有进行最后调试完成以前,可以被某些搜索引擎机动追加为搜索对象。如果这时候有人利用搜索引擎对这些网页进行查找,会得到有关文件的定位,并能在浏览器中查看到数据库地点和结构的细节,并以此揭示完整的源代码。
解决方法:程序员应该在网页发布前对它进行彻底的调试;安全专家则需要加固ASP文件以便外部的用户不能看到它们。首先对.inc文件内容进行加密,其次也可以使用.asp文件代替.inc文件使用户无法从浏览器直接观看文件的源代码。inc文件的文件名不要使用系统默认的或者有特殊含义容易被猜测到的名称,尽量使用无规则的英文字母。
1.5自动备份被下载
漏洞描述:在有些编辑ASP程序的工具中,当创建或者修改一个ASP文件时,编辑器自动创建一个备份文件,如:UltraEdit就会备份一个.bak文件,如创建或者修改了some.asp,编辑器会自动生成一个叫some.asp.bak文件,如果没有删除这个bak文件,攻击者可以直接下载some.asp.bak文件,这样some.asp的源程序就会被下载。
解决方法:上传程序之前要仔细检查,删除不必要的文档,对以bak为后缀的文件要特别小心。
1.6特殊字符
漏洞描述:输入框是黑客利用的一个目标,可以通过输入脚本语言等对用户客户端造成损坏;如果该输入框涉及数据查询,会利用特殊查询语句,得到更多的数据库数据,甚至表的全部。因此必须对输入框进行过滤。但如果为了提高效率仅在客户端进行输入合法性检查,仍有可能被绕过。
解决方法:在处理类似留言板、BBS等输入框的ASP程序中,最好屏蔽掉HTML、JavaScript、VBScript语句,如无特殊要求可以限定只允许输入字母与数字,屏蔽掉特殊字符。同时对输入字符的长度进行限制。而且不但要在客户端进行输入合法性检查,同时要在服务器端程序中进行类似检查。
1.7输入标准的HTML语句或者javascript语句会改变输出结果
漏洞描述:在输入框中打入标准的HTML语句会得到什么相的结果呢?
如一个留言本,在留言内容中打入:
<font size=10>你好!</font>
如果ASP程序中没有屏蔽HTML语句,那么就会改变“你好”字体的大小。在留言本中改变字体大小和贴图有时并不是什么坏事,反而可以使留言本生动。但是如果在输入框中写个 javascript 的死循环,如:
<a herf="http://someurl" onMouseover="while(1){window.close('/')}">特大新闻</a>
那么其他查看该留言的人只要移动鼠标到“特大新闻”上就会使用户的浏览器因死循环而死掉。
解决方法:编写类似程序时应该做好对此类操作的防范,譬如可以写一段程序判断客户端的输入,并屏蔽掉所有的HTML、Javascript 语句。
1.8 ASP聊天室程序的漏洞
漏洞描述:如果聊天室ASP程序设计不当,很容易会给利用来做坏事:可以踢人,穿墙,捣乱。首先,看看聊天室里有什么漏洞,看下面这段代码:
<html>
<head>
<body BGCOLOR="008888" TEXT="FFFFFF">
…………………………
<form NAME="sendmsg" ACTION="chatt.asp" METHOD="POST" target="mtalk1"
OnSubmit="return chksend();">
<input type="hidden" name="username" value="测试者">******
<input type="hidden" name="sex" value="boy">********
<input type="hidden" name="message" value="">
<input type="hidden" name="a_method" value="sendtalk">
<div align="center"><center>
<table CELLSPACING="0" CELLPADDING="0"> <tr>
<td>发言: <input type="text" name="msg" size="60"> </td>
<td><input type="submit" value="发言"> </td>
</tr>
<tr>
<td>悄悄:<input type=checkbox name=mtalk value=1>
对象:<input type="text" name="betalk" size="10">
………
</form>
<form name="getout" ACTION="chatt.pl" METHOD="POST">
<input type="hidden" name="username" value="测试者">!!!!!!
<input type="hidden" name="a_method" value="getout">!!!!
<input type="submit" value="退出"></td>
</form>
</body>
</html>
以上这段代码是在某聊天室用“测试者”做代号登陆后在发言帧下载来的,这只是一小部份,但在这一小部份代码里面就有两个漏洞。
第一个漏洞
看上面代码加上“*”号的两句,其中第一句中的“测试者”就是登陆的名字,第二句中的“boy”是登陆时的性别,还有下面加上“!”号的两句,第一句里还有登陆时的名字,这几句都是漏洞所在点。如果想在这个聊天室里穿墙的话,只要把发言帧的代码下载来另存,把“form”的“action”改成聊天室的地址,然后再把“*”号的第一句的“测试者”两字改成想要的名字就可以了。也可以变换性别,只要把第二句的“boy”改成“girl”。这就是所谓的穿墙术了。甚至可以把它改成在线人的名字,然后发言,这样就冒充别人的姓名谈话。
第二个漏洞
带“!”号的第一句,是合法用户登陆的名字,再看第二句,有“getout”,上面还有一段“form”标签,这段就是退出聊天室时的代码,这个有什么用呢?首先把“form”标签的“action”改成聊天室的地址,不然就不知道提交到哪儿了,然后把“风风”改成想踢下去的人的名字,然后单击“退出”,就把那个人踢出聊天室了。这个就是聊天室踢人的漏洞。
这两个漏洞产生的原因是这两个漏洞使服务程序不能识别客户发出的指令是不是合法用户,欺骗服务程序来更名发言或更名退出,使得真正的使用者受害。
上面的程序中还有一个漏洞,输入框没有对HTML语句和JAVASCRIPT语句做过滤,这个问题已经在漏洞7中详细分析。
解决方法:在程序设计中让服务程序能识别到底是谁发出的指令就可以了。具体做法可以为每个聊天者发一个识别码,像五笔字一样,也可以用每个聊天者的密码识别,也可以把聊天者的密码随机加密后用作识别等等,能使服务程序识别到底是谁发出的指令就可以了。
2 .ASP注入攻击及防注入措施
SQL注入式攻击是指利用设计上的漏洞,在目标服务器上运行SQL命令以及进行其他方式的攻击。动态生成SQL命令时没有对用户输入的数据进行验证是SQL注入攻击得逞的主要原因。编写通用的SQL防注入程序一般http请求不外乎get 和 post,所以只要在文件中过滤所有post或者get请求中的参数信息中的非法字符即可,所以实现http请求信息过滤就可以判断是是否受到SQL注入攻击。
IIS传递给asp.dll的get请求是是以字符串的形式,当传递给Request.QueryString数据后,asp解析器会分析Request.QueryString的信息,然后根据“&”分出各个数组内的数据。所以get的拦截如下:
dim sql_injdata SQL_inj SQL_Get
SQL_injdat= "’|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare"
SQL_inj = split(SQL_Injdata,"|")
If Request.QueryString<>"" Then
For Each SQL_Get In Request.QueryString
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.QueryString(SQL_Get),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=JavaScript>alert(’请不要在参数中包含非法字符尝试注入!’);history.back(-1)</Script>"
Response.end
end if
next
Next
End If
这样通过简单的语句就把一些注入所必须的语句和符号过滤掉了,只要插到像conn.asp这样类似被调用比较广泛的页面中就可以了。同样post也可以通过如下代码过滤,可以将两段代码整和到一起,只需要在conn.asp之类的打开数据库文件之前引用这个页面即可。
If Request.Form<>"" Then
For Each Sql_Post In Request.Form
For SQL_Data=0 To Ubound(SQL_inj)
if instr(Request.Form(Sql_Post),Sql_Inj(Sql_DATA))>0 Then
Response.Write "<Script Language=JavaScript>alert(’请不要在参数中包含非法字符尝试注入! ’);history.back(-1)</Script>"
Response.end
end if
next
next
end if
做到上述几点,已经可以置网站于一个相对安全的环境之中了。而实际上,网站安全问题的范畴是十分广泛的,这里提及只是沧海一粟。处于网络中的系统不可能完全避免来自网络中的风险,因此,应该保持警戒心和良好的习惯,时刻注意相关方面的最新动态,及时知道最新的漏洞,把握最新的技术,把最新、最切实的方案应用到系统上,才能真正保证系统的先进性和安全性。
参考文献:
[1] 隋涛.基于IIS和ASP的网站系统的安全问题[J].情报探索,2006.
[2]易昭湘,聂元铭,杨美眉.专家门诊——ASP开发答疑[M].北京:人民邮电出版社,2004.
[3] 吴明辉,胡煜,窦亮.ASP网络办公及商务应用系统开发实例导航[M]. 北京:人民邮电出版社,2003.
[4] 童爱红,俞海英.ASP动态网页设计实用教程[M]..北京: 清华大学出版社,2007.
[5] 杨大勇.ASP网络开发自学导航[M].北京:机械工业出版社,2007.
[6]李维杰,张华铎. Dreamweaver 8&ASP数据库网站开发简明教程[M].北京:清华大学出版社,2006