將不受信任的數(shù)據(jù)作為命令或查詢(xún)的一部分發(fā)送到解析器時(shí)庭猩,會(huì)產(chǎn)生諸如 SQL 注入窟她、NoSQL 注入、OS 注入和LDAP 注入的注入缺陷蔼水。攻擊者的惡意數(shù)據(jù)可以誘使解析器在沒(méi)有適當(dāng)授權(quán)的情況下執(zhí)行非預(yù) 期命令或訪問(wèn)數(shù)據(jù)礁苗。SQL 注入是最普遍存在的,也是往年危害最大的漏洞徙缴,今天我們就來(lái)簡(jiǎn)單理解關(guān)于 SQL 注入的一切试伙。
SQL 注入的字面意思
學(xué)習(xí) SQL 注入首先要了解什么是 SQL,在百度百科的解釋如下:
結(jié)構(gòu)化查詢(xún)語(yǔ)言 (Structured Query Language) 簡(jiǎn)稱(chēng) SQL于样,是一種特殊目的的編程語(yǔ)言疏叨,是一種數(shù)據(jù)庫(kù)查詢(xún)和程序設(shè)計(jì)語(yǔ)言,用于存取數(shù)據(jù)以及查詢(xún)穿剖、更新和管理關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)蚤蔓;同時(shí)也是數(shù)據(jù)庫(kù)腳本文件的擴(kuò)展名。
從解釋上來(lái)看糊余,SQL 是用來(lái)對(duì)數(shù)據(jù)庫(kù)系統(tǒng)進(jìn)行操作的結(jié)構(gòu)化查詢(xún)語(yǔ)言秀又,數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù),SQL 就是用來(lái)告訴數(shù)據(jù)我要什么數(shù)據(jù)贬芥,我要存儲(chǔ)什么樣的數(shù)據(jù)吐辙。
關(guān)于數(shù)據(jù)庫(kù),通常分為兩類(lèi)蘸劈,一類(lèi)是關(guān)系型數(shù)據(jù)庫(kù)昏苏,還有一類(lèi)是非關(guān)系型數(shù)據(jù)庫(kù),那么什么是關(guān)系型數(shù)據(jù)庫(kù),百度百科的解釋如下:
關(guān)系數(shù)據(jù)庫(kù)贤惯,是建立在關(guān)系模型基礎(chǔ)上的數(shù)據(jù)庫(kù)洼专,借助于集合代數(shù)等數(shù)學(xué)概念和方法來(lái)處理數(shù)據(jù)庫(kù)中的數(shù)據(jù)。標(biāo)準(zhǔn)數(shù)據(jù)查詢(xún)語(yǔ)言SQL就是一種基于關(guān)系數(shù)據(jù)庫(kù)的語(yǔ)言孵构,這種語(yǔ)言執(zhí)行對(duì)關(guān)系數(shù)據(jù)庫(kù)中數(shù)據(jù)的檢索和操作屁商。
當(dāng)前主流的關(guān)系型數(shù)據(jù)庫(kù)有 Oracle、DB2颈墅、PostgreSQL蜡镶、Microsoft SQL Server、Microsoft Access精盅、MySQL、浪潮 K-DB 等谜酒。
關(guān)于非關(guān)系型數(shù)據(jù)庫(kù)叹俏,百度百科的解釋如下:
非關(guān)系型數(shù)據(jù)庫(kù),又被稱(chēng)為 NoSQL(Not Only SQL )僻族,意為不僅僅是 SQL( Structured QueryLanguage粘驰,結(jié)構(gòu)化查詢(xún)語(yǔ)言),NoSqL 描述的是大量結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)方法的集合述么,根據(jù)結(jié)構(gòu)化方法以及應(yīng)用場(chǎng)合的不同蝌数,主要可以將 NOSQL 分為以下幾類(lèi):
(1)Column-Oriented
面向檢素的列式存儲(chǔ),其存儲(chǔ)結(jié)構(gòu)為列式結(jié)構(gòu)度秘,同于關(guān)系型數(shù)據(jù)庫(kù)的行式結(jié)構(gòu)顶伞,這種結(jié)構(gòu)會(huì)讓很多統(tǒng)計(jì)聚合操作更簡(jiǎn)單方便,使系統(tǒng)具有較高的可擴(kuò)展性剑梳。這類(lèi)數(shù)據(jù)庫(kù)還可以適應(yīng)海量數(shù)據(jù)的增加以及數(shù)據(jù)結(jié)構(gòu)的變化唆貌,這個(gè)特點(diǎn)與云計(jì)算所需的相關(guān)需求是相符合的,比如 GoogleAppengine 的 BigTable 以及相同設(shè)計(jì)理念的 Hadoop 子系統(tǒng)HaBase 就是這類(lèi)的典州代表垢乙。需要特別指出的是锨咙,Big Table 特別適用于 MapReduce 處理,這對(duì)于云計(jì)算的發(fā)展有很高的適應(yīng)性追逮。
(2)Key-Value酪刀。
面向高性能并發(fā)讀/寫(xiě)的緩存存儲(chǔ),其結(jié)構(gòu)類(lèi)似于數(shù)據(jù)結(jié)構(gòu)中的 Hash 表钮孵,每個(gè) Key 分別對(duì)應(yīng)一個(gè) Value骂倘,能夠提供非常快的查詢(xún)速度巴席、大數(shù)據(jù)存放量和高并發(fā)操作稠茂,非常適合通過(guò)主鍵對(duì)數(shù)據(jù)進(jìn)行查詢(xún)和修改等操作。Key-Value 數(shù)據(jù)庫(kù)的主要特點(diǎn)是具有極高的并發(fā)讀/寫(xiě)性能,非常適作為緩存系統(tǒng)使用睬关。MemcacheDB诱担、BerkeleyDB、Redis电爹、Flare 就是 Key-Value 數(shù)據(jù)庫(kù)的代表蔫仙。
(3)Document-Oriented。
面向海量數(shù)據(jù)訪問(wèn)的文檔存儲(chǔ)丐箩,這類(lèi)存儲(chǔ)的結(jié)構(gòu)與 Key-Value 非常相似摇邦,也是每個(gè) Key 別對(duì)應(yīng)一個(gè) Value,但是這個(gè) Value 主要以 JSOn(JavaSriptObjectNotations) 或者 XML 等格式的文檔來(lái)進(jìn)行存儲(chǔ)。這種存儲(chǔ)方式可以很方便地被面向?qū)ο蟮恼Z(yǔ)言所使用屎勘。這類(lèi)數(shù)據(jù)庫(kù)可在海量的數(shù)據(jù)中快速查詢(xún)數(shù)據(jù)施籍,典型代表為 MongoDB、CouchDB 等概漱。
在了解完 SQL 之后丑慎,我們來(lái)理解一下什么是注入:
注入:顧名思義就是插入的意思,在這里的意思就是在正常的 SQL 語(yǔ)句中瓤摧,插入我們構(gòu)造的語(yǔ)句竿裂,在獲取正常結(jié)果的情況,執(zhí)行我們構(gòu)造的 SQL 語(yǔ)句獲取額外的數(shù)據(jù)照弥,導(dǎo)致數(shù)據(jù)泄漏腻异。
通過(guò)實(shí)例了解 SQL 注入
在學(xué)習(xí) SQL 注入實(shí)例之前,大家要先明白一些 http 協(xié)議的基礎(chǔ)这揣,比如如何通過(guò) GET/POST/cookie 的方式向頁(yè)面提交參數(shù)數(shù)據(jù)悔常,這里就不多說(shuō)了,下面就以大家最熟悉的 php+mysql 作為例子來(lái)解釋 SQL 注入的過(guò)程给赞。
我們就以最常見(jiàn)的 GET 來(lái)作為理解的對(duì)象这嚣,假設(shè)有一個(gè)查看個(gè)人信息的頁(yè)面,鏈接如下:
http://www.xxxxxx.com/userinfo.php?id=1
懂 http 協(xié)議的朋友肯定知道上面鏈接中哪個(gè)是提交的參數(shù)塞俱,是我們可以控制的并任意修改的姐帚,在瀏覽器請(qǐng)求這個(gè)鏈接的時(shí)候,參數(shù) id 的值會(huì)被服務(wù)端障涯,通過(guò)函數(shù)$_GET['id'] 獲取罐旗,正常的 sql 語(yǔ)句如下:
select * from users where id = $_GET['id'];
提交之前的鏈接后,id 的值 1 就會(huì)被帶入上面的查詢(xún)語(yǔ)句唯蝶,如下:
select * from users where id = 1;
這樣做也沒(méi)什么不妥九秀,功能完全實(shí)現(xiàn)了,但是有了這群不按常理出牌的人之后粘我,就不安全了鼓蜒,平民老百姓沒(méi)人去修改 url 上的參數(shù)痹换,大部分根本不理解這個(gè) url 是如何構(gòu)成的,所以世界本來(lái)是安全的都弹,有了這些搞安全的娇豫,世界就不安全了。
當(dāng)我們把 url 改成下面這樣:
http://www.xxxxxx.com/userinfo.php?id=-1 union select database(
我們的參數(shù) id 的值就變成了 -1 union select database()這時(shí)的數(shù)據(jù)庫(kù)查詢(xún)語(yǔ)句就變成了:
select * from users where id = -1 union select database()
懂?dāng)?shù)據(jù)的肯定知道上面的語(yǔ)句的結(jié)果畅厢,返回的結(jié)果是原本程序做不到的冯痢,這就實(shí)現(xiàn)了 SQL 注入。
關(guān)于 SQL 注入有兩個(gè)方面框杜,一個(gè)是 SQL 注入漏洞:
通過(guò)簡(jiǎn)單的測(cè)試浦楣,測(cè)試這個(gè)參數(shù)存在 SQL 注入利用的可能就可以說(shuō)這里存在 SQL 注入漏洞
還有一個(gè)就是 SQL 注入攻擊:
在確定存在 SQL 注入漏洞的情況下,通過(guò)手工或者工具的方式咪辱,將數(shù)據(jù)庫(kù)中的敏感信息 dump 出來(lái)或者利用數(shù)據(jù)庫(kù)的特定獲取系統(tǒng)的權(quán)限振劳,這是一個(gè)利用的過(guò)程,在如今法律如此嚴(yán)格的情況下油狂,在做滲透測(cè)試的時(shí)候历恐,切記不要做這一步。
SQL 注入如何防御
從上面的例子可以看出选调,我們的參數(shù)是通過(guò)拼接字符串的方式進(jìn)行的夹供,在寫(xiě) php 代碼的時(shí)候灵份,通過(guò) $_GET['id'] 獲取到參數(shù)值之后直接拼接到了 SQL 查詢(xún)語(yǔ)句的后面仁堪,不過(guò)你提交的參數(shù)是什么都被當(dāng)作 SQL 語(yǔ)句來(lái)執(zhí)行了,那么我們?nèi)绾谓鉀Q這個(gè)問(wèn)題呢填渠?
如今為了解決 SQL 注入的問(wèn)題弦聂,從一開(kāi)始的過(guò)濾到現(xiàn)在使用的數(shù)據(jù)庫(kù)操作的庫(kù),使用參數(shù)化查詢(xún)的方式氛什,將用戶(hù)輸入或者參數(shù)的值全部當(dāng)作字符串來(lái)處理莺葫,不管你輸入的是什么,在 SQL 查詢(xún)語(yǔ)句中枪眉,你就是一個(gè)字符串捺檬,這樣你構(gòu)造的查詢(xún)語(yǔ)句就被當(dāng)作字符串來(lái)處理了,語(yǔ)句不被執(zhí)行也就不會(huì)存在 SQL 注入的問(wèn)題了贸铜。
俗話(huà)說(shuō)堡纬,只要是用戶(hù)輸入的都不可以信任,一個(gè)系統(tǒng)用戶(hù)可控的參數(shù)千千萬(wàn)蒿秦,只要有一個(gè)地方疏忽烤镐,那你之前做的一切就前功盡棄了,擴(kuò)展一下棍鳖,不僅僅是用戶(hù)輸入的不可信炮叶,只要是數(shù)據(jù)可以偽造的都不可信,比如 http 協(xié)議里的 Referer/user-agent 等。
總結(jié)
說(shuō)了這么多廢話(huà)镜悉,這個(gè)文章的目的就是讓一些沒(méi)什么基礎(chǔ)的人了解一下大家常說(shuō)的 SQL 注入相關(guān)的東西祟辟,從上面的描述可以看出,想要學(xué)習(xí) SQL 注入积瞒,最起碼的 http 協(xié)議是要學(xué)的川尖,不同數(shù)據(jù)的查詢(xún)語(yǔ)句以及數(shù)據(jù)庫(kù)特性也是需要了解的,一個(gè)網(wǎng)站的數(shù)據(jù)處理流程也是需要了解的茫孔,在有基礎(chǔ)的情況下叮喳,了解 SQL 注入的原理,然后就是進(jìn)階階段缰贝,以前的大佬經(jīng)常發(fā)的文章關(guān)于繞過(guò)什么的馍悟,慢慢積累就可以了。