SQL注射/SQL Injection漏洞

wyzsk發表於2020-08-19
作者: xsser · 2013/01/09 18:07

0x00 相關背景介紹 隨著網際網路web和資訊科技的發展,在web後端作為儲存和管理的的資料庫也得到了廣泛的應用,與web結合較為緊密的資料庫包括Mysql,Sqlserver,Oracle,Sqllite,Db2,Access等等。 資料儲存和管理作為應用的一個基本需求,在絕大多數的應用裡都得到了使用,這種大面積的使用也意味著在資料庫操作方面如果處理不當出現問題的可能性會很大,另外一方面由於資料庫承載了應用的資料資訊,如果資料庫出現問題一方面可能導致敏感資料的洩露和篡改(如信用卡賬戶,使用者密碼,管理賬戶和密碼,銷售記錄等等),直接導致損失和應用被攻陷,另外一方面,即使資料庫中不承載較為敏感的資訊,由於資料庫的特殊性,資料庫被攻擊的話也可以直接導致應用程式崩潰及其他嚴重的後果。 0x01 成因 應用為了和資料庫進行溝通完成必要的管理和儲存工作,必須和資料庫保留一種介面。目前的資料庫一般都是提供api以支援管理,應用使用底層開發語言如Php,Java,asp,Python與這些api進行通訊。對於資料庫的操作,目前普遍使用一種SQL語言(Structured Query Language語言,SQL語言的功能包括查詢、操縱、定義和控制,是一個綜合的、通用的關聯式資料庫語言,同時又是一種高度非過程化的語言,只要求使用者指出做什麼而不需要指出怎麼做),SQL作為字串透過API傳入給資料庫,資料庫將查詢的結果返回,資料庫自身是無法分辨傳入的SQL是合法的還是不合法的,它完全信任傳入的資料,如果傳入的SQL語句被惡意使用者控制或者篡改,將導致資料庫以當前呼叫者的身份執行預期之外的命令並且返回結果,導致安全問題。 那麼惡意使用者如何才能控制傳入的SQL語句呢?我們知道,既然傳入的SQL是以字串的方式傳入的,這個字串由應用生成,那麼如果應用生成這個字串的方式不對將可能導致問題,譬如考慮如下的功能:

$sql="select * from members where userid=".$_GET[userid];

$sb->query($sql); 
這段程式碼的邏輯是根據使用者請求的Userid進入資料庫查詢出不同的使用者並且返回給使用者,可以看到最終傳入的字串有一部分是根據使用者的輸入來控制的,一旦使用者提交
poc.php?userid=1 or 1=1
最終進入程式之後傳入資料庫的邏輯將是
$sb->query("select * from members where userid=1 or 1=1");
使用者完全可以根據傳入的內容來控制整個SQL的邏輯,實現間接控制和管理資料庫的目的,這種命令(SQL語句)和資料(使用者提交的查詢)不分開的實現方式導致了安全漏洞的產生。 由於不同的開發語言可能對api進行了不同的封裝,並且各種語言內部對資料的校驗會有不同的要求,譬如java和python屬於變數強型別並且各種開發框架的流行導致出現SQL注射的機率較小,php屬於弱型別不會對資料進行強制的驗證加上過程化的程式編寫思路導致出現注射的機率會較大。 0x02 攻擊方式及危害 透過典型的SQL注射漏洞,駭客是可以根據所能控制的內容在SQL語句的上下文導致不同的結果的,這種不同主要體現在不同的資料庫特性上和細節上。同時,後端的資料庫的不同導致駭客能利用SQL語句進行的操作也並不相同,因為很多的資料庫在標準的SQL之外也會實現一些自身比較特別的功能和擴充套件,常見的有Sqlserver的多語句查詢,Mysql的高許可權可以讀寫系統檔案,Oracle經常出現的一些系統包提權漏洞。 即使一些SQL注射本身無法對資料本身進行一些高階別的危害,譬如一些資料庫裡可能沒有儲存私密資訊,利用SQL查詢的結果一樣可能對應用造成巨大的災難,因為應用可能將從資料庫裡提取的資訊做一些其他的比較高危險的動作,譬如進行檔案讀寫,這種本身無價值的資料和查詢一旦被應用本身賦予較高的意義的話,可能一樣導致很高的危害。 評估一個SQL注射的危害需要取決於注射點發生的SQL語句的上下文,SQL語句在應用的上下文,應用在資料庫的上下文,綜合考慮這些因素來評估一個SQL注射的影響,在無上述利用結果的情況下,透過web應用向資料庫傳遞一些資源要求極高的查詢將導致資料庫的拒絕服務,這將是駭客可能能進行的最後的利用。 0x03 實際案例 WooYun: 新浪SAE淪陷,oauth token/安全密碼全部洩露,hack任意app 由於資料庫連結的許可權過於集中,透過構造合適的SQL語句,惡意使用者竊取當前資料庫連線裡所有的資料,從一個本不是特別嚴重的資料庫查詢處攻擊成功到較為敏感的資料,從而實現一個安全漏洞的最大的破壞。 WooYun: 搜狐女人頻道SQL注射漏洞 同樣由於程式對資料過濾不嚴,導致使用者可以控制程式處理的SQL語句,本身該查詢對資料進行攻擊的意義並不大,因為資料庫裡不包含特別敏感的資訊,精心構造該SQL語句可以將取回的結果反作用於程式,利用程式對結果的處理(這裡是將取回的資料進行讀模板操作),將導致可以在伺服器上執行命令,從而演變為一個高危險的漏洞。 0x04 修復方案 比較傳統的修復方式一般認為是對輸入的資料進行有效的過濾,但是由於輸入的來源太過廣泛,可能來自於資料庫,HTTP請求,檔案或者其他的資料來源,較難對所有進入的資料在各種場景下進行有效的過濾。 事實上最罪惡的不是資料,而是我們使用資料的方式,最為徹底的修復一定要查詢最為徹底的根源,我們可以看到最後的根源在於對資料和指令的不分離,所以在修復的時候應該極力將資料和指令分離。目前較為提倡的,同時在各種資料庫操作框架裡體現的方式就是以填充模板的方式來代替傳統的拼接的方式進行資料庫查詢,譬如:
$SqlTemplate="select * from members where userid={userid|int}";

$sb->PreSql($SqlTemplate,$_GET['userid']); 
模板裡有關資料及資料自身意義的描述,PreSql方法將實現將模板和資料安全的轉換為SQL語句的功能,以保障最終的安全的實現。 0x05 相關其他安全問題 0x06 相關資源
本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章