當前位置:編程學習大全網 - 源碼下載 - 舉個例子說明SQL註入的大致過程!

舉個例子說明SQL註入的大致過程!

如果妳以前沒有嘗試過SQL註入,第壹步是把IE菜單= & gtTool = & gtInternet選項= & gt高級= & gt刪除友好HTTP錯誤消息前面的勾號。否則無論服務器返回什麽錯誤,IE都只會顯示為HTTP 500服務器錯誤,得不到更多的提示信息。

第壹節,SQL註入原理

先說壹個網站www.19cn.com(註:本文在發表前已經得到站長的認可,大部分是真實數據)。

網站首頁有壹個名為“IE不開新窗口的各種解決方案”的鏈接,地址:。com/showdetail.asp?Id=49,我們在該地址後加上單引號',服務器將返回以下錯誤消息:

Microsoft JET數據庫引擎錯誤“80040e14”

字符串的語法錯誤在查詢表達式“ID=49”中。

/showdetail.asp,第8行

我們可以從這個錯誤提示中看到以下幾點:

1.網站使用Access數據庫,通過JET引擎而不是ODBC連接數據庫。

2.程序沒有判斷客戶端提交的數據是否符合程序要求。

3.此SQL語句查詢的表中有壹個名為ID的字段。

從上面的例子我們可以知道,SQL註入的原理是從客戶端提交專門的代碼來收集程序和服務器的信息,從而獲得妳想要的信息。

第二節,判斷SQL註入是否可以進行

看完第壹節,有人會想:我經常測試能不能這樣註射,不是很簡單嗎?其實這並不是最好的辦法。為什麽?

首先,每臺服務器的IIS不壹定會向客戶端返回特定的錯誤提示。如果將cint(參數)之類的語句添加到程序中,SQL註入將不會成功,但服務器也會報告壹個錯誤。特定提示信息是服務器處理URL時出現的錯誤。請聯系系統管理員。

其次,壹些稍微了解SQL註入的程序員認為過濾掉單引號是安全的,這種情況並不少見。如果用單引號測試,就檢測不到註入點。

那麽,什麽樣的測試方法更準確呢?答案如下:

① .com/showdetail.asp?id=49

② .com/showdetail.asp?id=49和1=1

③ .com/showdetail.asp?id=49和1=2

這就是1=1和1=2的經典測試方法。如何判斷?看看以上三個網站返回的結果:

可以註入的性能:

①正常顯示(這是不可避免的,否則程序有錯誤)

②正常顯示,內容與①基本相同。

(3)提示BOF或EOF(程序未作任何判斷時),或提示找不到記錄(判斷rs.eof時),或顯示內容為空(程序已添加on error resume next)。

如果不能註射就更容易判斷了。①也正常顯示。②、③壹般有程序定義錯誤提示或提示類型轉換錯誤。

當然,這只是傳入參數為數值時的壹種判斷方法。實際應用中會有字符參數和搜索參數,我會在中級章節的“SQL註入的壹般步驟”中分析。

第三節,判斷數據庫類型和註入方法

不同數據庫的功能和註入方式是不壹樣的,所以在註入之前,我們要判斷數據庫的類型。壹般ASP最常用的數據庫是Access和SQLServer,互聯網上99%以上的網站都是其中之壹。

程序怎麽能告訴妳它用的是什麽數據庫?讓我們看看:

SQLServer有壹些系統變量。如果服務器IIS提示沒有關閉,並且SQLServer返回壹個錯誤提示,您可以直接從錯誤消息中獲得它。該方法如下:

。com/showdetail.asp?id=49且用戶& gt0

這句話很簡單,卻包含了SQLServer獨特註入方式的精髓。我自己也是在壹次無意的測試中發現了這個高效的猜測方法。我來看看是什麽意思:首先,前面的說法很正常,側重於和用戶>;0,我們知道,user是SQLServer的內置變量,它的值是當前連接的用戶名,類型是nvarchar。將nvarchar的值與int的數字0進行比較,系統將首先嘗試將nvarchar的值轉換為int類型。當然,在轉換的過程中也會出現錯誤。SQLServer的錯誤提示是將nvarchar“ABC”的值轉換為數據類型為int的列時出現語法錯誤。呵呵,abc就是變量user的值,這樣就可以不費吹灰之力獲得數據庫的用戶名。在接下來的幾頁中,妳會看到許多使用這種方法的句子。

順便說壹下,我們都知道,SQLServer的用戶sa是壹個相當於Adminstrators權限的角色。有了sa權限,幾乎可以肯定他能拿到主機的管理員。上面的方法可以很容易的測試妳是否用sa登錄。需要註意的是,如果用sa登錄,提示是將“dbo”轉換為int的列有錯誤,而不是“sa”。

如果服務器IIS不允許返回錯誤提示,如何確定數據庫類型?我們可以從Access和SQLServer的區別開始。Access和SQLServer都有自己的系統表,例如用於存儲數據庫中所有對象的表。Access在系統表[msy objects]中,但是在Web環境下讀取這個表會提示“無權限”,SQLServer在表[sysobjects]中,在Web環境下可以正常讀取。

當確認可以註射時,使用以下語句:

。com/showdetail.asp?id=49且(select count(*) from sysobjects)>0

。com/showdetail.asp?id=49且(select count(*)from msy objects)>0

如果數據庫是SQLServer,那麽第壹個URL的頁面與原始頁面相同。com/showdetail.asp?Id=49大致相同;第二個URL將提示壹個錯誤,因為找不到表msysobjects。即使程序有容錯,頁面也和原頁面完全不同。

如果數據庫使用Access,情況就不同了。第壹個URL的頁面與原始頁面完全不同。第二個網站,取決於數據庫設置是否允許讀取系統表,壹般是不允許的,所以和原網站完全不同。大多數情況下,用第壹個URL就可以知道系統使用的數據庫類型,第二個URL只是在打開IIS錯誤提示時作為驗證使用。

第壹節,SQL註入的壹般步驟

首先判斷環境,找到註入點,判斷數據庫類型,在入門文章裏已經提到了。

其次,根據註入參數類型,在腦海中重構SQL語句的原貌,根據參數類型主要分為以下三種:

(A) ID=49註入的參數是數值型的,SQL語句的原始外觀大致如下:

Select * from字段=49的表名

註入的參數是ID=49和[查詢條件],即生成的語句:

Select * from表名,其中字段=49和[查詢條件]

(B) Class= Series註入的參數是字符型的,SQL語句原來的樣子大致如下:

Select * from表名,其中field =' series '

註入的參數是Class= series '和[查詢條件]和' ' =' = ',即生成的語句:

Select * from表名,其中field =' series '和[查詢條件]以及' ' ='' = ' '

(c)如果搜索時沒有篩選參數,例如keyword= keyword,則原始SQL語句如下所示:

Select * from表名,其中字段如' % keyword% '

註入的參數是keyword= '和[查詢條件]和' % 25' = ',即生成的語句:

Select * from表名,其中字段如“%”、[查詢條件]和“%”=“%”

然後,用SQL語句替換查詢條件,並猜測表名,例如:

ID=49且(從Admin中選擇Count(*))>=0

如果頁面與ID=49的頁面相同,則附加條件成立,即表Admin存在,否則不存在(請記住這個方法)。依此類推,直到猜出表名。

猜出表名後,用Count(字段名)代替Count(*),用同樣的原理猜出字段名。

有人會說:這裏有些偶然的成分。如果手表的名字很復雜,沒有規律,那就根本不用玩了。沒錯。這個世界上沒有100%成功的黑客技術。蒼蠅不叮無縫的蛋。黑客再高明,也是因為別人的程序寫得不好或者用戶保密意識不夠,才會下手。

有點跑題了。另壹方面,程序仍然有辦法告訴我們SQLServer庫的表名和字段名,我們將在高級文章中介紹。

最後,在成功猜測出表名和列名之後,通過使用SQL語句獲得字段的值。這裏介紹壹種最常用的方法——Ascii逐字解碼法。這個方法雖然慢,但肯定是可行的。

例如,我們知道用戶名字段存在於表Admin中。首先,我們獲取第壹條記錄並測試其長度:

。com/showdetail.asp?id=49且(從Admin中選擇top 1 len(用戶名)>;0

先說明原理:如果top 1的用戶名長度大於0,則條件成立;然後是> 1 、>;2、gt;3這樣測試,直到條件不成立,如> 7成立,> 8不成立,即len(username)=8。

當然,沒有人會傻到從0,1,2,3開始壹個壹個的測試,如何讓它更快,就看自己的發揮了。得到用戶名的長度後,用mid(username,N,1)截取第N個字符,再用asc(mid(username,N,1))得到ASCII碼,例如:

id=49且(select top 1 ASC(mid(username,1,1)) from Admin)>0

類似地,1字符的ASCII碼是通過逐漸縮小範圍獲得的。註意英文和數字的ASCII碼在1-128之間,可以用來加快猜測的速度。如果寫成程序測試,效率會大大提高。

第2節,SQL註入常用函數

有SQL語言基礎知識的人在SQL註入的成功率比不熟悉的人高很多。我們有必要提高自己的SQL水平,尤其是壹些常用的函數和命令。

Access:asc(字符)SQLServer:unicode(字符)

函數:返回字符的ASCII碼。

Access:chr(數字)SQLServer:nchar(數字)

函數:與asc相反,根據ASCII碼返回字符。

Access:mid (string,N,L N,L) SQLServer:substring (string,N,L)

函數:從N個字符中返回長度為L的子串,即介於N和N+L之間的字符串。

訪問:abc(數字)SQLServer:abc(數字)

函數:返回壹個數字的絕對值(猜測漢字時使用)

訪問:B和C之間的A SQL server:B和C之間的A

作用:判斷A是否在B和c之間。

第三節,中文處理方法

打針遇到漢字是常事,有的人壹遇到漢字就想打退堂鼓。其實只要對中文編碼有所了解,“中文恐懼癥”很快就能克服。

先說壹點常識:

在Access中,中文ASCII碼中可能有負數。取出負數後,用abs()取絕對值,漢字不變。

在SQLServer中,中文ascii是正數,但是因為是UNICODE的雙位編碼,所以不能使用函數ASCII()來獲取ASCII碼。必須使用函數unicode()返回unicode值,然後使用nchar函數獲取相應的中文字符。

  • 上一篇:大師風範 閱讀答案
  • 下一篇:工程師助理的工作職責
  • copyright 2024編程學習大全網