PHP漏洞挖掘之旅——SQL注入漏洞
學習使人豐富知識,
知識使人提升才能,
才能使人創造業績。
php漏洞挖掘之旅
SQL注入基本知識
要想真正全面的了解PHP中的SQL注入漏洞,我們必須要有以下幾方面知識的系統掌握。一是PHP語法知識(搜索一下PHP手冊就行,網上有很多);二是MySQL語法知識(最重要的部分,PHP懂的多點少點沒關係,但MySQL語法一定要全面系統的掌握,因為裡面涉及到了語法的構造);三是對HTTP協議有一定的了解,要懂得Get和Post方式的不同;四是要懂得Cookie和Session的知識。看上去似乎需要很多的準備,但其實大家只要用心學,相信這些東西不會難倒大家的。廢話不多說了,我們開始自己挖掘PHP漏洞之旅的第二站吧。希望在這裡能讓大家感覺到比五一黃金周更好的心情。
PHP注入比較重要的一點就是GPC的設置問題,因為MySQL4以下的版本是不支持子語句的,而且當php.ini里的magic_quotes_gpc為On時,提交的變數中所有的「」 (單引號)、「"」(雙引號)、「」(反斜線)和空字元都會自動轉為含有反斜線的轉義字元,給注入帶來不少的阻礙。不過只要有經驗,構造有效的語句其實一點也不難,甚至成功率很高,但也要具體情況具體分析。
下面先講解一下「Union Select」聯查,這部分和ASP有點出入,除了一定要用「Union」連接兩條SQL語句,最難掌握的就是欄位的數量。如果大家看過MySQL參考手冊,就會知道Select語句中的「select_expression」(select_expression表示你希望檢索的列[欄位])部分列出的列必須具有同樣的類型。第一個Select查詢中使用的列名將作為結果集的列名返回。簡單地說,也就是Union後面查選的欄位數量、欄位類型都應該與前面的Select一樣;而且,如果前面的Select為真,就會同時返回兩個Select的結果;當前面的Select為假時,就會返回第二個Select所得到的結果,不過某些情況下會替換掉第一個Select原來應該顯示的欄位。它們之間的關係如圖1所示,有了這個圖,直觀多了吧?所以我們應該先知道前面查詢表的數據表的結構,才能更好的進行注入。
圖1
如果我們查詢兩個數據表的欄位相同,類型也相同,我們就可以這樣提交:
SELECT * FROM article WHERE articleid=$id UNION SELECT * FROM……
如果欄位數量、欄位類型任意一個不相同,我們就必須先搞清楚數據類型和欄位數量,此時可以這樣提交:
SELECT * FROM article WHERE articleid=$id UNION SELECT 1,1,1,1,1,1,1 FROM……
否則就會提示如下的錯誤:
The used SELECT statements have a different number of columns
如果不知道數據類型和欄位數量,可以用「1」來慢慢試,因為「1」屬於int、str、var類型,所以只要慢慢改變數量,一定可以猜到的。如果大家不能馬上理解上面的知識,後面還有詳細的例子,可以幫大家更好的理解。
現在,理論知識我們已經了解了,下面我們就用上次遠程文件包含的方法在Linux下繼續自己動手找漏洞的過程。
詳解SQL注入部分(初級)
這部分對PHP注入非常重要,希望大家能自己分析裡面的每一步驟,然後動手實踐,最後完成漏洞挖掘。
我們還是從最簡單的程序開始。第一個程序是QDBlog,它是非常簡單且小巧的PHP+MySQL的日誌系統,整個Blog系統才9k,別看它小,但小並不代表程序就沒有漏洞。首先啟動Red Hat Linux EL 4,把源代碼下載回來,然後在命令行下操作,圖2是我把源代碼下載並且解壓縮的步驟。
圖2
小知識
Linux下的壓縮格式和Windows有所不同,Linux的壓縮格式一般為.tar.gz(我們用「tar –xvzf 文件名.tar.gz」來解壓縮)、.tar.bz2(先用「bunzip2 文件名.tar.gz2」,再用「tar xvf」解壓縮)。
進入程序目錄後,我們仍然要用到GREP(global search regular expression and print out the line,全面搜索正則表達式並把行列印出來)命令。如果不懂GREP命令也沒關係,大家請參考上一期的文章或者在Google里搜索GREP就可以了,裡面有不少詳細解釋,我這裡就不浪費版面了。
在命令行中輸入「grep -n -r $_POST *」,意思是在當前目錄下的所有文件中進行遞歸搜索符合「$_POST」的語句並列印出來。如圖3所示,我們得到了一些結果,如下的代碼進入了我們的眼帘。
圖3
authenticate.php:2:if($_POST[username] and $_POST[wordpass]) {
authenticate.php:7:$sql = "SELECT permissions, username FROM $prefix"."auth WHERE username = " . $_POST[username] . " AND password = MD5(".$_POST[wor dpass].");";
這段代碼的意思是在「authenticate.php:2」中有提交用戶和密碼的SQL查詢語句。OK,現在有了文件名和行數,我們就進入到文件裡面看看這裡的username變數有沒有初始化,如果沒有的話就意味著我們可以利用經典的「1 OR 1 = 1」不用密碼就能直接進入後台進行管理了。
這裡我們用nano這個工具來操作,它是vi的增強版,具體的用法我就不多說了。輸入「nano authenticate.php」,如圖4所示,代碼不是很多,我就簡單講解一下,讓大家對認證也有一些了解。「if($_POST[username] and $_POST[wordpass])」表示,如果同時設置了從login.php中傳遞過來的username用戶名和wordpass密碼就執行if中的語句;「$sql = "SELECT permissions, username FROM $prefix"."auth WHERE username = " . $_POST[username] . " AND password = MD5(".$_POST[wordpass].");";」的意思是說從$prefix.auth($prefix是安裝qdblog的前綴)中把輸入的用戶名、密碼和資料庫中的進行對比,如果輸入的數據和資料庫中的一致就登錄到index.php中,否則繼續進入login.php。知道了username和wordpass是從login.php中傳遞過來的,我們下面要做的就是看看 login.php中的用戶名和密碼變數是否設置了,如圖5所示。這個程序果然非常簡單,直接就把輸入的用戶和密碼帶入了資料庫中,這是很明顯的漏洞。到這裡,程序的漏洞已經分析出來了,我們看一下如何利用吧。
圖4
圖5
接下來我們就實踐一下看看分析的是否正確吧。如圖6所示,我們來到login.php,用上面分析的漏洞來試試,在用戶名處輸入「1 OR 1 = 1」,密碼隨便輸入,此時authenticate.php中的語句就變成了「$sql = "SELECT permissions, username FROM qd_auth WHERE username = 1 OR 1 = 1 AND password = MD5(「12345」);」,這樣就繞過了驗證。如圖7所示,我們進入了後台了,成功了!
圖7
利用已經學習到的知識,現在挖掘到了第二種類型的漏洞了,感覺如何呢?
SQL注入進級部分(中級)
中級的SQL注入就是利用注入漏洞來拿到用戶和MD5密碼,進而進入後台,得到WebShell。
最近國內的兩大論壇PHPWind和Discuz都暴出了0Day,不少網站紛紛倒下,下面我們就結合上面講的知識來分析一下PHPWind論壇的最新漏洞。PHPWind是國內用得比較多的一個PHP+MySQL的論壇程序,最近PHPWind 5.0出現了一個SQL注入漏洞,SQL注入的經典思維就是變數沒有過濾直接就帶入到資料庫中進行查詢了。
這個漏洞出現在passport_client.php文件中,我把有漏洞的代碼分析一下。如圖8所示是程序的第5-11行,意思是說如果$passport_ifopen或者$passport_type不等於client的話,同時$action.$userdb.$forward.$passport_key不等於$verify就返回
本文由掘安技術小組研究室綜合網路整理,圖片來源於網路;轉載請註明」轉自掘安技術小組研究室「,並附上鏈接。
維權通道(客服中心):
投稿| ※輝少※
照片| ※風順※
責編| ※許心痕※
編輯| ※風順※
審核| ※許心痕※


TAG:IT小子心痕 |