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

本文介绍了一种ASP图像上传漏洞的防范方法,通过自定义函数CheckFileType检查上传文件的真正类型,确保只有真正的图像文件才能上传成功。同时,介绍了如何避免字符的路径穿越攻击。

经常听说的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.LoadFromFilefilename
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
endfunction
%
>


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

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

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


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


所以,在Blog中的一文:
(ASP)文件系统之化境无组件(v2.0)上传
关于upfile.asp的全新内容如下:

< %@LANGUAGE = " VBSCRIPT " CODEPAGE = " 936 " % >
< ! -- #includefile = " upload.inc " -->
< html >
< head >
< title > 文件上传 </ title >
< metahttp - 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.LoadFromFilefilename
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
endfunction

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
endfunction

filesizemin
= 100
filesizemax
= 200 * 1024
set upload = new upload_5xSoft ' 建立上传对象
f_folder = upload.form( " upfilefolder " )

' ********************************列出所有上传文件***************************************************
For each formNameinupload.objFile
set file = upload.file(formName)
If file.filesize > 0 then

' ********************************检测文件大小***************************************************
If file.filesize < filesizemin Then
response.write
" 你上传的文件太小了 [<ahref=#onclick=history.go(-1)>重新上传</a>] "
ElseIf file.filesize > filesizemax then
response.write
" 文件大小超过了 " & filesizemax & " 字节限制 [<ahref=#onclick=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
" 文件格式不正确 [<ahref=#onclick=history.go(-1)>重新上传</a>] "
response.end
end if

'
### ASP 文件上传漏洞的安全性分析 文件上传功能如果实现不当,可能会成为严重的安全隐患。对于ASP环境下的文件上传漏洞而言,主要风险在于攻击者能够通过此途径向服务器植入恶意脚本或程序,进而取得对系统的控制权[^1]。 #### 检查与验证机制的重要性 确保文件类型的合法性至关重要。应采用白名单策略来限定允许上传的文件类型,而非黑名单方式阻止特定扩展名。例如,在处理图像类资源时只接受`.jpg`、`.png`等常见格式,并且要防止用户绕过简单的MIME类型检测手段[^3]。 #### 输入清理与编码转换 当接收到来自客户端的数据流之后,应当对其进行彻底清洗并实施必要的字符转义操作。这有助于抵御试图嵌入HTML标签或其他潜在危险代码的行为。特别是针对Windows平台下特有的路径解析特性——即系统会忽略多余的`.`符号作为分隔符的情况,开发人员需格外小心以避免被利用这一点来进行攻击尝试[^4]。 ```asp ' 假设这是用于保存上载图片的功能片段 Dim allowedExtensions : Set allowedExtensions = Server.CreateObject("Scripting.Dictionary") allowedExtensions.Add ".jpg", "" allowedExtensions.Add ".jpeg", "" allowedExtensions.Add ".gif", "" allowedExtensions.Add ".png", "" Function IsAllowedFileExtension(fileName) Dim ext, result ext = LCase(Mid(fileName, InStrRev(fileName, "."))) If Len(ext) > 0 Then result = CBool(allowedExtensions.Exists(ext)) Else result = False End If IsAllowedFileExtension = result End Function ``` 上述代码展示了如何创建一个字典对象用来存储许可的文件后缀列表,并定义函数判断传入名称是否属于这些合法类别之一。实际应用中还应该考虑更多细节比如大小写敏感度以及多级目录结构等问题。 #### 存储位置隔离 为了避免任何可能存在的执行权限滥用情况发生,建议将所有由外部提交过来的内容单独存放在专用区域内,远离应用程序根目录及其子文件夹之外的位置。同时设置恰当读取/写入属性限制,仅授予最低限度所需的操作权利给相关服务进程账户。 #### 日志记录与监控审计 建立健全的日志体系可以帮助及时发现异常活动迹象。每当有新的文档加入时都应在后台留下相应痕迹供后续审查;定期查看这些日志条目并与正常模式对比分析,以便尽早识别可疑行为并采取适当行动加以遏制。 #### 使用安全框架和库 借助成熟的第三方组件往往能简化很多复杂逻辑的设计工作量同时也提高了整体防护水平。选择那些经过广泛测试具备良好口碑的产品集成进来,如OWASP ESAPI (Enterprise Security API),它提供了多种保护措施包括但不限于输入验证、输出编码等功能模块支持。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值