- 博客访问: 217398
- 博文数量: 88
- 博客积分: 3020
- 博客等级: 中校
- 技术积分: 707
- 用 户 组: 普通用户
- 注册时间: 2009-02-12 16:56
分类: 网络与安全
2009-06-29 16:53:16
上传漏洞是一个非常恐怖的漏洞,如果你的程序里面有这种漏洞,那么恶意攻击者可以直接向你的服务器上传一个webshell(又称ASP木马、PHP木马等即利用服务器端的文件操作语句写成的动态网页,可以用来编辑你服务器上的文件),从而控制你的网站。
那么,上传漏洞是怎么样一种漏洞呢。
一
般对于上传漏洞的概念定义如下:由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本
文件。打个比方来说,如果你使用windows服务器并且以asp作为服务器端的动态网站环境,那么在你的网站的上传功能处,就一定不能让用户上传asp
类型的文件,否则他上传一个webshell,你服务器上的文件就可以被他任意更改了。
相对于我前面所谈到的跨站漏洞,不得不承认,上传漏洞对于网站的危害是致命的,那么,上传漏洞是如何产生的呢。
我
们知道,在WEB中进行文件上传的原理是通过将表单设为multipart/form-data,同时加入文件域,而后通过HTTP协议将文件内容发送到
服务器,服务器端读取这个分段(multipart)的数据信息,并将其中的文件内容提取出来并保存的。通常,在进行文件保存的时候,服务器端会读取文件
的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个文件名(为了防止重复),并且加上原始文件的扩展名来保存到服务器上。
慢着,就在这个扩展名这里就出了问题了,究竟是什么问题呢,我们开启一个新的章节来详细说说,上传漏洞的几种形式和各自的防护方法。
上传漏洞的几种形式及其防护
第一、 完全没有处理。
完
全没有处理的情况不用我说,看名字想必大家都能够了解,这种情况是程序员在编写上传处理程序时,没有对客户端上传的文件进行任何的检测,而是直接按照其原
始扩展名将其保存在服务器上,这是完全没有安全意识的做法,也是这种漏洞的最低级形式,一般来说这种漏洞很少出现了,程序员或多或少的都会进行一些安全方
面的检查。
第二、 将asp等字符替换。
我们再看一些程序员进阶的做法,程序员知道asp这样的文件名是危险的,因此他写了个函数,对获得的文件扩展名进行过滤,如:
Function checkExtName(strExtName)
strExtName = lCase(strExtName) '转换为小写
strExtName = Replace(strExtName,"asp","") '替换asp为空
strExtName = Replace(strExtName,"asa","") '替换asa为空
checkExtName = strExtName
End Function
使用这种方式,程序员本意是将用户提交的文件的扩展名中的“危险字符”替换为空,从而达到安全保存文件的目的。粗一看,按照这种方式,用户提交的asp文件因为其扩展名asp被替换为空,因而无法保存,但是仔细想想,这种方法并不是完全安全的。
突破的方法很简单,只要我将原来的webshell的asp扩展名改为aaspasp就可以了,此扩展名经过checkExtName函数处理后,将变为asp,即a和sp中间的asp三个字符被替换掉了,但是最终的扩展名仍然是asp。
因此这种方法是不安全的。如何改进呢,请接着往下看。
第三、 不足的黑名单过滤。
知道了上面的替换漏洞,你可能已经知道如何更进一步了,对了,那就是直接比对扩展名是否为asp或者asa,这时你可能采用了下面的程序:
Function checkExtName(strExtName)
strExtName = lCase(strExtName) '转换为小写
If strExtName = "asp" Then
checkExtName = False
Exit Function
ElseIf strExtName = "asa" Then
checkExtName = False
Exit Function
End If
checkExtName = True
End Function
你使用了这个程序来保证asp或者asa文件在检测时是非法的,这也称为黑名单过滤法,那么,这种方法有什么缺点呢。
黑
名单过滤法是一种被动防御方法,你只可以将你知道的危险的扩展名加以过滤,而实施上,你可能不知道有某些类型的文件是危险的,就拿上面这段程序来说吧,你
认为asp或者asa类型的文件可以在服务器端被当作动态脚本执行,事实上,在windows2000版本的IIS中,默认也对cer文件开启了动态脚本
执行的处理,而如果此时你不知道,那么将会出现问题。
实际上,不只是被当作动态网页执行的文件类型有危险,被当作SSI处理的文件类型也有危险,
例如shtml、stm等,这种类型的文件可以通过在其代码中加入语句的方式,将你的数据库链接文件引入到当前的文件中,而此时通过浏览器访问这样的文件并查看源代码,你的
conn.asp文件源代码就泄露了,入侵者可以通过这个文件的内容找到你的数据库存放路径或者数据库服务器的链接密码等信息,这也是非常危险的。
那
么,如果你真的要把上面我所提到的文件都加入黑名单,就安全了吗,也不一定。现在很多服务器都开启了对asp和php的双支持,那么,我是不是可以上传
php版的webshell呢,所以说,黑名单这种被动防御是不太好的,因此我建议你使用白名单的方法,改进上面的函数,例如你要上传图片,那么就检测扩
展名是否是bmp、jpg、jpeg、gif、png之一,如果不在这个白名单内,都算作非法的扩展名,这样会安全很多。
第四、 表单中传递文件保存目录。
上
面的这些操作可以保证文件扩展名这里是绝对安全的,但是有很多程序,譬如早期的动网论坛,将文件的保存路径以隐藏域的方式放在上传文件的表单当中(譬如用
户头像上传到UserFace文件夹中,那么就有一个名为filepath的隐藏域,值为userface),并且在上传时通过链接字符串的形式生成文件
的保存路径,这种方法也引发了漏洞。
FormPath=Upload.form("filepath")
For Each formName in Upload.file ''列出所有上传了的文件
Set File=Upload.file(formName) ''生成一个文件对象
If file.filesize<10 Then
Response.Write "请先选择你要上传的图片 [ 重新上传 ]"
Response.Write "