SQL注入
l 何謂“SQL注入”
SQL注入(SQL Injection),就是通過網站的漏洞,使用SQL命令(如:DML語句、DDL語句、SQL擴展存儲過程等)獲得網站正使用的數據庫的信息、修改數據庫記錄、讀取服務器的註冊表、追加Windows的帳號、修改Windows帳號的權限等。
l SQL注入的方式
現階段較爲流行的SQL注入工具一般是通過Get和Post方法進行注入。
l SQL注入是怎樣產生的
使用Get方式進行注入,一般存在於形如:http://xxx.xxx.xxx/abc.asp?id=XX等帶有參數的ASP動態網頁中,有時一個動態網頁中可能只有一個參數,有時可能有N個參數,有時是整型參數,有時是字符串型參數,不能一概而論。總之只要是帶有參數的動態網頁且此網頁訪問了數據庫,那麼就有可能存在SQL注入。如果ASP程序員沒有安全意識,不進行必要的字符過濾,存在SQL注入的可能性就非常大。
#注:字符過濾只是防止注入的一種方法,具體的請參照後面的介紹。
使用Post方式進行注入,一般存在於表單的提交中,因爲在表單的提交中基本上都會編碼,所以使用該方式進行注入比較困難,以下着重介紹Get方式的注入,Post方式的注入形同Get方式的注入。
l 如何判斷是否存在SQL注入
Ø 前期準備
IE的「ツール」→「インターネット オプション」→「 詳細設定」→ 「ブラウズ」中的「HTTPエラーメッセージを簡易表示する」前的勾去掉。 以獲得更多的錯誤提示信息。
Ø 注入驗證
對字符型參數:
因爲大多數網頁中對數據表的操作都是使用串連接的形式實現的,如下:
strSQL = “select * from TABLE where name=’”&strUsrName&”’ and password=’”& strPasswd & “’”
所以在檢驗是否存在注入,常見的方法是在參數後面加個半角的單引號,如:
http://xxx.xxx.xxx/abc.asp?id=XX’
當頁面被運行後,畫面出現以下錯誤時,認爲該網頁可以進行注入:
技術情報 (サポート擔當者用)
· エラー タイプ
Microsoft OLE DB Provider for SQL Server (0x80040E14)
文字列 '' の前で引用符が閉じていません。
/test/xxx.asp, line 40
這說明該頁面沒有對輸入的參數進行有效性檢查,即過濾單引號,則可以使用以下方式進行注入:
1、http://xxx.xxx.xxx.xxx/abc.asp?name=aaa’ or 1=1--
2、http://xxx.xxx.xxx.xx/abc.asp?name=aaa’;exec('create table temp ( [name] [char] (10)) ')--
對於整型參數:
對於整型參數來講,上面的方法就不大適用了,因爲對於整型參數,SQL代碼可能如下:
strSQL = “select * from TABLE where id=”& strID
即使程序中對strID參數中的單引號做了過濾,也可使程序產生注入,如下:
1、 http://xxx.xxx.xxx.xxx/abc.asp?id=1 or 1=1—
2、 http://xxx.xxx.xxx.xxx/abc.asp?id=1 ;exec('create table temp ( [name] [char] (10)) ')—
其中“--”在SQL中是註釋的意思,所以“--”之後的代碼均作爲註釋處理。
對於上面的字符型和整型參數的第1種情況,條件“or 1=1”會使strSQL語句中的where條件變得無效;而第2種情況,代碼會先執行分號之前的strSQL語句,然後執行exec後的SQL語句創建表,通過修改exec後的SQL語句,就可以通過你的數據庫鏈接,進行SQL注入的攻擊。
l SQL注入所產生的安全隱患
Ø 逃避安全驗證
從理論上說,認證網頁中會有形如:
select * from admin where username='XXX' and password='YYY' 的語句,若在正式運行此句之前,沒有進行必要的字符過濾,則很容易實施SQL注入。
如在用戶名文本框內輸入:abc’ or 1=1-- 在密碼框內輸入:123 則SQL語句變成:
select * from admin where username='abc’ or 1=1 and password='123’ 不管用戶輸入任何用戶名與密碼,此語句永遠都能正確執行,用戶輕易騙過系統,獲取合法身份。
Ø 修改數據表的信息
通過SQL注入的漏洞,能夠得到系統中表的相關信息,從而修改表的內容。
注:得到表的信息的方法可以參見網上提供的攻擊方法,這裏就不作介紹了。
Ø 追加Windows帳號/修改帳號權限
ASP木馬只有USER權限,要想獲取對系統的完全控制,還要有系統的管理員權限。怎麼辦?提升權限的方法有很多種:
上傳木馬,修改開機自動運行的.ini文件(它一重啓,便死定了);
複製CMD.exe到scripts,人爲製造UNICODE漏洞;
下載SAM文件,破解並獲取OS的所有用戶名密碼;
等等,視系統的具體情況而定,可以採取不同的方法。
Ø 修改註冊表
利用xp_regread擴展存儲過程修改註冊表。
另一個有用的內置存儲過程是xp_regXXXX類的函數集合(Xp_regaddmultistring, Xp_regdeletekey,Xp_regdeletevalue,Xp_regenumkeys,Xp_regenumvalues, Xp_regread,Xp_regremovemultistring,Xp_regwrite)。
攻擊者可以利用這些函數修改註冊表,如讀取SAM 值,允許建立空連接,開機自動運行程序等。
Ø 用其他存儲過程去改變服務器
Xp _servicecontrol過程允許用戶啓動,停止服務
Xp_availablemedia 顯示機器上有用的驅動器
Xp_dirtree 允許獲得一個目錄樹
Xp_enumdsn 列舉服務器上的ODBC數據源
Xp_loginconfig 獲取服務器安全信息
Xp_makecab 允許用戶在服務器上創建一個壓縮文件
Xp_ntsec_enumdomains 列舉服務器可以進入的域
Xp_terminate_process 提供進程的進程ID,終止此進程
攻擊者可以利用這些存儲過程來得到服務器信息,進而去攻擊服務器。
l SQL注入的防禦
其實SQL注入的方式不論是Post還是Get方式,注入的參數類型也就是字符型和整型兩種,對於這兩種參數類型的防禦,可以分別採取以下措施:
u 對參數進行判斷
Ø 字符型參數:
對能夠引起SQL注入的字符做替換處理,例如:
「'」→「''」
「/」→「//」
「%」→「/%」
「_」→「/_」
Ø 整型參數
對整型參數,在取得參數的值後,通過驗證參數值的類型的合法化,來避免SQL
的注入。
例如:
通過VBScript的函數IsNumeric來判斷整型參數的輸入值是否合法;
或者通過CLng函數進行對輸入值進行轉換,捕獲Err.Number的方式,來判斷整型參數的輸入值是否合法。
u PlaceHolder方式
<%
Set ObjConn = Server.CreateObject("ADODB.Connection")
ObjConn.Open "sample","dbuser","dbpass"
Set ObjCmd = Server.CreateObject("ADODB.Command")
ObjCmd.CommandText= "SELECT * FROM user WHERE userid=? AND password=?"
ObjCmd.CommandType = 1
ObjCmd.ActiveConnection = ObjConn
userid = Request.QueryString("userid")
Set ObjUserid = Server.CreateObject("ADODB.Parameter")
ObjUserid.Value = userid
ObjUserid.Size = Len(userid)
ObjUserid.Type = 200
ObjCmd.Parameters.Append ObjUserid
password = Request.QueryString("password")
Set ObjPassword = Server.CreateObject("ADODB.Parameter")
ObjPassword.Value = password
ObjPassword.Size = Len(password)
ObjPassword.Type = 200
ObjCmd.Parameters.Append ObjPassword
Set ObjRS = ObjCmd.Execute()
%>
使用上面的方法,可以將參數的檢查和無害化交由系統進行處理
l 總結
SQL注入產生的後果雖然很嚴重,但只要我們在編碼時進行正確的防禦就可以了,在Web應用中,無論是採用Post還是Get方式傳遞SQL的參數,要做到以下幾點:
1. 整型參數要驗證類型的合法化
2. 字符型參數要對特殊字符進行正確的替換
3. 對DB的操作儘量使用placeholder的方式
以上。