PJBlog安全性分析

Authorlake2http://lake2.0x54.org

Date2006-1-1

 

PJBlog2PuterJam開發的一款免費的ASP + Access的個人blog系統,這幾天偶想弄個blog來玩玩,經過比較選中了功能、界面都相對較好的PJBlog2。經過試用,感覺這blog還不錯,也發現幾個安全方面的小問題,就把我的一點點見解發出來。我分析的版本是051211發佈的PJBlog2 v2.4.1211版本。

 

 

一、 密碼加密算法

PJBlog2沒有采用常用的MD5算法對用戶密碼加密,而是使用的SHA1算法。SHA1算法跟MD5類似,也是單向散列函數,不過它對任意長度的數據進行處理輸出160位的數值。

PJBlog2在創建新用戶的時候會隨機生成一個6位的字符串Salt,用戶的明文密碼加上這個Salt值再進行hash纔得到加密後的密碼。即:Password = SHA1(user_pwd & Salt)。這樣子做的好處是即使兩個一樣的密碼hash後的結果也完全不同。這個稍微“另類”的算法給破解密碼帶來了點難度。

呵呵,有難度不等於不能破解,網上沒有現成的程序,需要自己動手寫個纔是。因爲.NET提供了SHA1的類所以最初用VB.Net寫的,由於狂耗資源的問題一直解決不了,只好換C了。用C實現SHA1的源代碼我找了好久纔在一個老外的站找到,還不錯,呵呵,有興趣的可以看下老外的SHA1類:http://www.codeproject.com/cpp/csha1.asp

程序可以在這裏( http://www.0x54.org/lake2/program/PJBlogCracker.exe )下載,是命令行下的,功能比較弱,單線程速度超級慢,可能還有bug,諸多問題以後再改咯。

 

二、 登陸認證

PJBlog2的認證方式是用的CookiesIP。當用戶登陸成功,系統隨機產生一個Hashkey寫入Cookies並記錄到數據庫中,然後通過Cookies裏的HashkeyUsername還有IP來判斷用戶。Cookies好辦,可以用跨站、下數據庫等方式拿,可以這IP就難辦了,看來進行Cookies欺騙的可能性很小啊。呵呵,那就不看這個咯。

 

三、 幾個地方過濾不嚴

第一個就是統計訪問的referer過濾不嚴。看:

 

       Guest_Refer=Trim(Request.ServerVariables("HTTP_REFERER"))

         Conn.ExeCute("INSERT INTO blog_Counter(coun_IP,coun_OS,coun_Browser,coun_Referer) VALUES ('"&Guest_IP&"','"&Guest_Browser(1)&"','"&Guest_Browser(0)&"','"&CheckStr(Guest_Refer)&"')")

 

呵呵,只是把referer過濾後用CheckStr檢查之,看CheckStr代碼:

 

'*************************************

'過濾特殊字符

'*************************************

Function CheckStr(byVal ChkStr)

         Dim Str:Str=ChkStr

         Str=Trim(Str)

         If IsNull(Str) Then

                   CheckStr = ""

                   Exit Function

         End If

    Str = Replace(Str, "&", "&")

    Str = Replace(Str,"'","'")

    Str = Replace(Str,"""",""")

         Dim re

         Set re=new RegExp

         re.IgnoreCase =True

         re.Global=True

         re.Pattern="(w)(here)"

    Str = re.replace(Str,"$1here")

         re.Pattern="(s)(elect)"

    Str = re.replace(Str,"$1elect")

         re.Pattern="(i)(nsert)"

    Str = re.replace(Str,"$1nsert")

         re.Pattern="(c)(reate)"

    Str = re.replace(Str,"$1reate")

         re.Pattern="(d)(rop)"

    Str = re.replace(Str,"$1rop")

         re.Pattern="(a)(lter)"

    Str = re.replace(Str,"$1lter")

         re.Pattern="(d)(elete)"

    Str = re.replace(Str,"$1elete")

         re.Pattern="(u)(pdate)"

    Str = re.replace(Str,"$1pdate")

         re.Pattern="(/s)(or)"

    Str = re.replace(Str,"$1or")

         Set re=Nothing

         CheckStr=Str

End Function

 

過濾了單引號、雙引號、連接符等,不過最重要的“<”和“>”卻沒有過濾。呵呵,跨站腳本攻擊又有用武之地了。注意只顯示前面40個字符在頁面,要好好構造哦。

第二就是遊客評論輸入用戶名也是用的CheckStr過濾,用戶名數據庫有限制,24個字符,這裏構造CSS就更有難度了,不過可以有別的用處,具體的嘛,呵呵,後文詳述。

有些blog主人禁止了遊客評論,所以就只好註冊後再評論了,但是註冊後評論的名字文本框被設成了註冊名而且只讀,怎麼辦?呵呵,沒關係,可以外部提交數據的。

再一個就是blog的留言板插件,還是用戶名沒過濾好,這個更難利用,只有20個字符哦。

 

四、 數據庫的問題

PJBlog2的默認數據庫名爲pblog.asp,雖然數據庫裏面有個貌似防下載的blog_Notdownload表,呵呵,訪問數據庫試試,可以下載的哦。

既然可以下載,當然可以插入asp代碼運行咯。有些地方(比如遊客評論內容)插入asp代碼會被扯開,不知道原因,鬱悶。

經測試評論的姓名裏是可以插ASP代碼的。前面說了這裏過濾不嚴,這樣插入數據庫的asp不會被顯示出來的,看到的只是個沒名字的傢伙在唧唧歪歪,呵呵。這個可要好好構造哦,24個字符而且"被過濾了,想了一下,正好找到一個最短的,恰好24個字符:<%eval request(chr(9))%>

留言版的內容也可以插入asp代碼,不過管理員看留言時看得到的哦。

呵呵,當然大多數站長應該都是改了數據庫名稱的,但是測試時還是發現少數人不改……

 

五、 上傳文件

出於安全的考慮,PJBlog2限制了上傳文件類型,包括aspasaaspxcercdxhtr。其實現在很多虛擬主機不僅支持asp,還會支持aspxphpperl的,而且也可以上傳shtml等格式,所以如果既然要限制最好是把所有服務器執行文件的類型一起限制纔是。

上傳文件這裏還有點問題,看attachment.asp裏的代碼:

 

Dim F_File,F_Type

Set F_File=FileUP.File("File")

F_Name=randomStr(1)&Year(now)&Month(now)&Day(now)&Hour(now)&Minute(now)&Second(now)&"."&F_File.FileExt

F_Type=FixName(F_File.FileExt)

IF F_File.FileSize > Int(UP_FileSize) Then

         Response.Write("<div style=""padding:6px""><a href='attachment.asp'>文件大小超出,請返回重新上傳</a></div>")

ElseIF IsvalidFile(UCase(F_Type)) = False Then

         Response.Write("<div style=""padding:6px""><a href='attachment.asp'>文件格式非法,請返回重新上傳</a></div>" )

Else

         F_File.SaveAs Server.MapPath("attachments/"&D_Name&"/"&F_Name)

         response.write "<script>addUploadItem('"&F_Type&"','attachments/"&D_Name&"/"&F_Name&"',"&Request.QueryString("MSave")&")</script>"

         Response.Write("<div style=""padding:6px""><a href='attachment.asp'>文件上傳成功,請返回繼續上傳</a></div>")

End IF

 

保存文件的後綴是F_File.FileExt,而檢查的是經過FixName()函數處理的後綴,那就看看fixname函數定義,在function.asp中:

 

'*************************************

'過濾文件名字

'*************************************

Function FixName(UpFileExt)

         If IsEmpty(UpFileExt) Then Exit Function

         FixName = Ucase(UpFileExt)

         FixName = Replace(FixName,Chr(0),"")

         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","")

End Function

 

呵呵,它把危險後綴過濾了的,如果我的文件後綴是asp(0x00)gif,那麼檢查的時候過濾chr(0)asp,後綴就成了gif,通過,保存的時候就是asp(0x00)gif。從理論上來說是對的啊,我搞了半天也不行,鬱悶。有知道的大俠告訴我啊。

不過我們可以利用這個上傳aspx格式。呵呵,我們上傳aspx文件,fixname函數過濾asp,於是後綴就成了x。只要把x設爲可以上傳的格式,就可以傳aspx文件了。

 

六、 附件管理問題

管理員登陸後有個附件管理功能,看他參數類似於http://localhost/blog/ConContent.asp?Fmenu=SQLFile&Smenu=Attachments&AttPath=attachments/month_0512,可以通過指定AttPath瀏覽web目錄的哦。

但是系統限制了站外提交數據,所以不能直接改url,那就“曲線救國”吧。找到友情鏈接添加功能,url就填上我們構造的url,保存,然後點查看,就繞過站外的限制了。注意構造的AttPath的第一個字符不能是“.”和“/”哦,程序有檢查的。我們這樣構造就可以跳到blog根目錄:http://localhost/blog/ConContent.asp?Fmenu=SQLFile&Smenu=Attachments&AttPath=attachments/..

 

 

呵呵,最後還是希望大家支持PJBlog2,真的是很好用的啊。希望作者再接再厲,把這套blog系統做得更好,造福衆多網民J

PS:作者真是勤快啊,補丁已經出來了,呵呵

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章