題目丟一段請求或一段程式碼出來,問這是哪種攻擊。
有一題請求裡帶著 UNION SELECT,我看到它掛在一個網頁的參數上,我一開始選了 XSS,現在回頭看真是天真(?
我一開始根本沒把這幾種常見攻擊的長相分開來記。看到是網頁的東西就往 XSS 猜,看到帶參數就往 SQL iinjection 猜,單純靠的是題幹提到什麼,不是那段字串本身在做什麼。
先不管它出現在哪,先看這段字串是什麼語言,再看它想做什麼。
同樣是塞在網頁參數裡的一串東西,底下要它去解析的東西不一樣,那就是不同的攻擊。
' UNION SELECT、' OR '1'='1,這是 SQL。
我一開始也不熟悉SQL語法,所以我問了AI,為甚麼輸入' OR 1=1'
$id = $_GET['id']; // 使用者輸入,直接拿來用
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
我輸入 1 的時候,也就是id=1,查詢是這樣,只回一筆:
SELECT ... WHERE user_id = '1'
但我輸入的是 ' OR '1'='1,這段被原封不動拼進去,查詢就變成:
SELECT ... WHERE user_id = '' OR '1'='1'
看那個 WHERE:user_id = '' 找不到人,但後面接了一個 OR '1'='1',而 '1'='1' 肯定是成立的。整個條件變成恆真,資料庫就把整張 users 表都吐回來了。
我的理解是,關鍵在我輸入的那個==單引號==。
它把程式原本用來包住我這串值的引號提前閉合掉,後面的 OR '1'='1' 就不再是「一個要查的值」,而是被資料庫當成 SQL 語法去執行了。
單純就是,我的輸入跨過了「資料」跟「指令」的界線——本來只該是拿去比對的值,結果變成了改寫查詢的命令。
所以注入的成因,大致可以理解成:輸入沒有被當成純資料,而是被當成可執行的語法拼了進去。
至於怎麼從根本擋掉,則是對應到input validation,留到後面講修補的時候再說。 SQL injection。
<script>、onerror=、document.cookie,這類的是 JavaScript。
它想做的是讓這段程式碼被送到別人的瀏覽器上跑起來,偷 cookie 或做一些使用者不知情的動作。這是 XSS。
../../../etc/passwd,這是檔案路徑,而且一直往上跳。
它想做的是脫離網站原本設定好的目錄,去讀伺服器上不該給外面看的檔案。這種「用 ../ 在目錄之間遊走」的手法叫 directory traversal,如果那個路徑最後被網站拿去執行,就落在 LFI(Local File Inclusion,本地檔案引入)。
上面三個是我最一開始答錯過的,另外幾個我是後來補進來的,順手記一下差別。
命令注入(command injection):字串裡在呼叫系統去執行東西,像 ;ls、| whoami,或是某個語言的 exec 函式。它是想借網站的手,在伺服器的作業系統上下指令。
RFI(Remote File Inclusion,遠端檔案引入):手法跟 LFI 很像,也是操縱網址,差別在 LFI 讀的是伺服器上已經存在的檔案,RFI 是讓網站去把攻擊者自己主機上的程式碼抓過來執行。一個是讀本機、一個是跑遠端。
SSRF(Server-Side Request Forgery,伺服器端請求偽造):讓伺服器去對外發一個攻擊者指定的請求,常見的目標是內網位址,或雲端環境那個很有名的 169.254.169.254(拿雲端主機的中繼資料)。
我一開始會把 SSRF 跟 LFI 搞混,後來想通了,方向剛好是反的:LFI 是讓伺服器把本機的檔案讀出來給外面,SSRF 是讓伺服器對外去打一個請求。一個往內、一個往外。
| 看到的東西 | 大致是什麼語言/形式 | 想做什麼 |
|---|---|---|
' UNION SELECT、' OR 1=1 |
SQL | 改掉後端的查詢,多撈資料 |
<script>、onerror=、document.cookie |
JavaScript | 讓程式碼在別人的瀏覽器上跑 |
../../../etc/passwd |
檔案路徑 | 跳出目錄,讀伺服器上的檔案(LFI) |
;ls、| whoami、exec 函式 |
系統指令 | 在伺服器的 OS 上下指令 |
目標是內網 IP 或 169.254.169.254 |
一個對外請求 | 讓伺服器替攻擊者去打別的地方(SSRF) |
這種東西光看字串,印象不深,自己實踐一次比較記得住。
所以我在家裡的實驗環境裡架了一台 DVWA(Damn Vulnerable Web Application)。
它是一個故意留了一堆漏洞的練習網站,選單裡就直接分好 SQL Injection、XSS、File Inclusion、Command Injection 這幾個模組,難度還可以調,從 low 開始最適合看清楚一個 payload 打進去、後面發生什麼事。
難度我都設在 low,一個一個模組打過去。
SQL Injection。 User ID 欄位我不打數字,改打 ' OR '1'='1。
原本只該回一筆的查詢,把整張使用者表都吐了出來。

換個指令,改成 ' UNION SELECT user, password FROM users #,連密碼的 hash 都一起撈出來。
XSS (Reflected)。 Name 欄位打 <script>alert('XSS')</script>。
送出之後,瀏覽器直接把這段當程式碼跑,跳出一個視窗。我送的字串變成在我自己瀏覽器上執行的東西了。

File Inclusion。 它網址本來是 ?page=include.php,我把它改成 ?page=/etc/passwd。
low 難度沒做過濾,伺服器就把 /etc/passwd 的內容整個印在頁面上,一排 root:x:0:0:...。
Command Injection。 這個功能本來是拿去 ping 一個 IP,我輸入 127.0.0.1; whoami。
分號讓它 ping 完之後又多跑了一條指令,最後多印一行 www-data——那是這個網頁服務跑在誰身上。
四個模組打下來,前面那張表就不是背的了,是我親眼看它們各自長什麼樣。
這種靶機只在自己完全隔離的環境裡玩,DVWA 官方自己都直接寫「不要放到任何連得到外網的伺服器上,會被打爆」。
我這台就是關在實驗網段裡,連不出去。也不要拿這些 payload 去試不是自己的網站。
其實SQL injection、XSS、file inclusion、command injection這些東西獨立出來都能寫一整篇,但這邊先用一些簡單範例帶過,認識有這些攻擊、他們長甚麼樣子,先可以判別發生什麼事就好