经常听说的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 函数用来检查文件是否为图片文件
' 参数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
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
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
接着就可判断后再做文件的上传
所以,在Blog中的一文:
(ASP)文件系统之化境无组件(v2.0)上传
关于upfile.asp的全新内容如下:
<
%@LANGUAGE
=
"
VBSCRIPT
"
CODEPAGE
=
"
936
"
%
>
< ! -- #include file = " upload.inc " -->
< html >
< head >
< title > 文件上传 </ title >
< meta http - equiv = " content-type " content = " text/html;charset=gb2312 " >
</ head >
< body >
< %
on error resume next
dim upload,f_folder,file,formPath,iCount,filename,fileExt,filesizemin,filesizemax
' ******************************************************************
' 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)
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
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
filesizemin = 100
filesizemax = 200 * 1024
set upload = new upload_5xSoft ' 建立上传对象
f_folder = upload.form( " upfilefolder " )
' ********************************列出所有上传文件***************************************************
For each formName in upload.objFile
set file = upload.file(formName)
If file.filesize > 0 then
' ********************************检测文件大小***************************************************
If file.filesize < filesizemin Then
response.write " 你上传的文件太小了 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
ElseIf file.filesize > filesizemax then
response.write " 文件大小超过了 " & filesizemax & " 字节 限制 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
End If
' ********************************检测文件类型****************************************************
fileExt = ucase ( right (file.filename, 4 ))
uploadsuc = false
Forum_upload = " RAR|ZIP|SWF|JPG|PNG|GIF|DOC|TXT|CHM|PDF|ACE|MP3|WMA|WMV|MIDI|AVI|RM|RA|RMVB|MOV|XLS "
Forumupload = split (Forum_upload, " | " )
for i = 0 to ubound (Forumupload)
if fileEXT = " . " & trim (Forumupload(i)) then
uploadsuc = true
exit for
else
uploadsuc = false
end if
next
if uploadsuc = false then
response.write " 文件格式不正确 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
response.end
end if
' ********************************建立文件上传的目录文件夹****************************************
Set upf = Server.CreateObject( " Scripting.FileSystemObject " )
If Err <> 0 Then
Err.Clear
response.write( " 您的服务器不支持FSO " )
response.end
End If
f_type = replace (fileExt, " . " , "" )
f_name = year ( now ) & " - " & month ( now )
If upf.FolderExists(Server.MapPath(f_folder & " / " & f_type & " / " & f_name)) = False Then
If upf.FolderExists(Server.MapPath(f_folder & " / " & f_type)) = False Then
If upf.FolderExists(Server.MapPath(f_folder)) = False Then
upf.CreateFolder Server.MapPath(f_folder)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
Else
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
End If
Else
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
End If
End If
f_ftn = f_folder & " / " & f_type & " / " & f_name
Set upf = Nothing
' ********************************保存上传文件至文件夹*****************************************
randomize
ranNum = int ( 90000 * rnd ) + 10000
filename = f_ftn & " / " & day ( now ) & " - " & ranNum & " - " & file.filename
if TrueStr(filename) = false then
response.write " 非法文件 "
response.end
end if
if file.filesize > filesizemin and file.filesize < filesizemax then
file.SaveAs Server.mappath(filename) ' 保存文件
if f_type = " JPG " or f_type = " GIF " or f_type = " PNG " then
If not CheckFileType(Server.mappath(filename)) then
response.write " 错误的图像格式 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
Set fso = CreateObject ( " Scripting.FileSystemObject " )
Set ficn = fso.GetFile(Server.mappath(filename))
ficn.delete
set ficn = nothing
set fso = nothing
response.end
end if
response.write " <script>parent.cn_bruce.cn_content.value+=''</script> "
ElseIf f_type = " ZIP " or f_type = " RAR " or f_type = " DOC " or f_type = " TXT " then
response.write " <script>parent.cn_bruce.cn_content.value+=' " & filename & " '</script> "
' ElseIf
else
response.write " <script>parent.cn_bruce.cn_content.value+=' " & filename & " '</script> "
end if
iCount = iCount + 1
end if
set file = nothing
end if
next
set upload = nothing ' 删除此对象
response.write (iCount & " 个文件上传成功! <a href=# οnclick=history.go(-1)>继续上传</a> " )
% >
</ body >
</ html >
< ! -- #include file = " upload.inc " -->
< html >
< head >
< title > 文件上传 </ title >
< meta http - equiv = " content-type " content = " text/html;charset=gb2312 " >
</ head >
< body >
< %
on error resume next
dim upload,f_folder,file,formPath,iCount,filename,fileExt,filesizemin,filesizemax
' ******************************************************************
' 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)
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
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
filesizemin = 100
filesizemax = 200 * 1024
set upload = new upload_5xSoft ' 建立上传对象
f_folder = upload.form( " upfilefolder " )
' ********************************列出所有上传文件***************************************************
For each formName in upload.objFile
set file = upload.file(formName)
If file.filesize > 0 then
' ********************************检测文件大小***************************************************
If file.filesize < filesizemin Then
response.write " 你上传的文件太小了 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
ElseIf file.filesize > filesizemax then
response.write " 文件大小超过了 " & filesizemax & " 字节 限制 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
End If
' ********************************检测文件类型****************************************************
fileExt = ucase ( right (file.filename, 4 ))
uploadsuc = false
Forum_upload = " RAR|ZIP|SWF|JPG|PNG|GIF|DOC|TXT|CHM|PDF|ACE|MP3|WMA|WMV|MIDI|AVI|RM|RA|RMVB|MOV|XLS "
Forumupload = split (Forum_upload, " | " )
for i = 0 to ubound (Forumupload)
if fileEXT = " . " & trim (Forumupload(i)) then
uploadsuc = true
exit for
else
uploadsuc = false
end if
next
if uploadsuc = false then
response.write " 文件格式不正确 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
response.end
end if
' ********************************建立文件上传的目录文件夹****************************************
Set upf = Server.CreateObject( " Scripting.FileSystemObject " )
If Err <> 0 Then
Err.Clear
response.write( " 您的服务器不支持FSO " )
response.end
End If
f_type = replace (fileExt, " . " , "" )
f_name = year ( now ) & " - " & month ( now )
If upf.FolderExists(Server.MapPath(f_folder & " / " & f_type & " / " & f_name)) = False Then
If upf.FolderExists(Server.MapPath(f_folder & " / " & f_type)) = False Then
If upf.FolderExists(Server.MapPath(f_folder)) = False Then
upf.CreateFolder Server.MapPath(f_folder)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
Else
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type)
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
End If
Else
upf.CreateFolder Server.MapPath(f_folder & " / " & f_type & " / " & f_name)
End If
End If
f_ftn = f_folder & " / " & f_type & " / " & f_name
Set upf = Nothing
' ********************************保存上传文件至文件夹*****************************************
randomize
ranNum = int ( 90000 * rnd ) + 10000
filename = f_ftn & " / " & day ( now ) & " - " & ranNum & " - " & file.filename
if TrueStr(filename) = false then
response.write " 非法文件 "
response.end
end if
if file.filesize > filesizemin and file.filesize < filesizemax then
file.SaveAs Server.mappath(filename) ' 保存文件
if f_type = " JPG " or f_type = " GIF " or f_type = " PNG " then
If not CheckFileType(Server.mappath(filename)) then
response.write " 错误的图像格式 [ <a href=# οnclick=history.go(-1)>重新上传</a> ] "
Set fso = CreateObject ( " Scripting.FileSystemObject " )
Set ficn = fso.GetFile(Server.mappath(filename))
ficn.delete
set ficn = nothing
set fso = nothing
response.end
end if
response.write " <script>parent.cn_bruce.cn_content.value+=''</script> "
ElseIf f_type = " ZIP " or f_type = " RAR " or f_type = " DOC " or f_type = " TXT " then
response.write " <script>parent.cn_bruce.cn_content.value+=' " & filename & " '</script> "
' ElseIf
else
response.write " <script>parent.cn_bruce.cn_content.value+=' " & filename & " '</script> "
end if
iCount = iCount + 1
end if
set file = nothing
end if
next
set upload = nothing ' 删除此对象
response.write (iCount & " 个文件上传成功! <a href=# οnclick=history.go(-1)>继续上传</a> " )
% >
</ body >
</ html >