网站地图    收藏   

主页 > 后端 > 网站安全 >

[代码分析]FCKEditor 2.6.8 ASP Version File Upload Protect

来源:自学PHP网    时间:2015-04-17 11:59 作者: 阅读:

[导读] 今天在论坛看见一童鞋发关于fck上传漏洞的总结,这个说实话百度很多,但是他文中提到了关于fckeditor 2.6.8 asp的一个上传绕过http://www.exploit-db.com/exploits/23005/ ! 在exploit-db上只有他的一...

   今天在论坛看见一童鞋发关于fck上传漏洞的总结,这个说实话百度很多,但是他文中提到了关于fckeditor 2.6.8 asp的一个上传绕过http://www.exploit-db.com/exploits/23005/ !
    在exploit-db上只有他的一个利用视频和修复建议,没有具体的代码分析,于是乎我百度了下,大多都是直接转载的exploit-db的内容,基本没有代码分析过程!
    于是抱着知其然更需知其所以然的态度,看了下代码。
=================================================
001 '漏洞文件:editor/filemanager/connectors/asp/commands.asp
002 '漏洞函数:
003
004 Sub FileUpload( resourceType, currentFolder, sCommand )
005    Dim oUploader
006    Set oUploader = New NetRube_Upload
007    oUploader.MaxSize   = 0
008    oUploader.Allowed   = ConfigAllowedExtensions.Item( resourceType )
009    oUploader.Denied    = ConfigDeniedExtensions.Item( resourceType )
010    oUploader.HtmlExtensions = ConfigHtmlExtensions
011    oUploader.GetData
012    Dim sErrorNumber
013    sErrorNumber = "0"
014    Dim sFileName, sOriginalFileName, sExtension
015    sFileName = ""
016    If oUploader.ErrNum > 0 Then
017        sErrorNumber = "202"
018    Else
019        ' Map the virtual path to the local server path.
020        Dim sServerDir
021        sServerDir = ServerMapFolder( resourceType, currentFolder, sCommand ) '获取保存文件路径
022        Dim oFSO
023        Set oFSO = Server.CreateObject( "Scripting.FileSystemObject" )
024        if not (oFSO.FolderExists( sServerDir ) ) then '判断文件夹是否存在
025            sErrorNumber = "102"
026        else
027            ' Get the uploaded file name.
028            sFileName   = oUploader.File( "NewFile" ).Name '获取上传文件名(包含后缀)
029            sExtension  = oUploader.File( "NewFile" ).Ext  '获取上传文件后缀(获取方式是文件名倒数第一个点开始的后面的字符)
030            sFileName = SanitizeFileName( sFileName ) '对文件名进行处理,处理方式见文章下面的相关函数
031            sOriginalFileName = sFileName
032            Dim iCounter
033            iCounter = 0
034 '*******************************************************************
035            Do While ( True )
036                Dim sFilePath
037                sFilePath = CombineLocalPaths(sServerDir, sFileName) '把文件路径和文件名合在一起
038                If ( oFSO.FileExists( sFilePath ) ) Then
039                    iCounter = iCounter + 1
040                    sFileName = RemoveExtension( sOriginalFileName ) & "(" & iCounter & ")." & sExtension 
041                                        '漏洞关键点 sFileName
042                    sErrorNumber = "201"
043                Else
044                    oUploader.SaveAs "NewFile", sFilePath
045                    If oUploader.ErrNum > 0 Then sErrorNumber = "202"
046                    Exit Do
047                End If
048            Loop
049 '*********************************************************************
050 '以上部分是一个循环,当sFilePath不存在时,就直接进入else中调用类中oUploader.SaveAs保存文件!这个过程就是我们第一次
051 '上传时的代码执行流程,在第一个流程中我们sFilePath变量是sServerDir和sFileName两个变量合成的,此时的sFileName是
052 '经过 SanitizeFileName()函数处理过后的变量,而当我们再次上传同名文件时,会进入if流程这个时候的sFileName将是用
053 'sExtension的后缀,此时的sFileName将在下次循环中和sServerDir一起合成sFilePath,因此第二次上传的后缀是没有经过处理的
054 '然后直接带入oUploader.SaveAs中进行保存,接下来看下oUploader.SaveAs保存文件和oUploader.File( "NewFile" ).Ext后缀获取
055 '的代码流程。
056 '*********************************************************************
057        end if
058    End If
059    Set oUploader   = Nothing
060    dim sFileUrl
061    sFileUrl = CombinePaths( GetResourceTypePath( resourceType, sCommand ) , currentFolder )
062    sFileUrl = CombinePaths( sFileUrl, sFileName )
063    If ( sErrorNumber = "0" or sErrorNumber = "201" ) then
064        SendUploadResults sErrorNumber, sFileUrl, sFileName, ""
065    Else
066        SendUploadResults sErrorNumber, "", "", ""
067    End If
068 End Sub
069
070 相关函数:
071 --------------------------------------------
072 function SanitizeFileName( sNewFileName ) '检测文件名函数,用正则替换文件名中的特殊字符然后替换为下划线
073    Dim oRegex
074    Set oRegex = New RegExp
075    oRegex.Global   = True
076    if ( ConfigForceSingleExtension = True ) then
077        oRegex.Pattern = "\.(?![^.]*$)"
078        sNewFileName = oRegex.Replace( sNewFileName, "_" )
079    end if
080    'remove \ / | : ? *  " < > and control characters
081    oRegex.Pattern = "(\\|\/|\||:|\;|\?|\*|""|\<|\>|[\u0000-\u001F]|\u007F)"
082    SanitizeFileName = oRegex.Replace( sNewFileName, "_" )
083    Set oRegex = Nothing
084 end function
085 --------------------------------------------
086 Function RemoveExtension( fileName )
087    RemoveExtension = Left( fileName, InStrRev( fileName, "." ) - 1 )'InStrRev返回某字符串在另一个字符串中最后出现的位置
088 End Function
089 --------------------------------------------
090 NetRube_Upload 类文件位于editor/filemanager/connectors/asp/class_upload.asp中
091 -----------------------------------------------
092 Set File(sFormName) = New NetRube_FileInfo
093 File(sFormName).FormName    = sFormName
094 File(sFormName).Start = nFormEnd
095 File(sFormName).Size = nFormStart - nFormEnd - 2
096 nPosStart   = InStr(nPosEnd, sFormHeader, " filename=", 1) + 11
097 nPosEnd = InStr(nPosStart, sFormHeader, """")
098 File(sFormName).ClientPath  = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart)
099 File(sFormName).Name    = Mid(File(sFormName).ClientPath, InStrRev(File(sFormName).ClientPath, "\") + 1)
100 File(sFormName).Ext = LCase(Mid(File(sFormName).Name, InStrRev(File(sFormName).Name, ".") + 1))
101 '获取后缀,没有任何过滤验证得到File(sFormName).Ext
102 nPosStart   = InStr(nPosEnd, sFormHeader, "Content-Type: ", 1) + 14
103 nPosEnd = InStr(nPosStart, sFormHeader, vbCr)
104 File(sFormName).MIME    = Mid(sFormHeader, nPosStart, nPosEnd - nPosStart)
105 -----------------------------------------------
106 Public Sub SaveAs(sItem, sFileName)
107    If File(sItem).Size < 1 Then
108        nErr = 2
109        Exit Sub
110    End If
111 If Not IsAllowed(File(sItem).Ext) Then
112    nErr = 4
113    Exit Sub
114 End If
115 If InStr( LCase( sFileName ), "::$data" ) > 0 Then
116    nErr = 4
117    Exit Sub
118 End If
119 Dim sFileExt, iFileSize
120    sFileExt    = File(sItem).Ext
121    iFileSize   = File(sItem).Size
122 ' Check XSS.
123     If Not IsHtmlExtension( sFileExt ) Then
124 ' Calculate the size of data to load (max 1Kb).
125    Dim iXSSSize
126    iXSSSize = iFileSize
127        If iXSSSize > 1024 Then
128        iXSSSize = 1024
129    End If
130 ' Read the data.
131    Dim sData
132    oSourceData.Position = File(sItem).Start
133    sData = oSourceData.Read( iXSSSize )    ' Byte Array
134    sData = ByteArray2Text( sData )         ' String
135        ' Sniff HTML data.
136    If SniffHtml( sData ) Then
137        nErr = 4
138        Exit Sub
139    End If
140    End If
141 '下面代码直接使用ADODB.Stream保存文件
142    Dim oFileStream
143    Set oFileStream = Server.CreateObject("ADODB.Stream")
144    With oFileStream
145    .Type = 1
146    .Mode = 3
147    .Open
148    oSourceData.Position = File(sItem).Start
149    oSourceData.CopyTo oFileStream, File(sItem).Size
150    .Position   = 0
151    .SaveToFile sFileName, 2
152 'SaveToFile保存文件
153    .Close
154    End With
155    Set oFileStream = Nothing
156 End Sub
157 '这样fck的上传流程基本就是这样了,最后我们使用\0截断,是因为用ADODB.Stream保存文件的时候就会对我文件名处理时候形 www.2cto.com
158 '成的截断,c语言大家懂的。
=====================================
既然是ADODB.Stream保存文件时候,对文件名的处理文件,造成的\0截断,抱着追根究底的想法,想知道到底具体ADODB.Stream对文件名的处理是怎么样的,逆向能力有限,于是google看有没有类似的文章,只找到了FSO保存文件时候
的\0截断分析http://www.security-assessment.com/files/documents/whitepapers/0x00%20vs%20ASP%20file%20upload%20scripts.pdf
此次分析就到此结束了,再深究就需要深厚的逆向编程功底做支撑了,小菜无能为力。
如文件有错希望指正,如你看了此文有不同见解,望相互讨论!
 

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论