1. 程式人生 > 實用技巧 >sql注入基礎

sql注入基礎


有好多人都只知道有sql注入漏洞這種漏洞,也知道怎麼用一些工具來利用漏洞,但是卻不知道SQL注入漏洞的原理。為了幫助初學者理解sql注入的原理,我寫下了這篇文章,希望能對大家有所幫助。

什麼是SQL注入:

SQL注入是***者通過把惡意SQL命令插入到Web表單的輸入域或頁面請求的查詢字串中,來達到欺騙伺服器執行惡意的SQL命令的一種***方式。(資料與程式碼沒有完全分離)

Sql注入漏洞產生原理:

上面我們提到SQL注入的產生原因是資料和程式碼沒有完全分離產生的。下面我們來看看SQL注入漏洞具體的產生過程:

首先,我們來看看瀏覽器瀏覽連結時的工作原理。

在我們開啟某一個連結的時候瀏覽器和伺服器是存在互動的。這個連結中存在著伺服器需要為瀏覽器提供的資料內容的查詢名稱。比如

www.123.com/news.index.aspid=1(假想地址),這裡,當瀏覽器提出訪問請求的時候,伺服器就會在資料庫中查詢id=1的資料,然後反饋給瀏覽器,這樣,我們瀏覽器就能根據伺服器反饋的資料來滿足瀏覽者的需求。查詢的程式碼如下圖所示。

wKiom1Xq3cvRrbgBAAEXtKCaHnY865.jpg

按理說,這個過程是挺巧妙的吧。但是,如果你在網站程式碼編寫的時候沒有將資料與程式碼分離的話,這個過程中就存在著漏洞。

在資料庫查詢過程中,實際執行的語句如下:

Select *from news where id=1

現在我們在URLhttp://www.123.com/news.index.aspid=1(假想地址))後面新增"and 1=1"

,此時實際執行的SQL語句是:

Select *from news where id=1 and 1=1

由於這個條件永遠成立,所以返回的頁面和正常頁面相同。

當新增“ and 1=2”時,會執行如下SQL語句:

Select *from news where id=1 and 1=2

由於這個條件永遠不成立,所以返回的頁面和正常頁面不同。

現在我們可以控制引數id的值來影響程式的返回結果。我們來分析一下上面圖中的程式碼,後臺在通過GET方式取的引數id的值後,直接用來構造動態SQL語句,並執行SQL查詢。這整個過程沒有對變數id的值作任何處理。這就導致了SQL注入漏洞的產生。(其實,這個漏洞我們如果在寫網站程式碼的時候將資料與程式碼分離,那麼這種漏洞完全可以避免。不過由於一些程式猿的程式碼編寫問題,這種漏洞在網站裡還是很常見。)

Sql注入漏洞的判斷:

我們上面講了sql注入漏洞,那麼到底怎麼判斷一個網站到底有沒有sql注入漏洞呢?

首先,注入是有一定前提條件的。那就是我們的目標一定是動態的,存在資料庫互動的web系統。如果不是動態的話,大家還是洗洗睡吧,別往sql注入方面想了。(我剛接觸sql注入的時候看過別人拿工具去試一個靜態站點。。。。)

我們的注入型別有字元型注入、整型注入和搜尋型注入。

我們判斷是否有sql注入漏洞的時候也是針對這三種注入型別來判斷的。

字元型注入漏洞的判斷:

字元型注入漏洞的判斷就是我們常見的單引號探測。

在我們的判斷目標後加一個單引號,如果目標回饋一個異常介面,就說明它沒有進行字元型過濾。這樣,我們就可以判斷這裡很可能存在字元型注入漏洞。

wKioL1Xq4Abx4-67AAKcHlzudJU835.jpg

×××注入漏洞的判斷:

對於×××注入漏洞,我們使用and探測。比如

http://www.123.com/news.index.aspid=1 (1)

我們在它後面加上and 1=1

http://www.123.com/news.index.aspid=1 and 1=1 2

看它的載入情況是否與原來的網頁的載入相同。然後我們在(1)的後面再加上and 1=2

http://www.123.com/news.index.aspid=1 and 1=2 3

然後載入。如果(1)與(2)的載入情況相同而(3)與(1)(2)的載入情況不同,我們就可以判斷此處存在×××注入漏洞。wKiom1Xq3fCjd80nAAR8NiZgQqE101.jpgwKioL1Xq4CGjDZN-AAQN_7pVX0w413.jpgwKiom1Xq3gqQbfbMAAMTTAvlF50161.jpg

搜尋型注入漏洞的判斷:

搜尋型注入漏洞的判斷與×××注入漏洞相似,都用到了and 1=1 and 1=2。下面,我們來介紹下怎麼判斷搜尋型注入漏洞吧。

首先,我們在搜尋框中輸入1%’and 1=1 and ‘%’=’,點選搜尋,檢視搜尋結果。

然後,我們在搜尋框中輸入1%’and1=2 and ‘%’=’ ,點選搜尋,檢視搜尋結果。

如果我們兩次的搜尋結果不一樣的話,那就說明此處存在搜尋型注入漏洞

介紹搜尋型漏洞的一篇文章:

http://blog.guetsec.org/?p=85

有的人在探測sql注入漏洞的時候只用到單引號探測,單引號探測探測不到漏洞的話他就認為這裡沒有漏洞。但其實,對sql注入有一點了解的程式猿他會在這裡對字元型進行過濾,讓你單引號探測的時候探測不出來。所以我們在判斷是否存在sql注入漏洞的時候最好還是把這三種漏洞全部探測完再下結論。

各型別注入的利用原理:

×××注入:

ID=49這類注入的引數是數字型,SQL語句原貌大致如下:

Select*from表名where欄位=49

注入的引數為ID=49And[查詢條件],即是生成語句:

Select*from表名where欄位=49And[查詢條件]

字元型注入:

Class=武漢這類注入的引數是字元型,SQL語句原貌大致概如下:

Select*from表名where欄位='武漢'

注入的引數為Class=連續劇'and[查詢條件]and‘'=',即是生成語句:

Select*from表名where欄位='連續劇'and[查詢條件]and‘'=''

搜尋型注入:

搜尋型注入利用的是網頁在搜尋時沒過濾引數的漏洞,如keyword=關鍵字,SQL語句原貌大致如下:

Select*from表名where欄位like'%關鍵字%'

注入的引數為keyword='and[查詢條件]and‘%25'='即是生成語句:

Select*from表名where欄位like'%'and[查詢條件]and‘%'='%'

手工注入的步驟:

A) 找注入
B)
確認注入
C)
收集資訊(伺服器名,資料庫版本,安裝目錄等)
D)
爆資料庫
E)
爆表段
F)
爆欄位

判斷web系統的資料庫型別。

判斷acess資料庫和sqlserver資料庫:

不同的資料庫的函式、注入方法都是有差異的,所以在注入之前,我們還要判斷一下資料庫的型別。一般 ASP 最常搭配的資料庫是 Access SQLServer,網上超過 99% 的網站都是其中之一。而PHP網站一般搭配MYSQL資料庫。

大部分情況下,sql漏洞檢測的時候會顯示資料庫型別,但是如果sql漏洞檢測的時候網站沒有顯示資料庫型別,我們又該怎麼辦呢?

我們可以從 Access SQLServer 和區別入手,Access SQLServer 都有自己的系統表,比如存放資料庫中所有物件的表,Access 是在系統表 [msysobjects ]中,但在 Web 環境下讀該表會提示“沒有許可權”,SQLServer是在表 [sysobjects] 中,在 Web 環境下可正常讀取。

區分MSsql資料庫和Acess資料庫:

在注入點後加上: ;–(一個分號,兩個橫線)比如這個網址
www.123.com/news.index.aspid=1,我們事先已經確定了它是注入點了, 這樣的話我們就可以在後面加上;–讓它變成
www.123.com/news.index.aspid=1; 提交這個網址,如果頁面返回正常的話,說明資料庫是MSSQL。因為在MSSQL資料庫裡,;和–都是存在的,”;用來分離兩個語句,而”–“就是註釋符,在它後面的語句都不執行。而ACCESS資料庫裡沒有。所以如果是ACCESS的資料庫,當你在注入地址後面加上”;–“的話那程式就會把”;–“當成引數的一部分,這樣查詢就會出錯。如果錯誤,那基本上可以肯定是ACCESS了(因為網上用這兩種資料庫的網站最多。)

用以上方法都判斷不出來的話,那就利用ACCESSMSSQL資料庫的差異來進行判斷。要用到兩個查詢語句。同樣,如果注入點是www.123.com/news.index.aspid=1,那我們在後面加上 and exists (select count(*) fromsysobjects),那麼地址就變成了
www.123.com/news.index.aspid=1 andexists (select count(*) from sysobjects)。如果頁面正常返回,那就可以證明資料庫是MSSQL的。如果返回正常,就說明存在sysobjects這個表,因為這個表MSSQL資料庫裡有而ACESS資料庫沒有,所以可以確定資料庫的MSSQL的。如果返回錯誤,那就不是。那我們怎麼用查詢語句來判斷資料庫是不是ACCESS的呢?我們在注入點後加上 and exists (select count(*) frommsysobjects)。就成了www.123.com/news.index.aspid=1 andexists (select count(*) from msysobjects),按剛才理解MSSQL資料庫的方法去理解這條語句。這裡要注意,提交這個語句是不會返回正常頁面的。就算是ACCESS資料庫也不會返回正常的頁面。因為預設情況下,我們是沒有許可權查詢這個表裡的資料的。不過WEB會提示我們 “記錄無法讀取;msysobjects’沒有讀取許可權”。如果返回的是這個錯誤資訊的話,那就證明是ACCESS資料庫了。簡單地來說就是兩條查詢語句:
and exists (select count(*) from sysobjects)
and exists (select count(*) from msysobjects)

如果第一條返回正常,那就是MSSQL資料庫,如果兩條都不正常,那就是ACCESS資料庫了。

手工Sql注入:

前面我們在這個網站已經發現了注入點並且確認注入,現在開始接下來的分析。

收集資訊:

wKioL1Xq4D7g1tO0AAHbE2NAjzo928.jpg

從這裡我們可以看出一下幾點:

1、網站使用的是Access資料庫,通過ODBC引擎連線資料庫,而不是通過JET

2、程式沒有判斷客戶端提交的資料是否符合程式要求。

3、該網站採用ASP指令碼。

接下來就是分析資料庫裡面的東西了。

猜表名:

用到的語句:and exists(select count(*) from 你要猜的表名) 。在注入點後加上這句話,如果返回正常,說明你猜的表是存在的!比如
www.123.com/news.index.aspid=1 andexists (select count(*) from admin),如果返回正常,說明admin這張表存在。如果返回錯誤,就說明不存在。別的表也都是這麼猜.

wKioL1Xq4E6ik6o_AAVrFPkV7WQ234.jpg

這裡我們猜的user表存在。

常用的表名:admin usernews manage a_admin x_admin m_admin adminuser admin_user article_adminadministrator manager member memberlist users Manage_User user_infoadmin_userinfo login new使用者會員

然後接著猜列名:

用到的語句:and (select count(列名) from 猜到的表名)>0 。在注入點後加上這句話,如果返回正常,說明你猜的列是存在的!比如
www.123.com/news.index.aspid=1 and(select count(username) from admin)>0,如果返回正常,那username這個列就存在。不過首先要確定from後面跟的表名要是存在的哦,不然你怎麼猜都是錯的。

wKioL1Xq4FzRy0EFAAU-RizvpJg965.jpg

所猜欄位名存在。

常用的列名:username password id adminusername admin_username adminname admin_nameadmin adminuser admin_user user_name user_admin administrator administratorsadminpassword admin_pwd adminpass userpass user_pass admin_passwod 使用者使用者名稱密碼帳號

檢測記錄數:

用到的語句:and (select count(*) from 猜到的表名)>X X是個數字)。在注入點後加上這句話,並不停地變換X這個數字,直到猜到準確的記錄數為止。比如www.123.com/news.index.aspid=1 and(select count(*) from admin)>2 ,這個句子是猜admin表裡有幾條記錄的,也就是有幾個管理員(一個管理員對應一條記錄)。如果返回正常,說明admin這張表裡的記錄數大於 2。這個時候我們把2改成別的大一點的數。比如5,如果返回錯誤,說明管理員的個數在25之間,25之間的整數是34,這個時候我們變換語句為www.123.com/news.index.aspid=1 and(select count(*) from admin)=3或者=4,哪個返回正常那管理員的個數就是哪個。如果提交>5還返回錯誤,那就再取一個更大的數,再重複剛才的動作就可以猜到記錄數。

檢測欄位長度:

用到的語句:and (select top 1 len() from )>X (X和剛才一樣。)select top 1是查詢第一條資料的意思(在WEB環境下不支援多行回顯,只是一次查詢的資料不能超過一行。),lenMSSQL裡的一個函式,用法是len(), ()裡可以是字串也可以是表示式也可以是列名。

這裡檢測欄位長度和檢測記錄數都可以可以採用了二分查詢法,這樣可以減少判斷次數,節省時間。如果採用從order by 1依次增加數值的方法來判斷,需要8次才可以確定欄位數,採用二分查詢法只需要5次就夠。當欄位數很大時,二分查詢法的優勢更加明顯,效率更高。


轉載於:https://blog.51cto.com/xiaoqin00/1691629