SQL 做法、通靈
2020/4/7 王子軒
這堂課,補充一些東西,之後我們來應用一下你們之學的
這是之前的簡報
SELECT, UPDATE:https://hackmd.io/@XMRHRX/HJ-P95kGu#/
INSERT, DELETE, KEY:https://hackmd.io/@XMRHRX/rkKg-VfzO#/
INNER JOIN, UNION:https://hackmd.io/@XMRHRX/HyovPkEzd
語法的補充
AS
將某個欄位或是表設定一個別名(Alias)
WHERE with Alias
ORDER BY
SELECT <col1>[, <col2>...]
FROM <table>
ORDER BY <col> [<ASC|DESC>][, <col> [<ASC|DESC>]...]
ASC: 遞增 DESC:遞減 (如果沒有選擇,預設 ASC)
假設有一張表…
SELECT * FROM employees ORDER BY Title;
結果:
TOP (SQL Server)
LIMIT (MySQL)
ROWNUM (Oracle)
限制查詢後,最多顯示多少比資料
補充一些 table 的 column 設定
AUTO INCREMENT
欄位的值在插入時會自動增加(INCREMENT)
常常被用在作為 PK 的 ID,讓每筆資料的編號由資料庫系統幫你處理。
UNIQUE
欄位值不重複,如:生份證號碼
NOT NULL
設定該欄位不能為 NULL(類似空值),如:密碼
有 NOT NULL 和 AUTO_INCREMENT 的範例
建議需要時,再根據使用的資料庫系統上網查,因為語法時常有不同
SQL 的 function
要特別注意 function 會因為資料庫系統不同而有差 mysql、nosql、mariaDB…一大堆資料庫系統
SUM()
int SUM(int)
加總欄位的"數值"
SELECT SUM(<int col>) FROM table_name;
ex:
SELECT SUM(`city_code`) FROM Taiwan_City
範例
CONCAT
str CONCAT(str1, str2[, str3...])
合併"字串",將傳入的字串接起來
SLEEP()
睡覺
讓資料庫暫停/延遲/睡眠一段時間
聽起來沒用是吧?
COUNT()
int COUNT(<column_name>)
回傳該欄位總共有幾筆資料
試試
先下載&匯入:https://drive.google.com/file/d/1gKfOSMpdLPZgCxjxwGG8CCgmTdg8V9IL/view?usp=sharing
情境:新生入住
今天宿舍服務中心給了新生入住的表,
學號 | 床位 |
---|---|
B10700011 | G404-1 |
B10516005 | G405-1 |
B10716043 | G406-1 |
流程
- 根據入住資料的學號,從表 user 查到 uid
- 根據為床位,對應到 iptable 的 description
- 把 user 查到的 uid,填寫到 iptable 裡面的 uid
(實際情況跟練習有差)
學號 | 床位 |
---|---|
B10700011 | G404-1 |
B10516005 | G405-1 |
B10716043 | G406-1 |
試著用一個 query,只要放入對應的學號和床位,就能幫它入住。 下一頁有提示,要的自己翻頁過去 > <
流程
- 根據入住資料的學號,從表 user 查到 uid
SELECT WHERE
- 根據為床位,對應到 iptable 的 description
SELECT WHERE,善用LIKE %
- 把 user 查到的 uid,填寫到 iptable 裡面的 uid
INNER JOIN, UPDATE
先試著正確的查詢 1,2 步驟,再來試著用 INNER JOIN,正確根據床位合併,最後再來 UPDATE
SQL 的安全問題
SQL 的重點:injection
講了 3 堂課就是為了這個
幹訓的時候...SQL injection
NOTE:我知道幹訓的時候大部分人一臉蒙逼,在完全不知道 SQL 也沒寫過查詢就直接學注入 XD。
看懂 SQL 了,再回頭看一次
假設我們用查到的數量判斷,判斷帳號是否存在
SELECT COUNT(*) FROM `user`
WHERE `username` = "<user input>"
NOTE:就是如果你輸入的判斷查到資料,COUNT 就不會是 0,如果你輸入得資料不再資料庫內,就會是 0
user input = B10811011
SELECT COUNT(*) FROM `user`
WHERE `username` = "B10811011"
user input = B10811011" OR true --+-
SELECT COUNT(*) FROM `user`
WHERE `username` = "B10811011" OR true --+- "
--+-是 SQL 的註解之一,這裡是為了把最後一個\"無視,避免語法錯誤
NOTE: 這樣就可以破壞原來的用意,可以想想,既然可以插入自己的 query,那 query 還可以做哪些事情呢?
通常的學習軌跡
- 了解 SQL
- 寫過 SQL
- 程式裡面用過 SQL
被打爆- 看懂攻擊原理
開幹
有興趣可以試著在程式裡應用資料庫
不管要搞開發還是要把別人的 Server 搞到開花
未來都會用到
NOTE:其實這才是通常的軌跡,雖然我也是從注入開始學的啦 XD
補充資料
互動式教學:https://www.hacksplaining.com/exercises/sql-injection
Lab:https://defendtheweb.net/playground?subject=sqli