web上传漏洞+暴库
----从源头说起
ivory
isno@qq.com
提到脚本攻击,首当其冲的当然是注入和跨站了。注入和跨站简直防不胜防,利用的手法非常简单,这足以让正在学ipc$入侵的朋友们轻松的黑掉一个大站;而且牛人们也开发了各种各样的工具,让攻击变得更傻瓜化。当这两个漏洞还没走到尽头,又惊现三个漏洞:web上传和暴库、旁注,又给脚本攻击开辟了一块新的空间,一时间黑站,挂马,刷装备变得如此容易。这却让菜鸟很迷茫,只有一味的利用工具去效仿,却全然不知道原理。这是不对的,正所谓:物有本末,事有终始,知所先后,则近道矣。
一:web上传漏洞
饮水思源,让时钟倒退到 2004年5月7日 ,大部分人还在梦乡的时候,动网主站上突然出现一个大猪头,那就是上传漏洞刚暴出的时候,漏洞非常之严重,用小猪的话说是DVBBS7.0 SP2以下通杀。刚开始大家都不知道漏洞是怎么样的,所以就进行了很多的猜测,其中最有道理的猜测是逢源的理论:“windows在NTFS下,文件名长度最长是256个字符,多余的字符将自动把后面的舍去,只要我们构造一个长的文件名(aa......252个a....a.asp.jpg),这样可以饶过动网的上传检测,而且windows接受到这个文件名后会自动把后面的.jpg舍去,这样就上传了一个(aa.....252个a....a.asp)这样一个木马到服务器上”。但是一段时间后证明这个理论不正确,而同时54nb率先公布了猪蛋儿利用的漏洞:实际上是动网利用的“无组件上传”对用户提交的变量过滤不严格。
#由于篇幅问题,无组件上传有漏洞的文件附在光盘里。
关键地方就是在:
1. fileExt=lcase(file.FileExt)
if CheckFileExt(fileEXT)=false then
response.write "文件格式不正确 [ <a href=# οnclick=history.go(-1)>重新上传</a> ]"
response.end
2. ranNum=int(90000*rnd)+10000
filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt
if file.FileSize>0 then ''如果 FileSize > 0 说明有文件数据
file.SaveToFile Server.mappath(filename) ''保存文件
所以有两个难题,第一个是检测文件格式的,用后缀来判断,第二个是真正的上传并更名保存。所以主要是2里面要动点脑筋,而除formPath以后全部都不可用户提交的,对提交文件的类型做了限制,显然想直接上传ASP文件是不可行的.但是我们来看一下做为后辍的依据从哪里。
找到reg_upload.asp文件:
<form name="form" method="post" action="upfile.asp" enctype="multipart/form-data" >
<input type="hidden" name="filepath" value="uploadFace">
<input type="hidden" name="act" value="upload">
<input type="file" name="file1">
<input type="hidden" name="fname">
<input type="submit" name="Submit" value="上传" οnclick="fname.value=file1.value,parent.document.forms[0].Submit.disabled=true,
parent.document.forms[0].Submit2.disabled=true;">
</form>
所以我们知道是从file1和fname得来的!好,这里清楚了,回头再看看2中的关键句子:
filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt
前面提到过这里我们能修改只有formPath,这里很重要,我们知道:在计算机中检测字符串的关键就是看是否碰到'/0'字符,如果是,则认为字符串结束了.也就是说我们在构造上传文件保存路径时,只要欺骗计算机,让他认为类似uploadface/sec.asp,这样的路径参数已经结束了,这样,后面一连串的时间字符我们都可以不要,从而达到直接将文件保存为我们定义的文件名的目的。我们要做的是在构造的数据包中,将表单中的filepath改成类似uploadface/sec.asp'/0'的字符串然后发送出去就行了。
至于'/0'怎么构造呢,我用UltraEdit将后面添加一个hex码为00的字符就可以了,然后就可以抓包上传了,由于文章主要是讲原理,所以怎么抓包和上传就省略了。
其实就是这么简单的,现在很多所谓“变形”的上传其实基本理论还是上面分析的那个。武学之道固然浩瀚如海,可是百变不离其宗,一切武功修为以内功为主,如果内功不深,再神奇奥秘的招式也没有用。
二:暴库
既然要从源头说起,这里就要顺便正名一下:最早发现暴库缺陷是是我本人,也就是以前在x档案上叫sohu的MM。
#我的文章“sohu的作品”,还有sniper以前在《黑客x档案2004.2》上登过的文章“你藏好了吗?轻松揪出数据库”也附在光盘中。当时参与讨论的有怪狗、iceyes、sniper。后来证明了我们的想法是错误的,其实漏洞不在editer.asp中,而在于conn.asp,而这一切都是巧合,但是这确实是暴库的雏形。
后来牛人们就研究了% 5C 暴库法,这也是最简单而且有效的方法,结合我的错误思路一起分析一下暴库法的原理:
首先,“%5c”暴库法并不是网站本身的漏洞,而是利用了IIS解码方式中的一个特征,如果IIS安全设置不周全,而网页设计者在脚本编写中未考虑到IIS的这个特征,% 5C 暴库就会出现。
“%5C”它实际上是“/”的十六进制代码。在电脑中,它们是同一个东西,但在url中提交“/”和“%5c”却会产生不同的结果。 比如我们提交这两个url:
/sec/sec.asp
/sec/sec.asp
IE会自动把“/”转变成“/”,但是当我们把“/”换成十六进制写法“%5c”时,IE却不会对此进行转换。所以url中的“%5c”被原样提交了。当IIS收到并做出解析时,又会进行再一次的编码:将% 5c 还原成“/”。这样,IIS中网址的相对路径无形中变成了“/sec/conn.asp”。
既然是暴库,所以我们再来看看一般conn.asp是怎么写的(针对access):
<%
dim Sql
dim dbpath
set Sql=server.createobject("adodb.connection")
DBPath = Server.MapPath("data/admin.mdb") 'Server.MapPath方法的作用是将网站中的相对路径转变成物理上的绝对路径。
Sql.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & DBPath
%>
好,我们假设网站:http://127.0.0.1的根目录为:“c:/sec/”,漏洞目录为:“c:/sec/ld/”,数据库为:“c:/sec/ld/data/admin.mdb” conn.asp为:“c:/sec/ld/conn.asp”,记住这些目录标识:“/”是在服务器上的。
对于conn.asp来说,当Server.MapPath方法将相对路径转为真实路径时,它实际是两个路径加在一起得到真实路径的:
第一部分: 网页目前执行时所在的相对路径,也就是从网站物理根目录起的相对路径,这里conn.asp处在从根目录起的“/ld/”下。
第二部分: 调用的数据库的相对路径是data/admin.mdb。
最后得到从根目录起的完整相对路径:“/ld/data/admin.mdb”。
当我们提交一个象http://127.0.0.1/ld%5Cconn.asp的url来调用数据库时:
第一部分: 得到的将是:“/ld/”
第二部分 :再加上数据库得到的是:“/ld/data/admin.mdb”。
而在IIS中,“/”和“/”代表着不同的意义,遇到了“/”时,认为它已到了根目录所在的物理路径,不再往上解析,于是网站的完整相对路径变成了:“/data/admin.mdb”,可以理解为“根目录/data/admin.mdb”。IIS却找不到这个数据库,这样就愚弄了IIS,搬起石头砸自己的脚,没办法,只好报错:
Microsoft JET Database Engine 错误 '80004005'
'C:/sec/data/admin.mdb'不是一个有效的路径。
其实很多朋友问,得到数据库位置有什么用?我这里简单的说一下用法:
如果数据库可下,把数据库得到后,可以得到一些密码。
如果数据库不可下,一般应该是asp、asa(一部分这样的后缀还可下,如果不让下,可以在数据库中添加一个表nodown,然后写入一个字段:[<%='z'-1]即可”)这样更好办了,直接写木马,恩哼。。。
其实防范方法很简单,在conn.asp中前面加一句:On Error Resume Next即可。
还未登刊,请不要到处转载!