天天看點

sql注入攻擊的原理(sql注入攻擊防範)

SQL 注入(SQLi)是一種可執行惡意 SQL 語句的注入攻擊。這些 SQL 語句可控制網站背後的資料庫服務。攻擊者可利用 SQL 漏洞繞過網站已有的安全措施。他們可繞過網站的身份認證和授權并通路整個 SQL 資料庫的資料。他們也可利用 SQL 注入對資料進行增加、修改和删除操作。

SQL 注入可影響任何使用了 SQL 資料庫的網站或應用程式,例如常用的資料庫有 MySQL、Oracle、SQL Server 等等。攻擊者利用它,便能無需授權地通路你的敏感資料,比如:使用者資料、個人資料、商業機密、知識産權等等。SQL 注入是一種最古老、最流行、也最危險的網站漏洞。OWASP 組織(Open Web Application Security Project)在 2017 年的 OWASP Top 10 文檔中将注入漏洞列為對網站安全最具威脅的漏洞。

sql注入攻擊的原理(sql注入攻擊防範)

發起 SQL 注入攻擊的過程及原因

為了發起 SQL 注入攻擊,攻擊者首先需要在網站或應用程式中找到那些易受攻擊的使用者輸入。這些使用者輸入被有漏洞的網站或應用程式直接用于 SQL 查詢語句中。攻擊者可建立這些輸入内容。這些内容往往被稱為惡意載體,它們是攻擊過程中的關鍵部分。随後攻擊者将内容發送出去,惡意的 SQL 語句便會在資料庫中被執行。

SQL 是一種用于管理關系型資料庫中資料的查詢語言。你能使用它進行查詢、修改和删除資料。很多網站或應用程式将所有資料都存儲在 SQL 資料庫。有時候,你也可以使用 SQL 指令運作作業系統指令。是以,一次成功的 SQL 注入攻擊可能會引起非常嚴重的後果。

  • 攻擊者可利用 SQL 注入,從資料庫中得到其他使用者的使用者憑證。之後他們便能僞裝成這些使用者。這些使用者中甚至有可能包括有所有資料庫權限的資料庫管理者。
  • SQL 可用于從資料庫中選擇并輸出資料。SQL 注入漏洞允許攻擊者通路資料庫服務中的所有資料。
  • SQL 也可用于修改資料庫中資料,或者添加新資料。例如,在金融産品中,攻擊者能利用 SQL 注入修改餘額,取消交易記錄或給他們的賬戶轉賬。
  • SQL 可用于從資料庫中删除記錄,甚至删除資料表。即使管理者做了資料庫備份,在資料庫中資料恢複之前,被删除的資料仍然會影響應用的可用性。而且,備份很可能沒有覆寫最近的資料。
  • 在某些資料庫服務中,可通過資料庫服務通路作業系統。這種設計可能是有意的,也可能是無意的。在這種情況下,攻擊者将 SQL 注入作為初始手段,進而攻擊防火牆背後的内網。

SQL 注入攻擊的類型有:帶内 SQL 注入(使用資料庫錯誤或 UNION 指令)、盲目 SQL 注入和帶外 SQL 注入。你可在 SQL 注入的類型 和盲目 SQL 注入是什麼中了解更多資訊。

為了一步步了解如何發起 SQL 注入攻擊和它可能引起的嚴重後果,可參考運用 SQL 注入:動手實踐的例子。

簡單的 SQL 注入例子

第一個例子非常簡單。它展示了攻擊者如何利用 SQL 注入漏洞繞過應用安全防護和管理者認證。

以下腳本是執行在網站伺服器上的僞代碼。它是通過使用者名和密碼進行身份認證的簡單例子。該例子中資料庫有一張名為users的表,該表中有兩列資料:username和password。

# 定義 POST 變量
uname = request.POST['username']
passwd = request.POST['password']

# 存在 SQL 注入漏洞的 SQL 查詢語句
sql = “SELECT id FROM users WHERE username=’” + uname + “’ AND password=’” + passwd + “’”

# 執行 SQL 語句
database.execute(sql)      

這些輸入字段是容易遭受 SQL 注入攻擊的。攻擊者能夠在輸入字段中利用 SQL 指令,修改資料庫服務執行的 SQL 語句。比如,他們可使用含有單引号的把戲,将password字段設定為:

password' OR 1=1      

是以,資料庫服務将執行以下 SQL 查詢:

SELECT id FROM users WHERE username='username' AND password='password' OR 1=1'      

由于OR 1=1語句,無論username和password是什麼,WHERE分句都将傳回users表中第一個id。資料庫中第一個使用者的id通常是資料庫管理者。通過這種方式,攻擊者不僅繞過了身份認證,而且還獲得了管理者權限。他們也可以通過注釋掉 SQL 語句的後續部分,進一步控制 SQL 查詢語句的執行:

-- MySQL, MSSQL, Oracle, PostgreSQL, SQLite
' OR '1'='1' --
' OR '1'='1' /*
-- MySQL
' OR '1'='1' #
-- Access (using null characters)
' OR '1'='1' %00
' OR '1'='1' %16      

基于合并查詢的 SQL 注入例子

使用 UNION 操作符是最常見的 SQL 注入類型之一。它允許攻擊者将兩個或更多個 SELECT 語句的查詢結果合并為一個結果。這種技術被稱為基于合并查詢的 SQL 注入。

以下是這種注入攻擊的一個例子。該例子在testphp.vulnweb.com網頁上進行,該網頁是 Acunetix 維護的故意存在漏洞的網站。(譯者注:可以跟着該例子在 testphp.vulnweb.com 站點體驗 SQL 注入攻擊的過程。)

以下 HTTP 請求是一位使用者發送的合法正常請求:

GET http://testphp.vulnweb.com/artists.php?artist=1 HTTP/1.1
Host: testphp.vulnweb.com      
sql注入攻擊的原理(sql注入攻擊防範)

artist參數容易受到 SQL 注入攻擊。以下的載體修改了該參數,希望找到某個不存在的記錄。它設定該參數的值為-1。當然,它可以是資料庫中不存在的任意值。然而,負數往往是個好主意,因為資料庫中的 id 很少會是負數。

在 SQL 注入攻擊中,UNION操作符通常被用于在原始查詢語句中,附加惡意的 SQL 查詢語句,網站服務将執行所有查詢語句。注入的查詢語句的結果将和原始查詢語句的結果合并。這樣攻擊者便可以得到其他資料表中的資料。(譯者注:這步是為了示範當 UNION 之後的語句為SELECT 1, 2, 3時,頁面将輸出 2 和 3。)

GET http://testphp.vulnweb.com/artists.php?artist=-1 UNION SELECT 1, 2, 3 HTTP/1.1
Host: testphp.vulnweb.com      
sql注入攻擊的原理(sql注入攻擊防範)

接下來的例子展示了在這個存在漏洞的網站中,如何修改 SQL 注入的載體并得到有意義的資料:

GET http://testphp.vulnweb.com/artists.php?artist=-1 UNION SELECT 1,pass,cc FROM users WHERE uname='test' HTTP/1.1
Host: testphp.vulnweb.com      
sql注入攻擊的原理(sql注入攻擊防範)

如何防止 SQL 注入

防止 SQL 注入唯一可靠的方式是驗證輸入和參數化查詢,參數查詢包括預準備的查詢語句(譯者注:指存儲過程)。網站應用不應該在代碼中直接使用使用者輸入。開發者必須檢查所有使用者輸入,而不是僅檢查網頁表單中的輸入,比如登入表單。他們必須移除潛在的惡意代碼因素,比如單引号。在你的線上環境中屏蔽資料庫錯誤也是個好主意。因為結合資料庫錯誤,SQL 注入攻擊将獲得更多資料庫相關資訊。

如果你使用 Acunetix 掃描器發現了 SQL 注入漏洞,你可能不能立即修複它。比如,這個漏洞可能存在開源代碼中。在這種情況下,你可以臨時使用網站防火牆對輸入進行校驗。

參考在 PHP 應用中防止 SQL 注入漏洞并修複它們,了解在 PHP 語言中如何防止 SQL 注入攻擊。參考 Bobby Tables 教你阻止 SQL 注入攻擊,查找如何在其他程式設計語言中預防 SQL 注入攻擊。

如何預防 SQL 注入——通用技巧

預防 SQL 注入攻擊并不容易。特定的預防技術與 SQL 注入漏洞的子類型、SQL 資料庫引擎和程式設計語言有關。盡管如此,你仍然可以遵循一些通用政策來確定網站安全。

第一步:培養并保持安全意識

為了保證你的網站安全,所有參與搭建該網站的人員都必須意識到 SQL 注入漏洞相關的風險。你應該為所有開發者、測試員工、運維員工和系統管理者提供适量的安全教育訓練。你可以讓他們參考這篇文章作為安全教育訓練的開始。

第二步:不要信任任何使用者輸入

将所有使用者輸入都看作不可信的。任何被用作 SQL 查詢的使用者輸入都有 SQL 注入攻擊的風險。對待授權使用者或内部員工的輸入,也應該像對待外部使用者輸入一樣,将其視為不可信。

第三步:使用白名單,而不是黑名單

不要基于黑名單過濾使用者輸入。因為聰明的攻擊者總是能找到繞過黑名單的方法,是以應盡可能隻使用嚴格的白名單,對使用者輸入進行驗證和過濾。

第四步:采用最新的技術

更老的網站開發技術沒有防止 SQL 注入攻擊的保護機制。盡量使用最新版本的開發環境和開發語言,并使用與它們相關的新技術。例如,在 PHP 中應使用 PDO 而不是 MySQLi。

第五步:采用經過驗證的機制

不要嘗試從零開始建立應對 SQL 注入攻擊的防護機制。大多數現代開發技術已經為你提供了預防 SQL 注入攻擊的機制。你應該使用這些已有的技術,而不是嘗試重新造輪子。比如,使用參數化查詢和存儲過程(stored procedure)。

第六步:周期性掃描

SQL 注入漏洞可能被開發者引入,也可能被外部庫、子產品或軟體引入。你應該使用網站漏洞掃描器(比如 Acunetix)周期性掃描你的網站。如果你使用 Jenkins,你可以安裝 Acunetix 插件,實作每次建構時進行自動掃描。

請各位大牛以不參與,不破壞,不違法為第一原則