关于补ASP上传漏洞,检测JPG文件内容

最近网站被上传传马,十有八九是从ASP无组件上传漏洞进来的。经过一翻苦苦研究,觉得应该对上传后的图片附件进行内容检测,如果发现是伪装图片,立即删除。

网上也找到了一些检测JPG的代码,但是我的附件上传允许文件类型有:JPG、RAR,RAR就被误为不合法了

发这个贴子,是想提两个问题的,希望大家能分别回答:

1、我想知道,检测JPG内容的原理,是不是就像我们用记事本打开这张JPG图片看到的乱码一样,然后检测有没有危险的代码,从而判断是否图片文件??如果是的话,检测里面有没有 <%%>这对符号不就行了吗

2、就是求一段好的无错的检测是否JPG、RAR文件的过滤代码了

---------------------------------------------

发表于:2008-05-29 22:36:3810楼 得分:10
rar文件前3个字符是Rar
gif文件前3个字符是GIF
jpg文件换行符后有JFIF标志


发表于:2008-05-30 04:09:5512楼 得分:10
ASP 上传漏洞, 针对文件内容做检测是一个方向. 但这方向不对.

正确的方向.是要针对ASP对\0字符处理漏洞.

针对这个问题. 因为我不太懂ASP.. 在200几年来着,写了一篇关于动网上传漏洞的补救..你GOOGLE一下,应该会搜索到.

补救的算法很烂..只要知道原理.补救还是有效的...

针对技术共享的问题..个人觉得应该有开源共享的精神..对于系统漏洞.应该在第一时间内将漏洞公布(个人喜好)


发表于:2008-05-30 09:51:1114楼 得分:0
为什么不从服务器安全的方向想想呢?
把上传目录的脚本执行权限设置成无
传了也执行不了


发表于:2008-05-30 10:15:1517楼 得分:10
而且这个上传漏洞与什么语言无关!
ASP,PHP,JSP,NET都一样
一样存在这个问题,也许2003服务器现在安全多了,不像以前,JPG图片木马可以运行,以前发现这个漏洞2003服务器可以运行图片木马时,就研究补了这个上传图片木马的漏洞,不过现在2003服务器都打了补丁,不允许运行了
但还有少部分服务器还是可以经过改造的图片木马!

当然很多也没有太多人会利用改造的图片木马

前不久我也测试过不少服务器,基本都不允许图片木马运行了,当然你如果还有别的漏洞,那么这个图片木马又是一个危险

既然你已经接触和意识到了这个,相信你也能想出来!


发表于:2008-05-30 10:21:3618楼 得分:10
仔细阅读一下关于 2003-2004年被暴的 动网上传漏洞.

\0字符

在ASP中处理不当所致.

也就是说上传的HTTP包中 对于文件名 "abc.asp\0.jpg" 在ASP中,服务器得到的文件名是 abc.asp 而不是 abc.asp.jpg 导致写文件是,文件名被命名为 abc.asp

PHP中做过测试,无此现象.

具体的请做测试后,再发言.

另赋以前的丑作:

http://www.google.com/search?hl=en&q=%E5%8A%A8%E7%BD%91%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%E8%A1%A5%E6%95%91

对ASP不太喜欢,请勿笑话,呵呵.


呵呵,你对黑不够理解,这种abc.asp\0.jpg改一个后缀的漏洞算什么??
图片木马不是指的这个
而是指的abc.jpg就这样的,但实际上他的内容是可执行代码!!

经过改造的,以前在补丁没有出来以前,直接在2003服务器远行

最开始是
<%
str="nihao"
response.write str
%>这样的代码保存为abc.jpg这样的放到2003服务器站点下可以直接运行
补丁出来以后再对以上代码作一些改造,还可以运行

不管代码是什么
<?php
echo "nihao"
?>
保存为abc.jpg一样可以运行
所以说,还有很多很多改造的方法,甚至可以把一个整页的代码放都可以


你以为上传漏洞就只是文件名 "abc.asp\0.jpg"你这种图片木马吗?这种东西实在太简单,一个split分割取第一个是不是图片格式就可以过滤掉
没什么好想的

你去GOOGLE一下,看看2003服务器以前是不是有这么一个漏洞!
是不是可以直接运行包含运行代码的abc.jpg文件
意思就是说,把abc.jpg里面包含的运行代码解析成了网页形式,并不是图片也不是打叉

道高一尺,魔高一丈,没有太安全的,不能一劳永逸,要经常维护,针对特殊漏洞做特殊处理

+展开
-VBScript
Private Function BinVal(Byval bin)
        Dim ImageSize,i
        ImageSize = 0
        For i = lenb(bin) To 1 Step -1
            ImageSize = ImageSize *256 + ASCB(Midb(bin,i,1))
        Next
        BinVal = ImageSize
    End Function

    Private Function BinVal2(Byval bin)
        Dim ImageSize,i
        ImageSize = 0
        For i = 1 To Lenb(bin)
            ImageSize = ImageSize *256 + ASCB(Midb(bin,i,1))
        Next
        BinVal2 = ImageSize
    End Function

    Private Function GetImageSize() 
        Dim ImageSize(2),bFlag
        bFlag = oUpFileStream.Read(3)

        Select Case Hex(BinVal(bFlag))
            Case "4E5089":
                oUpFileStream.Read(15)
                ImageSize(0) = "png"
                ImageSize(1) = BinVal2(oUpFileStream.Read(2))
                oUpFileStream.Read(2)
                ImageSize(2) = BinVal2(oUpFileStream.Read(2))
            Case "464947":
                oUpFileStream.Read(3)
                ImageSize(0) = "gif"
                ImageSize(1) = BinVal(oUpFileStream.Read(2))
                ImageSize(2) = BinVal(oUpFileStream.Read(2))
            Case "535746":
                Dim BinData,sConv,nBits
                oUpFileStream.Read(5)
                BinData = oUpFileStream.Read(1)
                sConv = Num2Str(ASCB(BinData),2 ,8)
                nBits = Str2Num(Left(sConv,5),2)
                sConv = Mid(sConv,6)
                While(Len(sConv)                    BinData = oUpFileStream.Read(1)
                    sConv = sConv&Num2Str(ASCB(BinData),2 ,8)
                Wend
                ImageSize(0) = "swf"
                ImageSize(1) = Int(ABS(Str2Num(Mid(sConv,1*nBits+1,nBits),2)-Str2Num(Mid(sConv,0*nBits+1,nBits),2))/20)
                ImageSize(2) = Int(ABS(Str2Num(Mid(sConv,3*nBits+1,nBits),2)-Str2Num(Mid(sConv,2*nBits+1,nBits),2))/20)
            Case "535743":'flashmx
                ImageSize(0) = "swf"
                ImageSize(1) = 0
                ImageSize(2) = 0
            Case "FFD8FF":
                Dim p1
                Do 
                    Do: p1 = BinVal(oUpFileStream.Read(1)): Loop While p1 = 255 And Not oUpFileStream.EOS
                    If p1>191 and p1<196 Then Exit Do Else oUpFileStream.Read(BinVal2(oUpFileStream.Read(2))-2)
                    Do:p1 = BinVal(oUpFileStream.Read(1)):Loop While p1<255 And Not oUpFileStream.EOS
                    Loop While True
                    oUpFileStream.Read(3)
                    ImageSize(0) = "jpg"
                    ImageSize(2) = BinVal2(oUpFileStream.Read(2))
                    ImageSize(1) = BinVal2(oUpFileStream.Read(2))
            Case Else:
                If Left(Bin2Str(bFlag),2) = "BM" Then
                    oUpFileStream.Read(15)
                    ImageSize(0) = "bmp"
                    ImageSize(1) = BinVal(oUpFileStream.Read(4))
                    ImageSize(2) = BinVal(oUpFileStream.Read(4))
                Else
                    ImageSize(0) = "(UNKNOWN)"
                End If
        End Select
        GetImagesize = ImageSize
    End Function



据说只用 上传白名单 和 自动生成上传文件名 就可以避免。。。

能操作服务器直接设置脚本执行权限就最好了。。。

发表于:2008-05-30 15:05:3329楼 得分:0
再说,他不一定要在你上传目录执行这个,通过你别的漏洞,比如还原数据库漏洞,或者一些网站还有文件管理的功能,等等这些漏洞移走


发表于:2008-05-30 15:08:1230楼 得分:10
据说只用 上传白名单 和 自动生成上传文件名 就可以避免。。。

这个也不能完全避免

自动生成文件名只是让人一时找不到文件罢了

上传白名单?
指的什么?限制上传IP?
还是限制上传类型?
限制上传IP不切实际,限制上传类型都没用


不管怎么说你上传的东西
程序里肯定可以让你保存到某个目录,不管你用什么文件名(含特殊字符的文件名也行),程序不管
程序自动生成一个文件名+允许的后缀。不用原来的文件名,这样可以有效的防止保存到其它目录


你第一次总是先要执行你上传的木马吧(该目录无脚本执行权限)
至于你上面说的那是后话,你总该把木马放出来先吧。


发表于:2008-05-30 17:30:3434楼 得分:0
用LoadPicture检测吧,它是vbs自带的一个函数,从VB的LoadPicture扩展出来的,虽然功能不多,但是在ASP下够用了
+展开
-VBScript
Dim img 
Set img = LoadPicture("D:\1.jpg")'如果不是图片文件,这里就出错了,用On Error Resume Next来捕获错误 
Set img = Nothing 

Public Function GetImageSize(ByVal strPath) 
    On Error Resume Next 
    Dim img 
    Set img = LoadPicture(strPath) 
    If Err.Number Then 
        Response.Write "图片装入错误:" & Err.Description 
        Err.Clear 
        GetImageSize = Array(0, 0) 
        Exit Function 
    End If 
    GetImageSize = Array(img.Width, img.Height) 
    Set img = Nothing 
End Function 

GetImageSize "D:\1.jpg" 



文件名我不管你是什么
只要你后缀名是JPG就可以了,是图片就可以了,除非你服务器设置上传的东西都统一使用一种执行不了的后缀名
但是这样,图片显示又是一个大问题
而且上传的不在乎是什么文件名,只在乎允许不允许运行,这个图片木马我不一定是脚本的,普通的一个HTML就可以,不需要脚本!而且就算是这种脚本的,可以比如还原数据库漏洞,或者一些网站还有文件管理的功能,等等这些漏洞移走。移到允许执行脚本的目录
除非不允许上传非正常的图片,也就是楼主说的检测JPG文件内容,而你们一直都只在强调一个后缀名含与不含有特殊字符!
上传漏洞要最彻底的话就是不允许上传非正常文件

现在也有人使用监控软件,监控上传的是否正常文件

也有不少站在用


发表于:2008-05-30 17:59:2939楼 得分:0
其实不用对这些判断的,只要你在服务器设置上传的文件不执行脚本,我看你的木马啥运行


发表于:2008-05-30 18:41:3840楼 得分:0
我还是不太明白的,我试过在2003上将asp改成jpg,结果服务器是当纯HTML来执行的,对 <%%>里的代码并不加以理会。虽然不是我想像的出一个红叉。但也算是不是太笨。个人感觉这些个漏洞都是些愚蠢透顶的系统bug. 系统有漏洞,那真是没救了,再怎么小心都不行。


+展开
-VBScript
function IsImgFile(sFileName) 
        const adTypeBinary=1 
        dim return 
        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) 
        
        on error resume next 
        
        return=false 
        dim fstream,fileExt,stamp,i 
        '得到文件后缀并转化为小写 
        FileExt = LCase(GetFileExt(sFileName)) 
        '如果文件后缀为 jpg,jpeg,bmp,gif,png 中的任一种 
        '则执行真实图片判断 
        If strInString(FileExt,"jpg|jpeg|bmp|gif|png")=true then 
            Set fstream=Server.createobject("ADODB.Stream"
            fstream.Open 
            fstream.Type=adTypeBinary 
            fstream.LoadFromFile sFileName 
            fstream.position=0 
            select case LCase(FileExt) 
            case "jpg","jpeg" 
                stamp=fstream.read(2) 
                for i=0 to 1 
                    If ascB(MidB(stamp,i+1,1))=jpg(i) then return=true else return=false 
                next 
            case "gif" 
                stamp=fstream.read(6) 
                for i=0 to 5 
                    If ascB(MidB(stamp,i+1,1))=gif(i) then return=true else return=false 
                next 
            case "png" 
                stamp=fstream.read(4) 
                for i=0 to 3 
                    If ascB(MidB(stamp,i+1,1))=png(i) then return=true else return=false 
                next 
            case "bmp" 
                stamp=fstream.read(2) 
                for i=0 to 1 
                    If ascB(MidB(stamp,i+1,1))=bmp(i) then return=true else return=false 
                next 
            End select 
            
            fstream.Close 
            Set fseteam=nothing 
            If err.number <>0 then return = false 
        else 
            return = true 
        End If 
        IsImgFile = return 
    End function 
 

发表于:2008-05-30 17:41:5835楼 得分:0
修正一个,如果要正确取到尺寸,要除以26.46,搞不明白为什么是26.46
...
GetImageSize = Array(Round(img.Width / 26.46), Round(img.Height / 26.46))
...






加支付宝好友偷能量挖...


评论(0)网络
阅读(155)喜欢(0)Asp/VBScript