2011年12月2日 星期五

#SQL SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上)


需要對 SQL Injection 做一些防堵措施
防止系統崩潰

1.透過參數,去接所有輸入字串,並設定好資料型態,長度,內容檢查
2.顯示標準的錯誤訊息,預防試誤攻擊

以下是一些關於 SQL 以及系統安全的網址,提供給大家參考。
http://www.microsoft.com/sql/
http://www.microsoft.com/security/
http://www.sqlsecurity.com/
http://www.nextgenss.com/
http://www.atstake.com/
http://www.securityfocus.com/
http://www.appsecinc.com/
=============================================

[C#][ASP.NET]使用具名參數及SQL語法


為能有效的阻絕駭客利用『資料隱碼』方式入侵,微軟建議採取以下各項防範之道:
1. 加強程式上的安全檢查措施:在程式中加上輸入資料型態檢查、資料長度檢查與資料內容檢查,讓駭客無法利用隱藏於輸入資料的特殊指令或程式碼有機可乘
2. 妥善使用權限管理:在程式中勿用較高權限來存取資料庫,比如說讓SQL程式使用資料庫管理員(System Administrator, SA)身份來存取資料庫。此外,若使用Windows 2000作業系統搭配SQL Server則建議使用Windows 2000認證機制。 
3. 保持良好的程式開發習慣:撰寫資料庫存取或查詢程式時,利用兩個單引號『’’』來標註任何輸入的變數給SQL程式;利用單引號『’』會讓駭客的隱碼易於得逞 
4. 將核心程式碼隱藏起來:勿讓網頁上程式直接存取或查詢資料庫,而是透過預存程式(Stored-procedure)來執行,而XML Web Service也是另一個提高安全性的好方法,保護核心程式邏輯與資料庫結構不至外洩,而Microsoft SQL Server 2000是目前唯一支援XML Web Service的資料庫管理系統。 
5. 以標準的訊息回覆給客戶:電子商務網站對於任何回覆給客戶的訊息應有所規範,透過程式攔截下任何作業系統或資料庫管理系統所可能產生的錯誤訊息,改以統一且明確的訊息來指導客戶。 
6. 刪除多餘的資料表(Table):資料庫管理系統安裝後會有幾個既存的資料表,這些資料表是供程式開發、範例資料庫或暫存使用,如”pub”及”Northwind”等,請在電子商務網站上線後移除;因為這些公用的資料表架構是公開的,易為駭客所利用。

==============================================



SELECT * FROM tblUser WHERE UserName='admin'--' AND Password='asdf'

關鍵就是原先的 AND 子句被 “--" 標示成說明,也就是 SQL Server 僅僅執行
SELECT * FROM tblUser WHERE UserName='admin'





‘ or 1=1--

SQL Server 所接收的整個語法變成:
SELECT * FROM tblUser WHERE UserName='' or 1=1--' AND Password='asdf'
因為加上的 or 1=1,則不管之前的條件為合,只要某個條件為真,整個判斷式就都為真



========================================================


SQL Injection (資料隱碼)– 駭客的 SQL填空遊戲(上)
http://www.microsoft.com/taiwan/sql/sql_injection_g1.htm



對於預防 SQL Injection 的建議
綜合以上各種的侵入技巧,筆者在此歸納一些維護系統安全的建議。
  • 儘量地利用 ASP 或 ASP.NET 在伺服器端檢查與限制輸入變數的型別與長度,過濾掉不需要的內容。要注意的是這些檢查不要放在前端。
    就算在前端利用 HTML Input 標籤的 MaxLength 屬性,或是以 JScript 撰寫程式來設定欄位長度的限制,只要將該網頁另存新檔,修改內容後(一般只要改寫 Form 的 Action 屬性以及 Input 的 MaxLength 屬性),重新以瀏覽器開啟再執行便可避過這些瀏覽器端的檢查。
  •  ASP 程式登入 SQL Server 的帳號不要使用 sa,或任何屬於 Sysadmin 群組的帳號,避免有過大的權限。
  • sa 一定要有強固的密碼,尤其是 SQL Server 7.0 以前的版本,在裝機時預設 sa 沒有密碼,而一般管理者裝完後也忘了或怕麻煩而不更改密碼。
  • 利用 ADO 的 Command 物件或 ADO.NET 的 SqlCommand class 來透過參數執行 SQL 語法,直接以 ADODB 的 Connection 物件執行預存程序的寫法一樣糟糕。範例如下:
Exec spXXX 參數,…
因為駭客所加入的 SQL 語法一樣可以執行:
Exec spXXX 參數,…;SHUTDOWN
我們可以建立一個預存程序程式碼列表 5
ECREATE PROC spUserAccount
@UserName NVarchar(50),@Password NVarchar(50)
AS
SELECT UserName,Password FROM tblUser
WHERE UserName=@UserName AND Password=@Password
程式碼列表 5:用來找尋符合的使用者帳號密碼的預存程序。
同時將整個 ASP 的查詢換成如程式碼列表 6 的寫法:
<%
If Request("UserName")<>"" And Request("Pass")<>"" Then
Dim cnn,rec,strSQL,cmd
Set cnn=Server.CreateObject("ADODB.Connection")
With cnn
.ConnectionString=Application("Conn")
.Open
End With
'透過 ADODB.Command 物件來搭配預存程序,駭客就無法
'利用組合 SQL 字串的方式來侵入系統
Set cmd=Server.CreateObject("ADODB.Command")
With cmd
.ActiveConnection = cnn
.CommandText = "spUserAccount"
.CommandType = 4 'adCmdStoredProc
.Parameters.Append .CreateParameter("UserName", 202, 1, 50, Request("UserName"))
'202 代表 adVarWChar,1 代表 adParamInput
.Parameters.Append .CreateParameter("Password", 202, 1, 50, Request("Pass"))
Set rec = .Execute()
End With
If NOT rec.EOF Then
Session("UserName")=Request("UserName")
Response.Write "歡迎光臨 " & Request("UserName")
Else
Response.Write "您的帳號/密碼輸入錯誤"
End If
Else
%>
程式碼列表 6:利用 ADODB 的 Command 物件來存取預存程序。
如程式碼列表 6 中灰色的程式碼區塊,將存取 SQL Server 預存程序的方式改以透過 ADODB 的 Command 物件,如此駭客就不能用加入自訂 SQL 的語法來要求 SQL Server 執行額外的動作。
  • 改掉預設的 Web 虛擬路徑,不要使用 IIS 裝好後預設的 <系統所在磁碟>\Inetpub\WWWRoot 路徑,否則利用前述的檔案存取方式,很容易在該目錄下動手腳。
  • 不要顯示錯誤訊息到前端。
    利用 VBScript 語法的 On Error Resume Next,並搭配 If Err.Number<>0 Then 的錯誤處理方式,自行將錯誤重導到適當的錯誤處理網頁,如此系統將更穩固,且駭客也不易透過錯誤訊息來探知系統的內部運作方式。
    或著,也可以修改<系統所在磁碟>\WINNT\Help\iisHelp\common\500-100.asp 預設網頁,最簡單的方式就是將它更改名字3
  •  將用不到但功能強大的延伸預存程序刪除。
  •  監控系統的執行。
  •  防火牆關閉 TCP 1433/UDP 1434 埠(port)對外的連線4 。
  •  隨時注意是否有新的修補程式要上。
以上是針對 SQL Injection 防護方式的建議,但我們應該謹記於心的是世界上沒有絕對安全的系統,只有自己時時小心,多看多聽駭客們是否有翻新的手法,系統是否有異常的狀況,唯有不斷加強系統的安全措施,才能將危害降至最低。

=======================================================

在PHP裡面如何做到基本的SQL injection防禦?


游擊式的SQL Injection攻擊


http://blog.darkthread.net/post-2008-05-22-hit-and-run-sql-injection-attack.aspx



SQL Injection,說穿了,你不傳參數給SQL
就沒有SQL Injection的問題
SQL Injection攻擊的目的在於破壞你的SQL查詢語法的結構
但是,大部分的資料庫網站又不能有根據參數來查詢特定的資料
所以,唯一可以攔截SQL Injection語法的地方
就在於傳入參數的位置
我後來都寫成如下
declare @param1 nvarchar(50)
Select @param1 = N'%param1%'
Select Top 100
*
From [Table1]
Where (1 = 1)
And [name] = @param
這個查詢句中的『%param1%』會利用程式Replace成傳入的參數
Replace進去之前要多加一個動作 把 ' Replace成 ''
一個單引號,要置換成兩個單引號
例如:
QuerySQL = QuerySQL.Replace("%param1%", str_param.Replace("'", "''"))
這樣Replace進去的參數就會自動把一個單引號變成兩個單引號
剛好SQL語法中,會把字串中的兩個單引號 解釋為一個單引號
所以不管外面怎麼SQL Injection攻擊
通通被你轉成字串格式的SQL變數
轉進去的SQL變數再查詢的時候
可以再利用CAST的方式轉換成其他資料型態
一旦轉不過去發生錯誤訊息!就會阻擋SQL Injection取得你資料的能力!
以上經驗分享!
直接攔截傳進來的參數!
# 小新 said on 17 September, 2009 12:26 AM
另外在資料顯示的部份!
所有要顯示在網頁上的資料
最好都先用 Server.HtmlEncode() 過在顯示出來
因為很多隱碼攻擊,都是利用塞一些特殊的<script>來達成效果
所以在輸出的時候,你就已經先把字串Encode過了
這些字串再網頁上就不會變成HTML的一部份
而是完完整整把<script>以文字方式呈現!
這樣就更容易抓是否有被攻擊!
所以
進來的參數你如果有特別處理過了
顯示出去的資料,你也特別處理過了
隱碼攻擊就不容易在你的網站上施展!
他只好去攻擊別人的網站!
一些簡單的小技巧提供大家參考!

沒有留言:

張貼留言