獻(xiàn)給喜歡鼓搗黑客技術(shù)的你:輕松理解什么是 SQL 注入

將不受信任的數(shù)據(jù)作為命令或查詢的一部分發(fā)送到解析器時,會產(chǎn)生諸如 SQL 注入、NoSQL 注入、OS 注入和LDAP 注入的注入缺陷。攻擊者的惡意數(shù)據(jù)可以誘使解析器在沒有適當(dāng)授權(quán)的情況下執(zhí)行非預(yù) 期命令或訪問數(shù)據(jù)。SQL 注入是最普遍存在的,也是往年危害最大的漏洞,今天我們就來簡單理解關(guān)于 SQL 注入的一切。

SQL 注入的字面意思

學(xué)習(xí) SQL 注入首先要了解什么是 SQL,在百度百科的解釋如下:

結(jié)構(gòu)化查詢語言 (Structured Query Language) 簡稱 SQL,是一種特殊目的的編程語言,是一種數(shù)據(jù)庫查詢和程序設(shè)計語言,用于存取數(shù)據(jù)以及查詢、更新和管理關(guān)系數(shù)據(jù)庫系統(tǒng);同時也是數(shù)據(jù)庫腳本文件的擴(kuò)展名。

從解釋上來看,SQL 是用來對數(shù)據(jù)庫系統(tǒng)進(jìn)行操作的結(jié)構(gòu)化查詢語言,數(shù)據(jù)庫存儲數(shù)據(jù),SQL 就是用來告訴數(shù)據(jù)我要什么數(shù)據(jù),我要存儲什么樣的數(shù)據(jù)。

關(guān)于數(shù)據(jù)庫,通常分為兩類,一類是關(guān)系型數(shù)據(jù)庫,還有一類是非關(guān)系型數(shù)據(jù)庫,那么什么是關(guān)系型數(shù)據(jù)庫,百度百科的解釋如下:

關(guān)系數(shù)據(jù)庫,是建立在關(guān)系模型基礎(chǔ)上的數(shù)據(jù)庫,借助于集合代數(shù)等數(shù)學(xué)概念和方法來處理數(shù)據(jù)庫中的數(shù)據(jù)。標(biāo)準(zhǔn)數(shù)據(jù)查詢語言SQL就是一種基于關(guān)系數(shù)據(jù)庫的語言,這種語言執(zhí)行對關(guān)系數(shù)據(jù)庫中數(shù)據(jù)的檢索和操作。

當(dāng)前主流的關(guān)系型數(shù)據(jù)庫有 Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL、浪潮 K-DB 等。

關(guān)于非關(guān)系型數(shù)據(jù)庫,百度百科的解釋如下:

非關(guān)系型數(shù)據(jù)庫,又被稱為 NoSQL(Not Only SQL ),意為不僅僅是 SQL( Structured QueryLanguage,結(jié)構(gòu)化查詢語言),NoSqL 描述的是大量結(jié)構(gòu)化數(shù)據(jù)存儲方法的集合,根據(jù)結(jié)構(gòu)化方法以及應(yīng)用場合的不同,主要可以將 NOSQL 分為以下幾類:

(1)Column-Oriented

面向檢素的列式存儲,其存儲結(jié)構(gòu)為列式結(jié)構(gòu),同于關(guān)系型數(shù)據(jù)庫的行式結(jié)構(gòu),這種結(jié)構(gòu)會讓很多統(tǒng)計聚合操作更簡單方便,使系統(tǒng)具有較高的可擴(kuò)展性。這類數(shù)據(jù)庫還可以適應(yīng)海量數(shù)據(jù)的增加以及數(shù)據(jù)結(jié)構(gòu)的變化,這個特點與云計算所需的相關(guān)需求是相符合的,比如 GoogleAppengine 的 BigTable 以及相同設(shè)計理念的 Hadoop 子系統(tǒng)HaBase 就是這類的典州代表。需要特別指出的是,Big Table 特別適用于 MapReduce 處理,這對于云計算的發(fā)展有很高的適應(yīng)性。

(2)Key-Value。

面向高性能并發(fā)讀/寫的緩存存儲,其結(jié)構(gòu)類似于數(shù)據(jù)結(jié)構(gòu)中的 Hash 表,每個 Key 分別對應(yīng)一個 Value,能夠提供非??斓牟樵兯俣?、大數(shù)據(jù)存放量和高并發(fā)操作,非常適合通過主鍵對數(shù)據(jù)進(jìn)行查詢和修改等操作。Key-Value 數(shù)據(jù)庫的主要特點是具有極高的并發(fā)讀/寫性能,非常適作為緩存系統(tǒng)使用。MemcacheDB、BerkeleyDB、Redis、Flare 就是 Key-Value 數(shù)據(jù)庫的代表。

(3)Document-Oriented。

面向海量數(shù)據(jù)訪問的文檔存儲,這類存儲的結(jié)構(gòu)與 Key-Value 非常相似,也是每個 Key 別對應(yīng)一個 Value,但是這個 Value 主要以 JSOn(JavaSriptObjectNotations) 或者 XML 等格式的文檔來進(jìn)行存儲。這種存儲方式可以很方便地被面向?qū)ο蟮恼Z言所使用。這類數(shù)據(jù)庫可在海量的數(shù)據(jù)中快速查詢數(shù)據(jù),典型代表為 MongoDB、CouchDB 等。

在了解完 SQL 之后,我們來理解一下什么是注入:

注入:顧名思義就是插入的意思,在這里的意思就是在正常的 SQL 語句中,插入我們構(gòu)造的語句,在獲取正常結(jié)果的情況,執(zhí)行我們構(gòu)造的 SQL 語句獲取額外的數(shù)據(jù),導(dǎo)致數(shù)據(jù)泄漏。

通過實例了解 SQL 注入

在學(xué)習(xí) SQL 注入實例之前,大家要先明白一些 http 協(xié)議的基礎(chǔ),比如如何通過 GET/POST/cookie 的方式向頁面提交參數(shù)數(shù)據(jù),這里就不多說了,下面就以大家最熟悉的 php+mysql 作為例子來解釋 SQL 注入的過程。

我們就以最常見的 GET 來作為理解的對象,假設(shè)有一個查看個人信息的頁面,鏈接如下:

http://www.xxxxxx.com/userinfo.php?id=1

懂 http 協(xié)議的朋友肯定知道上面鏈接中哪個是提交的參數(shù),是我們可以控制的并任意修改的,在瀏覽器請求這個鏈接的時候,參數(shù) id 的值會被服務(wù)端,通過函數(shù)$_GET['id'] 獲取,正常的 sql 語句如下:

select * from users where id = $_GET['id'];

提交之前的鏈接后,id 的值 1 就會被帶入上面的查詢語句,如下:

select * from users where id = 1;

這樣做也沒什么不妥,功能完全實現(xiàn)了,但是有了這群不按常理出牌的人之后,就不安全了,平民老百姓沒人去修改 url 上的參數(shù),大部分根本不理解這個 url 是如何構(gòu)成的,所以世界本來是安全的,有了這些搞安全的,世界就不安全了。

當(dāng)我們把 url 改成下面這樣:

http://www.xxxxxx.com/userinfo.php?id=-1 union select database(

我們的參數(shù) id 的值就變成了 -1 union select database()這時的數(shù)據(jù)庫查詢語句就變成了:

select * from users where id = -1 union select database()

懂?dāng)?shù)據(jù)的肯定知道上面的語句的結(jié)果,返回的結(jié)果是原本程序做不到的,這就實現(xiàn)了 SQL 注入。

關(guān)于 SQL 注入有兩個方面,一個是 SQL 注入漏洞:

通過簡單的測試,測試這個參數(shù)存在 SQL 注入利用的可能就可以說這里存在 SQL 注入漏洞

還有一個就是 SQL 注入攻擊:

在確定存在 SQL 注入漏洞的情況下,通過手工或者工具的方式,將數(shù)據(jù)庫中的敏感信息 dump 出來或者利用數(shù)據(jù)庫的特定獲取系統(tǒng)的權(quán)限,這是一個利用的過程,在如今法律如此嚴(yán)格的情況下,在做滲透測試的時候,切記不要做這一步。

SQL 注入如何防御

從上面的例子可以看出,我們的參數(shù)是通過拼接字符串的方式進(jìn)行的,在寫 php 代碼的時候,通過 $_GET['id'] 獲取到參數(shù)值之后直接拼接到了 SQL 查詢語句的后面,不過你提交的參數(shù)是什么都被當(dāng)作 SQL 語句來執(zhí)行了,那么我們?nèi)绾谓鉀Q這個問題呢?

如今為了解決 SQL 注入的問題,從一開始的過濾到現(xiàn)在使用的數(shù)據(jù)庫操作的庫,使用參數(shù)化查詢的方式,將用戶輸入或者參數(shù)的值全部當(dāng)作字符串來處理,不管你輸入的是什么,在 SQL 查詢語句中,你就是一個字符串,這樣你構(gòu)造的查詢語句就被當(dāng)作字符串來處理了,語句不被執(zhí)行也就不會存在 SQL 注入的問題了。

俗話說,只要是用戶輸入的都不可以信任,一個系統(tǒng)用戶可控的參數(shù)千千萬,只要有一個地方疏忽,那你之前做的一切就前功盡棄了,擴(kuò)展一下,不僅僅是用戶輸入的不可信,只要是數(shù)據(jù)可以偽造的都不可信,比如 http 協(xié)議里的 Referer/user-agent 等。

總結(jié)

說了這么多廢話,這個文章的目的就是讓一些沒什么基礎(chǔ)的人了解一下大家常說的 SQL 注入相關(guān)的東西,從上面的描述可以看出,想要學(xué)習(xí) SQL 注入,最起碼的 http 協(xié)議是要學(xué)的,不同數(shù)據(jù)的查詢語句以及數(shù)據(jù)庫特性也是需要了解的,一個網(wǎng)站的數(shù)據(jù)處理流程也是需要了解的,在有基礎(chǔ)的情況下,了解 SQL 注入的原理,然后就是進(jìn)階階段,以前的大佬經(jīng)常發(fā)的文章關(guān)于繞過什么的,慢慢積累就可以了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容