SQL Injection(SQL 注入、SQLi) 攻擊原理:
SQLi 為駭客常用的攻擊方式之一,其原理是由於程式有漏洞,沒有過濾使用者的輸入,因此攻擊者得以輸入惡意的字串(通常能改變 SQL 語法上的邏輯),令資料庫 (Database) 誤認為這些惡意字串是 SQL 指令的一部分而執行,從而取得資料庫的內容,並對內容(包含會員的帳號,密碼)進行竊取、假冒以及刪除等操作,。
圖片來源: SQL Injection 的多種攻擊方式與防護討論
舉例來說:
網站的會員登入時,需要輸入帳號與密碼, 而 PHP 等後端程式判定輸入的帳號、密碼比對資料庫的資料,來確定登入是否成功 ,PHP 執行的 SQL 語法如下:
從 Users 這個資料表中,取出符合 user_id 為 iamuser,且 password 為 newpassword 的會員資料。
select * from Users where user_id ='iamuser' and password ='newpassword';
[ SQL Injection ]
若是駭客輸入特殊字元
帳號: ' or 1=1 --
密碼:任意值 (甚至不用輸入)
SQL 語法變成:
select * from Users where user_id ='' or 1=1 -- and password ='newpassword';
- 因為「
--
」在 MySQL 語法中代表註解的意思,所以「--
」後面的字串會被認為是註解而不執行。 - where 後面剩下判斷 user_id 是否為空值,或者 1 是否等於 1,因為
1 = 1
永遠為true
,且 password 因被註解掉而可忽略,所以攻擊者成功登入此網站。 - SQL 語法的註解
「/*
」 MySQL
「--
」 MsSQL
SQL Injection 攻擊目的:
攻擊者這麼做能幹嘛?對他們有什麼好處?
- 偽裝目標身份:取得資料庫伺服器管理權限,取得系統較高權限後,有可能得以在網頁加入惡意連結以及 XSS(例如 ALTER LOGIN sa WITH PASSWORD=’xxxxxx’)。
- 修改現有資料:例如取消交易、取出系統內的資料,破壞、覆蓋或刪除資料,甚至使其無法連線
- 竄改網站以及公開儲存在資料庫內的個人識別資料、帳密和敏感公司資料
- 資料結構被駭客探知,得以做進一步攻擊(例如 SELECT * FROM sys.tables)。
- 經由資料庫伺服器提供的作業系統支援,讓駭客得以修改或控制作業系統(例如 xp_cmdshell “net stop iisadmin” 可停止伺服器的 IIS 服務)。
- 破壞硬碟資料,癱瘓全系統(例如 xp_cmdshell “FORMAT C:”)。
- 被攻擊者執行毀滅性的指令:
Truncate tables
、Drop tables
如何防範 SQL Injection 攻擊:
跳脫參數 Escape Parameters
SQLi 的原理為沒有過濾使用者的輸入,因此用正規化的方式驗證過濾的輸入值,將含有 SQL 指令過濾掉、或是將單引號變換成雙引號。缺點:
- SQL 語法關鍵字一旦新增,檢查規則就要跟著改變
- 總會有漏網之魚,無法全面防範
參數化查詢 Query Parameterization
參數化查詢的原理就是資料庫語法中的佔位符號。
例如:SELECT * FROM person WHERE name = $1 AND password = $2
如此一來,即使使用者輸入的參數有不當的指令,丟進去的參數不會被當作 SQL 語法去執行!
[ PHP 的 Prepare Statement ]
- 把參數都改成問號 (?) 代替
- bind_param() 的第一個參數,有幾個參數就要寫幾個,記得按照資料類型。
- 字串 string => s
數字 int => i
<?php // 1.將 SQL 語法進行 prepare statement,並把參數都換為問號(?) $stmt = $conn->prepare("select * from Users where user_id= ? and password= ?"); // 2.替換成想要的參數 // bind_param('依序寫下參數的資料類型,有幾個?就寫幾個',要換的第一個參數,要換的第二個參數,...,要換的第 n 個參數) $stmt->bind_param('ss', $username, $password); // 3. 執行 query 語法 $stmt->execute(); // 4. $result 為 query 的執行結果 $result = $stmt->getResult(); // 5. 如果 $result 的結果大於 0 筆 // 則 $row 為從 $result 中取出的每筆資料 if ($result->num_rows > 0) { $row = $result->fetch_assoc(); } ?>
白名單機制 White List
白名單的機制就是檢查使用者輸入的欄位一定只能是那些固定的值,例如使用者就只能輸入 lastname or firstname,也就是限制只能輸入的欄位名稱。其他
- 將伺服器與資料庫部屬在不同的機器上,並保持更新狀態。
- 部屬 Web 應用程式防火牆,過濾掉 OSI 應用層的威脅,一般防火牆只會顧到網路層、傳輸層間的威脅,對於應用層較為忽略。
- 盡量不要取容易被猜取的資料庫、資料表名稱 (但有可能造成維護人員的不易)。
- 在不需要使用到更新、插入資料時,資料庫以 view 方式處理供使用者查詢資料。
- 將資料庫預設帳號、密碼關閉,提高資料庫存取權限
參考來源:
- SQL 注入@MDN
- 企業常遇到的四種網頁注入(Web Injection)攻擊
- [第十二週] 資訊安全 - 常見攻擊:XSS、SQL Injection
SQL Injection - SQL Injection 常見的駭客攻擊方式
- SQL Injection 的多種攻擊方式與防護討論
- 一次看懂 SQL Injection 的攻擊原理
- 何謂資料隱碼 (SQL injection) 攻擊?程式設計師應如何預防?
- 資安滲透攻防筆記 - 1
- [Postx1] 攻擊行為-SQL 資料隱碼攻擊 SQL injection
- SQL injection 原理介紹與防範教學 - 工程師絕不能犯的低級錯誤!
- Sql injection 幼幼班