明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

深入SQL注入

[摘要]前面已經(jīng)把SQL注入攻擊的簡(jiǎn)單方法履了一遍 今天我們繼續(xù)就一些問(wèn)題來(lái)好好研究一下前面我們說(shuō)可以通過(guò)一些返回信息來(lái)判斷SQL注入, 但首先不一定每臺(tái)服務(wù)器的IIS都返回具體錯(cuò)誤提示給客戶端, 如果...

前面已經(jīng)把SQL注入攻擊的簡(jiǎn)單方法履了一遍

今天我們繼續(xù)就一些問(wèn)題來(lái)好好研究一下

前面我們說(shuō)可以通過(guò)一些返回信息來(lái)判斷SQL注入, 但首先不一定每臺(tái)服務(wù)器的IIS都返回具體錯(cuò)誤提示給客戶端, 如果程序中加了cint(參數(shù))之類語(yǔ)句的話, SQL注入是不會(huì)成功的, 但服務(wù)器同樣會(huì)報(bào)錯(cuò), 具體提示信息為處理 URL 時(shí)服務(wù)器上出錯(cuò)。 請(qǐng)和系統(tǒng)管理員聯(lián)絡(luò)。

其次, 部分對(duì)SQL注入有一點(diǎn)了解的程序員, 認(rèn)為只要把單引號(hào)過(guò)濾掉就安全了, 這種情況不為少數(shù), 如果你用單引號(hào)測(cè)試, 是測(cè)不到注入點(diǎn)的

那么, 什么樣的測(cè)試方法才是比較準(zhǔn)確呢?答案如下:

① http://host/showdetail.asp?id=49

② http://host/showdetail.asp?id=49 ;;and 1=1

③ http://host/showdetail.asp?id=49 ;;and 1=2

這就是經(jīng)典的1=1、1=2測(cè)試法了, 怎么判斷呢?看看上面三個(gè)網(wǎng)址返回的結(jié)果就知道了:

可以注入的表現(xiàn):

① 正常顯示(這是必然的, 不然就是程序有錯(cuò)誤了)

② 正常顯示, 內(nèi)容基本與①相同

③ 提示BOF或EOF(程序沒(méi)做任何判斷時(shí))、或提示找不到記錄(判斷了rs.eof時(shí))、或顯示內(nèi)容為空(程序加了on error resume next)

不可以注入就比較容易判斷了, ①同樣正常顯示, ②和③一般都會(huì)有程序定義的錯(cuò)誤提示, 或提示類型轉(zhuǎn)換時(shí)出錯(cuò)。

  當(dāng)然, 這只是傳入?yún)?shù)是數(shù)字型的時(shí)候用的判斷方法, 實(shí)際應(yīng)用的時(shí)候會(huì)有字符型和搜索型參數(shù), 下面我們?cè)趤?lái)坐分析。

不過(guò)我們先來(lái)說(shuō)一個(gè)問(wèn)題:

不同的數(shù)據(jù)庫(kù)的函數(shù)、注入方法都是有差異的, 所以在注入之前, 我們還要判斷一下數(shù)據(jù)庫(kù)的類型。 一般ASP最常搭配的數(shù)據(jù)庫(kù)是Access和SQLServer, 網(wǎng)上超過(guò)99%的網(wǎng)站都是其中之一。

怎么讓程序告訴你它使用的什么數(shù)據(jù)庫(kù)呢?來(lái)看看:

SQLServer有一些系統(tǒng)變量, 如果服務(wù)器IIS提示沒(méi)關(guān)閉, 并且SQLServer返回錯(cuò)誤提示的話, 那可以直接從出錯(cuò)信息獲取, 方法如下:

http://host/showdetail.asp?id=49 ;;and user>0

這句語(yǔ)句很簡(jiǎn)單, 但卻包含了SQLServer特有注入方法的精髓, 我自己也是在一次無(wú)意的測(cè)試中發(fā)現(xiàn)這種效率極高的猜解方法。 讓我看來(lái)看看它的含義:首先, 前面的語(yǔ)句是正常的, 重點(diǎn)在and user>0, 我們知道, user是SQLServer的一個(gè)內(nèi)置變量, 它的值是當(dāng)前連接的用戶名, 類型為nvarchar。 拿一個(gè)nvarchar的值跟int的數(shù)0比較, 系統(tǒng)會(huì)先試圖將nvarchar的值轉(zhuǎn)成int型, 當(dāng)然, 轉(zhuǎn)的過(guò)程中肯定會(huì)出錯(cuò), SQLServer的出錯(cuò)提示是:將nvarchar值 ”abc” 轉(zhuǎn)換數(shù)據(jù)類型為 int 的列時(shí)發(fā)生語(yǔ)法錯(cuò)誤, 呵呵, abc正是變量user的值, 這樣, 不廢吹灰之力就拿到了數(shù)據(jù)庫(kù)的用戶名。 在以后的篇幅里, 大家會(huì)看到很多用這種方法的語(yǔ)句。

順便說(shuō)幾句, 眾所周知, SQLServer的用戶sa是個(gè)等同Adminstrators權(quán)限的角色, 拿到了sa權(quán)限, 幾乎肯定可以拿到主機(jī)的Administrator了。 上面的方法可以很方便的測(cè)試出是否是用sa登錄, 要注意的是:如果是sa登錄, 提示是將”dbo”轉(zhuǎn)換成int的列發(fā)生錯(cuò)誤, 而不是”sa”。  

如果服務(wù)器IIS不允許返回錯(cuò)誤提示, 那怎么判斷數(shù)據(jù)庫(kù)類型呢?我們可以從Access和SQLServer和區(qū)別入手, Access和SQLServer都有自己的系統(tǒng)表, 比如存放數(shù)據(jù)庫(kù)中所有對(duì)象的表, Access是在系統(tǒng)表[msysobjects]中, 但在Web環(huán)境下讀該表會(huì)提示“沒(méi)有權(quán)限”, SQLServer是在表[sysobjects]中, 在Web環(huán)境下可正常讀取。

在確認(rèn)可以注入的情況下, 使用下面的語(yǔ)句:

http://host/showdetail.asp?id=49 ;;and (select count(*) from sysobjects)>0

http://host/showdetail.asp?id=49 ;;and (select count(*) from msysobjects)>0

如果數(shù)據(jù)庫(kù)是SQLServer, 那么第一個(gè)網(wǎng)址的頁(yè)面與原頁(yè)面http://host/showdetail.asp?id=49是大致相同的;而第二個(gè)網(wǎng)址, 由于找不到表msysobjects, 會(huì)提示出錯(cuò), 就算程序有容錯(cuò)處理, 頁(yè)面也與原頁(yè)面完全不同。

如果數(shù)據(jù)庫(kù)用的是Access, 那么情況就有所不同, 第一個(gè)網(wǎng)址的頁(yè)面與原頁(yè)面完全不同;第二個(gè)網(wǎng)址, 則視乎數(shù)據(jù)庫(kù)設(shè)置是否允許讀該系統(tǒng)表, 一般來(lái)說(shuō)是不允許的, 所以與原網(wǎng)址也是完全不同。 大多數(shù)情況下, 用第一個(gè)網(wǎng)址就可以得知系統(tǒng)所用的數(shù)據(jù)庫(kù)類型, 第二個(gè)網(wǎng)址只作為開啟IIS錯(cuò)誤提示時(shí)的驗(yàn)證。

 

們學(xué)會(huì)了SQL注入的判斷方法, 但真正要拿到網(wǎng)站的保密內(nèi)容, 是遠(yuǎn)遠(yuǎn)不夠的。 接下來(lái), 我們就繼續(xù)學(xué)習(xí)如何從數(shù)據(jù)庫(kù)中獲取想要獲得的內(nèi)容, 首先, 我們先看看SQL注入的一般步驟:

第一節(jié)、SQL注入的一般步驟

首先, 判斷環(huán)境, 尋找注入點(diǎn), 判斷數(shù)據(jù)庫(kù)類型, 這在入門篇已經(jīng)講過(guò)了。

其次, 根據(jù)注入?yún)?shù)類型, 在腦海中重構(gòu)SQL語(yǔ)句的原貌, 按參數(shù)類型主要分為下面三種:

(A)   ID=49 這類注入的參數(shù)是數(shù)字型, SQL語(yǔ)句原貌大致如下:

Select * from 表名 where 字段=49

注入的參數(shù)為ID=49 And [查詢條件], 即是生成語(yǔ)句:

Select * from 表名 where 字段=49 And [查詢條件]

(B) Class=連續(xù)劇 這類注入的參數(shù)是字符型, SQL語(yǔ)句原貌大致概如下:

Select * from 表名 where 字段=’連續(xù)劇’ 

注入的參數(shù)為Class=連續(xù)劇’ and [查詢條件] and ‘’=’ , 即是生成語(yǔ)句:

Select * from 表名 where 字段=’連續(xù)劇’ and [查詢條件] and ‘’=’’

(C) 搜索時(shí)沒(méi)過(guò)濾參數(shù)的, 如keyword=關(guān)鍵字, SQL語(yǔ)句原貌大致如下:

Select * from 表名 where 字段like ’%關(guān)鍵字%’ 

注入的參數(shù)為keyword=’ and [查詢條件] and ‘%25’=’, 即是生成語(yǔ)句:

Select * from 表名 where字段like ’%’ and [查詢條件] and ‘%’=’%’

接著, 將查詢條件替換成SQL語(yǔ)句, 猜解表名, 例如:

ID=49 And (Select Count(*) from Admin)>=0

如果頁(yè)面就與ID=49的相同, 說(shuō)明附加條件成立, 即表Admin存在, 反之, 即不存在(請(qǐng)牢記這種方法)。 如此循環(huán), 直至猜到表名為止。

表名猜出來(lái)后, 將Count(*)替換成Count(字段名), 用同樣的原理猜解字段名。

有人會(huì)說(shuō):這里有一些偶然的成分, 如果表名起得很復(fù)雜沒(méi)規(guī)律的, 那根本就沒(méi)得玩下去了。 說(shuō)得很對(duì), 這世界根本就不存在100%成功的黑客技術(shù), 蒼蠅不叮無(wú)縫的蛋, 無(wú)論多技術(shù)多高深的黑客, 都是因?yàn)閯e人的程序?qū)懙貌粐?yán)密或使用者保密意識(shí)不夠, 才有得下手。

有點(diǎn)跑題了, 話說(shuō)回來(lái), 對(duì)于SQLServer的庫(kù), 還是有辦法讓程序告訴我們表名及字段名的, 我們?cè)诟呒?jí)篇中會(huì)做介紹。

       最后, 在表名和列名猜解成功后, 再使用SQL語(yǔ)句, 得出字段的值, 下面介紹一種最常用的方法-Ascii逐字解碼法, 雖然這種方法速度很慢, 但肯定是可行的方法。

我們舉個(gè)例子, 已知表Admin中存在username字段, 首先, 我們?nèi)〉谝粭l記錄, 測(cè)試長(zhǎng)度:

http://www.19cn.com/showdetail.asp?id=49 ;;and (select top 1 len(username) from Admin)>0

先說(shuō)明原理:如果top 1的username長(zhǎng)度大于0, 則條件成立;接著就是>1、>2、>3這樣測(cè)試下去, 一直到條件不成立為止, 比如>7成立, >8不成立, 就是len(username)=8

  當(dāng)然沒(méi)人會(huì)笨得從0,1,2,3一個(gè)個(gè)測(cè)試, 怎么樣才比較快就看各自發(fā)揮了。 在得到username的長(zhǎng)度后, 用mid(username,N,1)截取第N位字符, 再asc(mid(username,N,1))得到ASCII碼, 比如:

id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0

同樣也是用逐步縮小范圍的方法得到第1位字符的ASCII碼, 注意的是英文和數(shù)字的ASCII碼在1-128之間, 可以用折半法加速猜解, 如果寫成程序測(cè)試, 效率會(huì)有極大的提高。

第二節(jié)、SQL注入常用函數(shù)

有SQL語(yǔ)言基礎(chǔ)的人, 在SQL注入的時(shí)候成功率比不熟悉的人高很多。 我們有必要提高一下自己的SQL水平, 特別是一些常用的函數(shù)及命令。

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

作用:返回某字符的ASCII碼

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

作用:與asc相反, 根據(jù)ASCII碼返回字符

Access:mid(字符串,N,L)   SQLServer:substring(字符串,N,L)

作用:返回字符串從N個(gè)字符起長(zhǎng)度為L(zhǎng)的子字符串, 即N到N+L之間的字符串

Access:abc(數(shù)字)   SQLServer:abc (數(shù)字)

作用:返回?cái)?shù)字的絕對(duì)值(在猜解漢字的時(shí)候會(huì)用到)

Access:A between B And C   SQLServer:A between B And C

作用:判斷A是否界于B與C之間

第三節(jié)、中文處理方法

       在注入中碰到中文字符是常有的事, 有些人一碰到中文字符就想打退堂鼓了。 其實(shí)只要對(duì)中文的編碼有所了解, “中文恐懼癥”很快可以克服。

先說(shuō)一點(diǎn)常識(shí):

Access中, 中文的ASCII碼可能會(huì)出現(xiàn)負(fù)數(shù), 取出該負(fù)數(shù)后用abs()取絕對(duì)值, 漢字字符不變。

SQLServer中, 中文的ASCII為正數(shù), 但由于是UNICODE的雙位編碼, 不能用函數(shù)ascii()取得ASCII碼, 必須用函數(shù)unicode ()返回unicode值, 再用nchar函數(shù)取得對(duì)應(yīng)的中文字符。

       了解了上面的兩點(diǎn)后, 是不是覺(jué)得中文猜解其實(shí)也跟英文差不多呢?除了使用的函數(shù)要注意、猜解范圍大一點(diǎn)外, 方法是沒(méi)什么兩樣的。

好了, 今天寫了這么多有點(diǎn)累了

大家自己看看吧   我想應(yīng)該可以把你這幾天學(xué)的關(guān)于SQL注入的種種東西作個(gè)總結(jié)吧。 頭腦中應(yīng)該有個(gè)清晰的認(rèn)識(shí)了吧

明天我們將說(shuō)如果碰到表名列名猜不到, 或程序作者過(guò)濾了一些特殊字符, 怎么提高注入的成功率?怎么樣提高猜解效率?

明天見 

 

忘了

想再?gòu)?qiáng)調(diào)一點(diǎn) 『特征字符的用法』

     我們?cè)谧⑷氲臅r(shí)候,通常是在網(wǎng)址后面加 and 1=1和 and 1=2去測(cè)試網(wǎng)址是否能注入

如果可以注入,一般有下面兩種情況:

A. and 1=1正常, and 1=2報(bào)HTTP錯(cuò)誤,這種情況,NBSI可以自動(dòng)做出判斷,無(wú)需輸入特征字符

B. and 1=1正常, and 1=2提示"找不到此記錄"之類的提示,但不報(bào)HTTP錯(cuò)誤,這時(shí),就需要我們輸入一個(gè)"特征字符",來(lái)幫助程序識(shí)別所傳入的SQL語(yǔ)句執(zhí)行結(jié)果是True還是False

   簡(jiǎn)單的說(shuō),"特征字符"就是 and 1=1頁(yè)面中包含有而 and 1=2頁(yè)面中不包含有的字符串.

 


上面是電腦上網(wǎng)安全的一些基礎(chǔ)常識(shí),學(xué)習(xí)了安全知識(shí),幾乎可以讓你免費(fèi)電腦中毒的煩擾。




標(biāo)簽:深入SQL注入