sql注入講解

一、輸入1' 發現數據庫報錯,緣由是咱們的輸入直接被代入到數據庫查詢語句裏面。

二、有沒有辦法能夠不讓他報錯呢?能夠嘗試一下構造正確的數據庫語法,使之不報錯。好比輸入 1 and 1=1 試試

select * from wuser where id = 1 and 1=1; 1=1永遠成立,id=1也是一樣存在,因此這個查詢不會報錯,會輸出正確信息。

而後嘗試 id = 1 and 1=2 ,結果不顯示,說明咱們構造的語句成功在數據庫中執行了。

三、成功執行後,僅僅是跟正常查詢顯示相同的內容,那有沒有辦法能夠顯示其餘內容呢?咱們在mysql中使用union select來實現。

union select的做用是拼接在正確數據庫查詢語句後面進行聯合查詢,union select查詢的字段數必定跟主查詢的字段數一致。

好比 select id ,user ,pass from wuser 這是主查詢,查詢的字段是3個,因此後面的union select的查詢字段必定也是3個。

select * from wuser where id = 1 union select 1,2,3;

四、union select查詢成功後顯示的仍是沒有變,其緣由是主查詢也成功返回告終果,而頁面上只顯示了返回結果的第一行,所以要想看到union select的結果,須要令第一行也就是主查詢的結果爲空。經常使用的辦法就是把主查詢的1改爲-1.

五、mysql中有幾個默認自帶的庫和查詢函數。咱們就可使用這些來查出數據庫中全部的內容。

自帶的函數有:database(),version(),user()

自帶的庫有:information_schema,此庫只有mysql5.0之後的版本纔有。

在以前union select顯示的數字位置,將數字替換成查詢mysql

 

union 查詢的通常步驟:

一、經過and 1=1,and 1=2的輸入,來判斷是否存在注入點。若是結果不一致,說明咱們輸入的語句被數據庫執行了。

二、經過觀察或報錯信息來斷定輸入點的數據類型,數字型,字符型,搜索型

三、使用order by來肯定主查詢數目。orderby本質上是一個排序的語法,可是order by有個條件,就是排序必須創建在正確的主查詢條數上。因此在注入中用order by並非爲了排序,而是爲了確認主查詢的條數,確保union select的查詢數與主查詢一致。order by只會在超出主查詢列數後纔會報錯,小於或等於主查詢列數不報錯。

四、使用union select 查詢,將主查詢項改爲負數或不存在,select * from wuser where id = -1 union select 1,2,3

五、在顯示的數字位置上,替換對應的查詢語句,database(),version(),user()

六、使用information_schema進行全部內容查詢,如下用課堂上的查詢來舉例:

a.使用database()得知當前的庫名:woniu

b.根據庫名列出全部的表名:SELECT group_concat(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "庫名"

-1 union select 1,(SELECT group_concat(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "woniu"),3

c.根據庫名woniu 表名 wstu 列出全部的列名:num,name,age

SELECT group_concat(COLUMN_NAME)  FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = "庫名" AND TABLE_NAME = "表名"

d、知道表名和列名,能夠直接查出表的內容

select group_concat(num) from wstu;select group_concat(name) from wstu;select group_concat(age) from wstu;



字符型注入:

字符型和數字型原理同樣,只是須要注意下語法規範問題。

正常數字查詢:select * from wuser where id = 1;

字符查詢:select * from wuser where id = '1';

字符型的注入語句就變成 select * from wuser where id = '1 and 1=1'; 發現咱們輸入的內容都被包裹在單引號內,不能執行咱們想要的sql語句,所以就要想辦法去構造payload來脫離單引號包裹。

字符型注入的payload: id = 1' and 1=1 #

在sql查詢中就變成了 select * from wuser where id = '1' and 1=1#'

咱們經過本身添加的單引號跟原有的第一個單引號閉合,而後執行咱們的sql注入語句,原來的第二個單引號由於沒法處理,因此用#註釋掉。

最終造成 select * from wuser where id ='1' and 1=1

在mysql中註釋符有兩種:#和--空格,一般咱們在頁面上使用話,要轉換成url編碼,#轉換成%23,--空格轉換成--+



斷定字符型注入和數字型注入的區別:

輸入單引號報錯後將報錯信息取出進行比對。

報錯的是:''1'''   ,首先去掉報錯文本的單引號-》'1''->去掉咱們的輸入1'-》'' ,發現剩下一對單引號,說明是字符型

報錯的是:'1'',首先去掉報錯文本的單引號-》1'->去掉咱們的輸入1'-》  ,發現沒有引號留下,說明是數字型

字符型不必定就是單引號,也有雙引號,也有括號等等,就要根據實際的報錯狀況去試探出查詢的語法。



搜索型和字符型的用法相同,也是要考慮到閉合和註釋的。

搜索型的語法通常是:select * from wuser where id like '%1%';

sql

相關文章
相關標籤/搜索