剛用這個技術的時候,也是看了不少前輩的博客,並本身搭建了測試環境,仍是從最基礎的提及吧:php
sql注入,顧名思義,就是經過sql語句去web後端的數據庫打交道,凡是存在數據庫的web,基本均可能存在相似的網站,在OWASP的top10裏也是數一數二的,sql注入最終的目的就是經過從url或者其餘的一些地方傳入一些參數,從而構建數據庫查詢語句,去後臺查一些表項,在實際中通常用這個技術去查詢管理員帳戶。。。舉一個例子吧,在例子中使用使用Damn Vulnerable Web App這個測試平臺吧,這個平臺我以爲若是是用來研究這些技術的原理的話,還算方便。安裝過程就不說了,直接上圖吧:mysql
1.打開dvwa:web
2.點開左邊的sql injectionsql
在頁面上點擊提交按鈕,在提交到服務器的http請求包裏,會帶有下列字段:GET /dvwa/vulnerabilities/sqli/?id=1&Submit=Submit ,抓取字段的方法是使用burpsuit,使用方法很少說了。提交到後臺請求以下:shell
131031 4:05:48 587 Connect dvwa@localhost on
587 Init DB dvwa
587 Query SELECT first_name, last_name FROM users WHERE user_id = '1'數據庫
經過後臺的查詢語句能夠看出,在url提交的id的值,傳入到了後臺構造的查詢語句。全部的注入,都是根據後臺的這個查詢語句來進行構造的。例如,在前面的頁面傳入1=1後端
後臺的查詢語句爲:服務器
131031 4:11:19 588 Connect dvwa@localhost on
588 Init DB dvwa
588 Query SELECT first_name, last_name FROM users WHERE user_id = '1=1'session
下面在前面提交 1'='1,後臺構造的語句爲:函數
131031 4:13:29 589 Connect dvwa@localhost on
589 Init DB dvwa
589 Query SELECT first_name, last_name FROM users WHERE user_id = '1'='1'
後臺的語句其實就是構造後的成果了,全部的sql注入最終基本都是爲了造成相似的語句,只是可能最後構造的查詢語句的表現形式不同,可能會經過各類編碼來的形式來展示。
下面就經過在前面提交些特殊字符,來查出後臺儘可能多的數據:
一、在頁面提交 1'or 1=1 order by 1 -- 查看結果
二、在頁面提交 1'or 1=1 order by 2 -- 查看結果
三、在頁面提交 1'or 1=1 order by 3 -- 查看結果
判斷是否有sql注入漏洞的方式並非只有這三種,只要是爲真條件就能夠,好比 1‘ or 1>0 這類的也能夠
在通常注入過程當中,會使用這種辦法去判斷當前的表有幾列,前兩個的輸出結果會比較正常,最後的顯示會報錯,說明當前的表有2列。有了這個數據,就能夠經過union關鍵字去抓其餘的東西,例如:
查看當前數據庫版本:在頁面提交 1' union select 1,version() -- 能夠查看到版本的一些信息
查看當前會話:1' union select 1,current_user() -- 等等,用這種方式去查看其餘的一些信息
其餘查什麼用戶名啊,等等吧,都是這種方式。
基本sql注入的大前提就是sql注入查詢語句,在存在sql注入的狀況下,你能夠直接在輸入框、網址欄等地方直接輸入必定的查詢語句,能夠爲所欲爲的查訓信息,入侵步驟,通常爲:
1.判斷是否有漏洞:
在url後面添加' ,查看報錯信息,例:http://localhost/cms/show.php?id=36',此時會報錯,報錯類型爲:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
從報錯信息來看,咱們構造的id=36'已經被傳到了mysql後臺,即後臺沒有過濾特殊字符,這種類型基本能夠判斷爲一個注入點,下面如今url後面添加真條件,如:
http://localhost/cms/show.php?id=36 and 1=1 --
此時發現返回的頁面正常,將1=1換成1=2後,返回的頁面跟1=1的頁面不同,此時可判定爲注入漏洞
2.判斷數據庫版本等信息,如:用戶、版本等,在此步以前,須要判斷當前表的列數,後面要用到union語句將其餘的信息鏈接在當前表項後,如,在url後面添加order by 17
後出現的報錯信息爲:
http://localhost/cms/show.php?id=36 order by 17
Unknown column '17' in 'order clause',報錯信息說明列數沒有17列,那麼將17改成15呢?結果發現頁面正常出現了,那麼將17改成16呢:結果仍是報錯,這個時候就說明當前表爲15列,即存儲id=36的這個文章的表的列數爲15
接下來要作的就是查詢一些信息,首先輸入http://localhost/cms/show.php?id=-36 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -- ,輸入id=-36是爲了將後面的信息顯現出來,不然只顯示id36的,後面的查詢結果都會被覆蓋,輸入上面的信息以後,結果爲:
經過上面的信息能夠看出,第3列和第11列顯示在了比較顯眼的地方,那麼就把3和11換成咱們想知道的消息便可,如將3換成version(),將11換成current_user(),或者user()查看下結果:
經過這就能夠看到一些信息,那麼如今查看一些有用的信息,常見的有:(收集信息很重要,對後面的操做有很大的影響,每一個版本的數據庫注入語句都不同)
a:system_user() 系統用戶名
b:user() 用戶名
c:current_user() 當前用戶名
d:session_user()鏈接數據庫的用戶名
e:database() 數據庫名
f:version() MYSQL數據庫版本
g:load_file() MYSQL讀取本地文件的函數
h:@@datadir 讀取數據庫路徑
i:@@basedir MYSQL 安裝路徑
j:@@version_compile_os 操做系統
將3和11分別換成上面的信息,獲得的結果以下:
system_user(),user(),current_user(),session_user():root@localhost database():cms version():5.6.12-log @@basedir:c:/wamp/bin/mysql/mysql5.6.12 @@datadir:c:\wamp\bin\mysql\mysql5.6.12\data\
2.查詢管理員表,得到管理員登陸密碼
判斷表名:
上述方式來判斷表格,固然也能夠本身寫腳本作,由於上述的步驟相對費些時間,當將admin修改成cms_user時
上述步驟能夠看出後臺確實存在cms_users表,那麼如今判斷表列:
截圖裏的url輸入的是判斷username是否是爲空,即判斷是否是存在username字段,若是存在文章正常顯示,若是把username改成name,顯示不正常,以此來判斷是否存在字段。
判斷用戶名:
上述語句能夠判斷是否存在用戶名,再判斷是否存在password字段,再查看密碼:
密碼知道了,就去查把,在cmd5上面查下,可能付費,密碼是test123,正常來講得到md5後要去查的
3.登陸網站後臺,上傳小馬
登錄後臺後,找到上傳點,
登錄後臺找到上傳點後,上傳一句話木馬,也就是傳說中的小馬中的小馬,上傳的時候,直接選擇php木馬,會報錯,這種狀況下,能夠試試將木馬的名字改成phpmm.php.jpg,上傳,若是服務器對接受的文件自動重命名,這個時候,就須要使用到圖片木馬了,在本測試環境裏,就是使用第三種方式上傳木馬。前面的兩種方式能夠先測試下,而後再使用第三種方式把,第三種方式裏提到的圖片木馬的製做辦法爲 用反彙編工具將圖片用16進制打開,而後將一句話木馬放在最後,以下圖:
而後再菜刀裏連接一句話木馬:
此時即已經能夠連接到系統了,以下圖:
4.上傳大馬(這部其實能夠再上步中作好,只是若是上傳文件限制了大小,則先傳小馬,再從小馬傳大馬)
5.提權,得到系統權限(這部能夠作也可不作,通常狀況下拿下webshell就能夠了)