程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> URL編碼與SQL注入

URL編碼與SQL注入

編輯:ASP技巧

說到url編碼,你或許會想起N年前的url編碼漏洞。可惜我是“生不逢時”啊,我接觸網絡時,那個漏洞早就絕跡咯。

言歸正傳,URL 編碼是什麼東東呢?看看我從網上抄的定義:

引用: url編碼是一種浏覽器用來打包表單輸入的格式。浏覽器從表單中獲取所有的name和其中的值 ,將它們以name/value參數編碼(移去那些不能傳送的字符, 將數據排行等等)作為URL的一部分或者分離地發給服務器。不管哪種情況, 在服務器端的表單輸入格式樣子象這樣:

theName=Ichabod+Crane&gender=male&status=missing&headless=yes

URL編碼遵循下列規則: 每對name/value由&符分開;每對來自表單的name/value由=符分開。如果用戶沒有輸入值給這個name,那麼這個name還是出現,只是無值。任何特殊的字符(就是那些不是簡單的七位ASCII,如漢字)將以百分符%用十六進制編碼,當然也包括象 =, &, 和 % 這些特殊的字符。


呵呵,明白了吧,其實url編碼就是一個字符ascii碼的十六進制。不過稍微有些變動,需要在前面加上“%”。比如“\”,它的ascii碼是92,92的十六進制是5c,所以“\”的url編碼就是\。那麼漢字的url編碼呢?很簡單,看例子:“胡”的ascii碼是-17670,十六進制是BAFA,url編碼是“%BA%FA”。呵呵,知道怎麼轉換的了吧。

URL編碼平時我們是用不到的,因為IE會自動將你輸入到地址欄的非數字字母轉換為url編碼。所以對於浏覽器來說http://blog.csdn.net/l%61ke2與http://blog.csdn.net/lake2是等效的(注意,第一個url我用%61替換了a)。呵呵,或許你已經想起了,有人提出數據庫名字裡帶上“#”以防止被下載,因為IE遇到#就會忽略後面的字母。破解方法很簡單——用url編碼#替換掉#。我本來企圖利用url編碼來躲過注射檢查的,不過失敗了,因為服務器端會將url編碼轉換成字符的。

等等,好像跑題了啊,呵呵,不好意思:)

現在SQL注射非常流行,所以就有人寫了一些防注射的腳本。當然啦,思路不一樣,效果大不同。各位看官請看下面的××SQL通用防注入ASP版部分代碼。

          Fy_Url=Request.ServerVariables("QUERY_STRING")
          Fy_a=split(Fy_Url,"&")
          redim Fy_Cs(ubound(Fy_a))
          On Error Resume Next
          for Fy_x=0 to ubound(Fy_a)
                     Fy_Cs(Fy_x) = left(Fy_a(Fy_x),instr(Fy_a(Fy_x),"=")-1)
          Next
          For Fy_x=0 to ubound(Fy_Cs)
                    If Fy_Cs(Fy_x)<>"" Then
                           If Instr(LCase(Request(Fy_Cs(Fy_x))),"and")<>0 then
                                  Response.Write "出現錯誤!"
                                  Response.End
                           End If
                    End If
          Next


它的思路就是先獲得提交的數據,以“&”為分界獲得並處理name/value組,然後判斷value裡是否含有定義的關鍵字(這裡為求簡便,我只留下了“and”),有之,則為注射。

乍一看去,value被檢查了,似乎沒有問題。呵呵,是的,value不會有問題,可是,name呢?

它的name/value組值來自於Request.ServerVariables("QUERY_STRING"),呵呵,不好意思,這裡出問題了。Request.ServerVariables("QUERY_STRING")是得到客戶端提交的字符串,這裡並不會自動轉換url編碼,哈哈,如果我們把name進行url編碼再提交的話,呵呵,那就可以繞過檢查了。比如參數是ph4nt0m=lake2 and lis0,此時程序能夠檢測到;如果提交%50h4nt0m=lake2 and lis0(對p進行url編碼),程序就會去判斷%50h4nt0m的值,而%50h4nt0m會被轉換為ph4nt0m,所以%50h4nt0m值為空,於是就繞過了檢測。

等等,為什麼既然name不解碼可以繞過檢查而value就不能繞過呢?因為value的值取自Request(Fy_Cs(Fy_x)),這個服務器就會解碼的。

程序怎麼改進呢?只要能夠得到客戶端提交的數據是解碼後的就可以了,把得到name的語句改為For Each SubmitName In Request.QueryString就可以了。

呵呵,謝謝閣下耐著性子看完我的文章^_^

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved