什么是SQL注入漏洞
SQL注入攻擊(SQL Injection),簡稱注入攻擊,SQL注入是web開發中最常見的一種安全漏洞。 SQL注入漏洞可以用來從數據庫獲取敏感信息,或者利用數據庫的特性執行添加用戶,導出文件等一系列惡意操作,甚至有可能獲取數據庫乃至系統最高權限
SQL注入漏洞原理
由于程序沒有過濾用戶的輸入,攻擊者通過響服務器提交惡意的SQL查詢語句,應用程序接收后錯誤的將攻擊者的輸入作為原始SQL查詢語句的一部分執行,導致改變了程序原始的SQL查詢邏輯,額外的執行了攻擊者構造的SQL查詢語句
SQL注入實例
1.類型1:數字型
2.$id = $_GET[id];
3.$sql = “SELECT * FROM “.$tablepre.”announcements WHERE id=$id”;
4.$result = $db->fetchsingleassocbysql( $sql );
5.$content = $result[‘content’];
提交 and 1=1,語句變成select * from tablepre announcements where id = 71 and 1=1 這時語句前值后值都為真,and以后也為真,返回查詢到的數據。執行了攻擊者額外的SQL查詢語句,導致SQL注入漏洞猜列名
1.類型2:字符型
2.$search = $_GET[key];
3.$sql = “SELECT * FROM users WHERE username LIKE ‘%$search%’ ORDER BY username”;
4.$result = $db->fetchsingleassocbysql( $sql );
5.$content = $result[‘content’];
提交%’order by id /* 語句變成SELECT * FROM users WHERE username LIKE ‘% %’ order by id /*ORDER BY username通過閉合單引號并閉合后面的原始語句,執行了攻擊者額外的SQL語句,導致SQL注入漏洞
PHP
參考:http://php.net/manual/zh/security.database.sql-injection.php
1.<?php
2.$offset = $argv[0]; // 注意,沒有輸入驗證!
3.$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
4.$result = pg_query($conn, $query);
5.?>
一般的用戶會點擊 $offset 已被斌值的“上一頁”、“下一頁”的鏈接。原本代碼只會認為 $offset 是一個數值。然而,如果有人嘗試把以下語句先經過 urlencode() 處理,然后加入URL中的話:
1.0;
2.insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
3.select 'crack', usesysid, 't','t','crack'
4.from pg_shadow where usename='postgres';
5.–
那么他就可以創建一個超級用戶了。注意那個 0; 只不過是為了提供一個正確的偏移量以便補充完整原來的查詢,使它不要出錯而已。
ASPX
1….
2.string userName = ctx.getAuthenticatedUserName();
3.string query = "SELECT * FROM items WHERE owner = '"
4. + userName + "' AND itemname = '"
5. + ItemName.Text + "'";
6.sda = new SqlDataAdapter(query, conn);
7.DataTable dt = new DataTable();
8.sda.Fill(dt);
9….
本代碼打算執行的查詢遵循:
1.SELECT * FROM items
2.WHERE owner = 'wiley'
3.AND itemname = 'name' OR 'a'='a';
但是,由于查詢的動態建立是通過連接常量庫查詢字符串和用戶輸入的字符串來實現的,因此只有在itemName中不包含單引號字符時,查詢才能正確執行。
如果攻擊者以用戶名”wiley”進入字符串"name' OR 'a'='a"作為itemName,那么查詢就會變成:
1.SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR 'a'='a';
增加的OR 'a'='a'條件會導致WHERE子句的估值始終為true
因此查詢在邏輯上就等同于一個更為簡單的查詢:SELECT * FROM items;
查詢的這種簡化使攻擊者能夠繞過查詢只返回身份驗證合格的用戶所擁有的項目的要求;而查詢現在所返回的是存儲在項目表中的所有條目,不論所有者是誰。
SQL注入的位置
無論是內網環境還是外網環境(互聯網),B/S架構的Web應用(以下指網站)都直接或者間接地受到各種類型的Web攻擊的影響。
對于后臺數據庫來說,以SQL注入攻擊危害最為普遍,由于網站服務端語言自身的缺陷與程序員編寫代碼的安全意識不足,攻擊者可以將惡意SQL語句注入到正常的數據庫操作指令中去,從而使該惡意SQL語句在后臺數據庫中被解析執行。
在SQL注入攻擊之前,首先要找到網站中各類與數據庫形成交互的輸入點。通常情況下,一個網站的輸入點包括:
1.表單提交,主要是POST請求,也包括GET請求。
2.URL參數提交,主要為GET請求參數。
3.Cookie參數提交。
4.HTTP請求頭部的一些可修改的值,比如Referer、User_Agent等。
5.一些邊緣的輸入點,比如.mp3文件的一些文件信息等。
服務端從客戶端直接或間接獲取數據的過程都是一次輸入過程, 無論直接或間接,默認情況下輸入的數據都應該認為是不安全的。
上面列舉的幾類輸入點,只要任何一點存在過濾不嚴,過濾缺陷等問題, 都有可能發生SQL注入攻擊。
大多數情況下,SQL注入的過程都是由工具完成的, 其中包括大批量注入工具的使用。
SQL注入的危害
這些危害包括但不局限于:
數據庫信息泄漏:數據庫中存放的用戶的隱私信息的泄露。
網頁篡改:通過操作數據庫對特定網頁進行篡改。
網站被掛馬,傳播惡意軟件:修改數據庫一些字段的值,嵌入網馬鏈接,進行掛馬攻擊。
數據庫被惡意操作:數據庫服務器被攻擊,數據庫的系統管理員帳戶被竄改。
服務器被遠程控制,被安裝后門。經由數據庫服務器提供的操作系統支持,讓黑客得以修改或控制操作系統。
破壞硬盤數據,癱瘓全系統。
一些類型的數據庫系統能夠讓SQL指令操作文件系統,這使得SQL注入的危害被進一步放大。
常見的SQL注入測試工具
##Pangolin , http://www.nosec.org/
##Scrawlr , https://download.spidynamics.com/Products/scrawlr/
SQL注入漏洞的解決方案
解決SQL注入問題的關鍵是對所有可能來自用戶輸入的數據進行嚴格的檢查、對數據庫配置使用最小權限原則。
1.所有的查詢語句都使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到SQL語句中。當前幾乎所有的數據庫系統都提供了參數化SQL語句執行接口,使用此接口可以非常有效的防止SQL注入攻擊。
2.對進入數據庫的特殊字符('"尖括號&*;等)進行轉義處理,或編碼轉換。
3.嚴格限制變量類型,比如整型變量就采用intval()函數過濾,數據庫中的存儲字段必須對應為int型。
4.數據長度應該嚴格規定,能在一定程度上防止比較長的SQL注入語句無法正確執行。
5.網站每個數據層的編碼統一,建議全部使用UTF-8編碼,上下層編碼不一致有可能導致一些過濾模型被繞過。
6.嚴格限制網站用戶的數據庫的操作權限,給此用戶提供僅僅能夠滿足其工作的權限,從而最大限度的減少注入攻擊對數據庫的危害。
7.避免網站顯示SQL錯誤信息,比如類型錯誤、字段不匹配等,防止攻擊者利用這些錯誤信息進行一些判斷。
8.在網站發布之前建議使用一些專業的SQL注入檢測工具進行檢測,及時修補這些SQL注入漏洞。
9.確認PHP配置文件中的magicquotesgpc選項保持開啟