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