解决ASP(图像)上传漏洞的方法

时间:2022-06-01 17:01:49

经常听说的ASP上传漏洞,即是将一些木马文件修改后缀名(修改为图像文件后缀),进行上传。

针对此情况使用下列函数进行辨别:
 


<%
'******************************************************************
'CheckFileType 函数用来检查文件是否为图片文件
'参数filename是本地文件的路径
'如果是文件jpeg,gif,bmp,png图片中的一种,函数返回true,否则返回false
'******************************************************************

const adTypeBinary=1

dim jpg(1):jpg(0)=CByte(&HFF):jpg(1)=CByte(&HD8)
dim bmp(1):bmp(0)=CByte(&H42):bmp(1)=CByte(&H4D)
dim png(3):png(0)=CByte(&H89):png(1)=CByte(&H50):png(2)=CByte(&H4E):png(3)=CByte(&H47)
dim gif(5):gif(0)=CByte(&H47):gif(1)=CByte(&H49):gif(2)=CByte(&H46):gif(3)=CByte(&H39):gif(4)=CByte(&H38):gif(5)=CByte(&H61)

function CheckFileType(filename)
on error resume next
CheckFileType=false
dim fstream,fileExt,stamp,i
fileExt=mid(filename,InStrRev(filename,".")+1)
set fstream=Server.createobject("ADODB.Stream")
fstream.Open
fstream.Type=adTypeBinary
fstream.LoadFromFile filename
fstream.position=0
select case fileExt
case "jpg","jpeg"
stamp=fstream.read(2)
for i=0 to 1
if ascB(MidB(stamp,i+1,1))=jpg(i) then CheckFileType=true else CheckFileType=false
next
case "gif"
stamp=fstream.read(6)
for i=0 to 5
if ascB(MidB(stamp,i+1,1))=gif(i) then CheckFileType=true else CheckFileType=false
next
case "png"
stamp=fstream.read(4)
for i=0 to 3
if ascB(MidB(stamp,i+1,1))=png(i) then CheckFileType=true else CheckFileType=false
next
case "bmp"
stamp=fstream.read(2)
for i=0 to 1
if ascB(MidB(stamp,i+1,1))=bmp(i) then CheckFileType=true else CheckFileType=false
next
end select
fstream.Close
set fseteam=nothing
if err.number<>0 then CheckFileType=false
end function
%>



那么在应用的时候 
CheckFileType(server.mappath("cnbruce.jpg"))
或者
CheckFileType("F:/web/164/images/cnbruce.jpg"))

反正即是检测验证本地物理地址的图像文件类型,返回 true 或 false值

所以这个情况应用在图像上传中,目前的办法是先允许该“伪图像”文件的上传,接着使用以上的自定义函数判断该文件是否符合图像的规范,若是木马伪装的图像文件则FSO删除之,比如:


file.SaveAs Server.mappath(filename) '保存文件
If not CheckFileType(Server.mappath(filename)) then
    response.write "错误的图像格式"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ficn = fso.GetFile(Server.mappath(filename))
    ficn.delete
    set ficn=nothing
    set fso=nothing
    response.end
end if


则是先将文件上传,接着立马使用自定义函数判断文件图像类型的吻合性,FSO做出删除该文件的操作。


ASP上传漏洞还利用"\0"对filepath进行手脚操作
http://www.cnbruce.com/blog/showlog.asp?cat_id=32&log_id=635 

针对这样的情况可使用如下函数


function TrueStr(fileTrue)
str_len=len(fileTrue)
pos=Instr(fileTrue,chr(0))
if pos=0 or pos=str_len then
TrueStr=true
else
TrueStr=false
end if
end function


接着就可判断后再做文件的上传


if TrueStr(filename)=false then
    response.write "非法文件"
    response.end
end if

file.SaveAs Server.mappath(filename)



所以,在Blog中的一文:(ASP)文件系统之化境无组件(v2.0)上传 

关于upfile.asp的全新内容如下:

  1. <%@LANGUAGE="VBSCRIPT" CODEPAGE="936"%>   
  2. <B>处理 SSI 文件时出错</B><BR> 
  3.   
  4. <html>  
  5. <head>  
  6. <title>文件上传</title>  
  7. <meta http-equiv="content-type" content="text/html;charset=gb2312">  
  8. </head>  
  9. <body>  
  10. <%  
  11. on error resume next  
  12. dim upload,f_folder,file,formPath,iCount,filename,fileExt,filesi*,filesizemax  
  13. '******************************************************************  
  14. 'CheckFileType 函数用来检查文件是否为图片文件  
  15. '参数filename是本地文件的路径  
  16. '如果是文件jpeg,gif,bmp,png图片中的一种,函数返回true,否则返回false  
  17. '******************************************************************  
  18. const adTypeBinary=1  
  19.  
  20. dim jpg(1):jpg(0)=CByte(&HFF):jpg(1)=CByte(&HD8)  
  21. dim bmp(1):bmp(0)=CByte(&H42):bmp(1)=CByte(&H4D)  
  22. dim png(3):png(0)=CByte(&H89):png(1)=CByte(&H50):png(2)=CByte(&H4E):png(3)=CByte(&H47)  
  23. dim gif(5):gif(0)=CByte(&H47):gif(1)=CByte(&H49):gif(2)=CByte(&H46):gif(3)=CByte(&H39):gif(4)=CByte(&H38):gif(5)=CByte(&H61)  
  24.  
  25. function CheckFileType(filename)  
  26. CheckFileType=false  
  27. dim fstream,fileExt,stamp,i  
  28. fileExt=mid(filename,InStrRev(filename,".")+1)  
  29. set fstream=Server.createobject("ADODB.Stream")  
  30. fstream.Open  
  31. fstream.Type=adTypeBinary  
  32. fstream.LoadFromFile filename  
  33. fstream.position=0  
  34. select case fileExt  
  35. case "jpg","jpeg"  
  36. stamp=fstream.read(2)  
  37. for i=0 to 1  
  38. if ascB(MidB(stamp,i+1,1))=jpg(i) then CheckFileType=true else CheckFileType=false  
  39. next  
  40. case "gif"  
  41. stamp=fstream.read(6)  
  42. for i=0 to 5  
  43. if ascB(MidB(stamp,i+1,1))=gif(i) then CheckFileType=true else CheckFileType=false  
  44. next  
  45. case "png"  
  46. stamp=fstream.read(4)  
  47. for i=0 to 3  
  48. if ascB(MidB(stamp,i+1,1))=png(i) then CheckFileType=true else CheckFileType=false  
  49. next  
  50. case "bmp"  
  51. stamp=fstream.read(2)  
  52. for i=0 to 1  
  53. if ascB(MidB(stamp,i+1,1))=bmp(i) then CheckFileType=true else CheckFileType=false  
  54. next  
  55. end select  
  56. fstream.Close  
  57. set fseteam=nothing  
  58. if err.number<>0 then CheckFileType=false  
  59. end function  
  60.  
  61. function TrueStr(fileTrue)  
  62.  str_len=len(fileTrue)  
  63.  pos=Instr(fileTrue,chr(0))  
  64.  if pos=0 or pos=str_len then  
  65.  TrueStr=true  
  66.  else  
  67.  TrueStr=false  
  68.  end if  
  69. end function  
  70.  
  71. filesi*=100  
  72. filesizemax=200*1024  
  73. set upload=new upload_5xSoft '建立上传对象  
  74. f_folder=upload.form("upfilefolder")  
  75.  
  76. '********************************列出所有上传文件***************************************************  
  77. For each formName in upload.objFile  
  78. set file=upload.file(formName)  
  79. If file.filesize>0 then  
  80.  
  81.     '********************************检测文件大小***************************************************  
  82.     If file.filesize<filesi* Then  
  83.         response.write "你上传的文件太小了 [ <a href=# onclick=history.go(-1)>重新上传</a> ]"  
  84.     ElseIf file.filesize>filesizemax then  
  85.         response.write "文件大小超过了 "&filesizemax&"字节 限制 [ <a href=# onclick=history.go(-1)>重新上传</a> ]"  
  86.     End If  
  87.  
  88.     '********************************检测文件类型****************************************************  
  89.     fileExt=ucase(right(file.filename,4))  
  90.     uploadsuc=false  
  91.     Forum_upload="RAR|ZIP|SWF|JPG|PNG|GIF|DOC|TXT|CHM|PDF|ACE|MP3|WMA|WMV|MIDI|AVI|RM|RA|RMVB|MOV|XLS"  
  92.     Forumupload=split(Forum_upload,"|")  
  93.     for i=0 to ubound(Forumupload)  
  94.         if fileEXT="."&trim(Forumupload(i)) then  
  95.             uploadsuc=true  
  96.             exit for  
  97.         else  
  98.             uploadsuc=false  
  99.         end if  
  100.     next  
  101.     if uploadsuc=false then  
  102.         response.write "文件格式不正确 [ <a href=# onclick=history.go(-1)>重新上传</a> ]"  
  103.         response.end  
  104.     end if  
  105.  
  106.     '********************************建立文件上传的目录文件夹****************************************  
  107.     Set upf=Server.CreateObject("Scripting.FileSystemObject")  
  108.     If Err<>0 Then  
  109.         Err.Clear  
  110.         response.write("您的服务器不支持FSO")  
  111.         response.end  
  112.     End If  
  113.     f_type= replace(fileExt,".","")  
  114.     f_name= year(now)&"-"&month(now)  
  115.     If upf.FolderExists(Server.MapPath(f_folder&"/"&f_type&"/"&f_name))=False Then  
  116.         If upf.FolderExists(Server.MapPath(f_folder&"/"&f_type))=False Then  
  117.             If upf.FolderExists(Server.MapPath(f_folder))=False Then  
  118.                 upf.CreateFolder Server.MapPath(f_folder)  
  119.                 upf.CreateFolder Server.MapPath(f_folder&"/"&f_type)  
  120.                 upf.CreateFolder Server.MapPath(f_folder&"/"&f_type&"/"&f_name)  
  121.             Else  
  122.                 upf.CreateFolder Server.MapPath(f_folder&"/"&f_type)  
  123.                 upf.CreateFolder Server.MapPath(f_folder&"/"&f_type&"/"&f_name)  
  124.             End If  
  125.         Else  
  126.             upf.CreateFolder Server.MapPath(f_folder&"/"&f_type&"/"&f_name)  
  127.         End If  
  128.     End If  
  129.     f_ftn=f_folder&"/"&f_type&"/"&f_name  
  130.     Set upf=Nothing  
  131.  
  132.     '********************************保存上传文件至文件夹*****************************************  
  133.     randomize  
  134.     ranNum=int(90000*rnd)+10000  
  135.     filename=f_ftn&"/"&day(now)&"-"&ranNum&"-"&file.filename  
  136.     if TrueStr(filename)=false then  
  137.         response.write "非法文件"  
  138.         response.end  
  139.     end if  
  140.     if file.filesize>filesi* and file.filesize<filesizemax then  
  141.     file.SaveAs Server.mappath(filename)  '保存文件  
  142.         if f_type="JPG" or f_type="GIF" or f_type="PNG" then  
  143.             If not CheckFileType(Server.mappath(filename)) then  
  144.             response.write "错误的图像格式  [ <a href=# onclick=history.go(-1)>重新上传</a> ]"  
  145.             Set fso = CreateObject("Scripting.FileSystemObject")  
  146.             Set ficn = fso.GetFile(Server.mappath(filename))  
  147.             ficn.delete  
  148.             set ficn=nothing  
  149.             set fso=nothing  
  150.             response.end  
  151.             end if  
  152.             response.write "<script>parent.cn_bruce.cn_content.value+='[img]"&filename&"[/img]'</script>"  
  153.         ElseIf f_type="ZIP" or f_type="RAR" or f_type="DOC" or f_type="TXT" then  
  154.             response.write "<script>parent.cn_bruce.cn_content.value+='[url]"&filename&"[/url]'</script>"  
  155.         'ElseIf  
  156.         else  
  157.             response.write "<script>parent.cn_bruce.cn_content.value+=' "&filename&" '</script>"  
  158.         end if  
  159.         iCount=iCount+1  
  160.     end if  
  161. set file=nothing  
  162. end if  
  163. next  
  164. set upload=nothing '删除此对象  
  165.  
  166. response.write (iCount&" 个文件上传成功! <a href=# onclick=history.go(-1)>继续上传</a>")  
  167. %>  
  168. </body>  
  169. </html>