2012年9月1日 星期六

面對SQL Injection,DBA可以做甚麼呢!

        難得公司請廠商做滲透測試,模擬駭客攻擊,我很好奇廠商會怎麼測試,所以同時間我也監控網站與資料庫的LOG,看看能從LOG裡讓我學到甚麼,當然最基本的SQL Injection與XSS一定會測試,身為DBA我當然最在意SQL Injection囉,而針對SQL Injection,我原本就做了以下前三項的設定
  1. 應用程式帳號權限最小化
  2. 限制中繼資料的可見性
  3. 稽核軌跡 
  4. 資料表(行)命名的考量

1.應用程式帳號權限最小化

        一般系統大多只會新增修改刪除及查詢資料,所以賦予帳號db_datareader與db_datawriter角色的權限就很合理,如果真有空且系統維護人員願意配合你,針對每個資料表來設定那更好囉

        若系統如有前後台之分,有的前台在internet,後台在intranet,更建議前後台使用不同的帳號,這樣權限就可以很容易區分開啦

        反正絕對不要給db_owner與sa這種太超過的權限就好

2.限制中繼資料的可見性

        像資料表、資料行、索引、檢查條件約束、觸發程序等名稱這些都算是中繼資料,要是使用者被授予某個資料表的Select權限,預設該使用者就能查到資料行的中繼資料,換言之駭客也能查到,看以下例子

USE master
GO
--建立test登入並指定密碼
CREATE LOGIN test WITH password ='qaz%123'
GO

--將使用者加入目前資料庫中
USE AdventureWorks
GO
CREATE USER test
GO
--只授予資料表SELECT權限
GRANT SELECT ON Person.Address TO test
GO

--模擬登入test
EXECUTE AS LOGIN='test'
SELECT SUSER_NAME(), USER_NAME()

--雖只有資料庫登入權限,但可查到中繼資料
SELECT * FROM sys.tables
SELECT * FROM sys.columns
SELECT * FROM sysobjects
GO



        預設僅有登入AdventureWorks資料庫權限,但卻可以查到所有資料庫的名稱


--記得將執行內容切回EXECUTE AS的呼叫者
revert
GO

         不覺得預設權限似乎大了點嗎?中繼資料可見性組態裡有提到中繼資料可見性組態在整體安全性計劃中扮演著重要的角色。但在某些情況中,技術純熟又執意操作的使用者還是能夠強制洩漏某些中繼資料。我們建議您將中繼資料權限部署為全面防禦中的一環。

        這不就是在講SQL Injection攻擊者要想辦法得到或猜到中繼資料嗎?所以當然要限制囉,怎麼限制很簡單,拒絕VIEW ANY DATABASE及VIEW DEFINITION權限,如下例子


--a.拒絕VIEW ANY DATABASE權限
USE master
GO
DENY VIEW ANY DATABASE TO test
GO
--b.拒絕VIEW DEFINITION權限
USE AdventureWorks
GO
DENY  VIEW definition TO test 
GO

--模擬登入test
EXECUTE AS LOGIN='test'
SELECT SUSER_NAME(), USER_NAME()
GO

--原本查得到的中繼資料現在都查不到囉
SELECT * FROM sys.tables
SELECT * FROM sys.columns
SELECT * FROM sysobjects
GO

--原本查的到所有資料庫名稱的,現在只查的到自己的與master,tempdb
SELECT [name] FROM sys.databases
SELECT DB_NAME()
GO


--記得將執行內容切回EXECUTE AS的呼叫者
revert
GO

        限制中繼資料的可見性能讓駭客不易從系統資料表取得資料表及資料行的名稱,要偷走資料就較困難

3.稽核軌跡

        啟用SQL Trace,除了追蹤一些基本的事件外,還追蹤Exception事件,因為資安事件多少會引發一些錯誤,所以排程定時去取TextData的錯誤訊息,發送mail通知給DBA,這樣才能及早發現問題,早點確認是否有資安事件發生

        我用Log Parser蒐集Web Log裡看起來異常的命令,先用unescape(java script與vb script都有的函數)解碼一遍,然後拿到資料庫執行看會不會產生錯誤,推敲引發這錯誤的目的為何?歸納如下表,紅字是會變動的,若各位用錯誤詢息的關鍵字拿來比對Trace檔裡TextData的內容,可以幫助判斷是否有SQL Injection攻擊喔,參考看看


        稍微說明一下像第一項,因為攻擊者通常不知道目標網站使用何種DB,反正就用自動化程式輪流try像這種ASCII字元轉換函數,各大DB好像都有類似的函數,SQL Server的字元轉換函數是CHAR,在Oracle對應的是CHR,亂槍打鳥一番,從錯誤回應中判斷是哪種DB Server囉,知道是哪種DB,就更好找對應的指令攻擊

        稽核軌跡我覺得還滿重要的,尤其是錯誤訊息的部分,可以及早發現異常攻擊,也可將錯誤提供給維護人員作前端應用程式debug的參考喔

4.資料表(行)命名的考量

        之前我都認為資料庫物件都使用名詞(有意義的名稱)來命名較為方便,比較容易判讀用途,但當我看到用字典檔暴力破解出資料表名稱的方法後,覺得用有意義的名稱命名反而不安全,萬一網站存有漏洞,而資料表命名又是有意義的,像現在駭客攻擊都是客製化的,蒐集的情資夠多,字典檔夠龐大,要猜出資料表名稱並不難,所以建議針對存有較敏感資料(個資法規範到的資料)的資料表,資料表(行)的名稱讓它無意義,或加上前後綴詞來防止被暴力破解出來,資料庫定序區分大小寫配合命名也大小寫也是一種方法




0 意見:

張貼留言