SQLite Remote Code Execution(RCE)與 Stacked Queries 攻擊筆記
本文將整合以下重點內容,幫助你快速理解並記錄:
- SQLite RCE:利用
ATTACH DATABASE與檔案寫入特性實現遠端程式碼執行(Remote Code Execution)。 - Stacked Queries(堆疊查詢):如何在一次注入中執行多條 SQL 語句,如
INSERT、DELETE、CALL、EXEC等。 - 原始程式碼脆弱點:不安全的 SQL 拼接方式。
- 繞過過濾規則:如果有一個正規表達式(
/[+*{}',;<>()\\[\\]\\/\\:]/)阻擋特定字元,可藉由編碼、函式組合等方式繞過。
一、SQLite RCE 攻擊:ATTACH DATABASE + 寫入惡意 PHP
1. 攻擊示例程式碼
1 | |
ATTACH DATABASE:在 SQLite 中,可將任意路徑掛載為資料庫檔。
CREATE TABLE:在被掛載的「lol」資料庫裡,建立一個名為 pwn 的表,欄位為 dataz text。
INSERT:將<?php system($_GET['cmd']); ?>寫進這個掛載的檔案(lol.php),最終形成能被 PHP 解譯的惡意程式碼。
-
RCE 達成原因
SQLite 可掛載任何檔案:即使該檔案其實是 PHP 程式,而非真正的 .db。
Web Server 解譯執行 PHP:lol.php 只要被存放在可執行 PHP 的目錄(如 /var/www/),即可透過瀏覽器訪問並帶上 ?cmd=… 達到 遠端指令執行(RCE)。 -
攻擊條件
目標環境使用 SQLite。檔案系統、Web Server 允許在 /var/www/ 下寫入檔案或修改檔案。程式/PDO 允許執行「多條 SQL」的堆疊查詢(Stacked Queries)。
二、Stacked Queries(堆疊查詢)概念
- 什麼是 Stacked Queries?
在一次 SQL 呼叫中,使用 ; 分隔多條獨立指令。
例如:
1 | |
可以執行 INSERT、UPDATE、DELETE、DROP、EXEC、CALL 等操作,不再只局限於 SELECT。
-
常見攻擊方式
刪除資料:
1; DELETE FROM products
若原本程式是:
1 | |
拼接後成:
1 | |
執行完後,整個 products 表皆被刪除。
修改資料(改管理者密碼):
1 | |
直接在同一次查詢中更新任意帳號密碼。
呼叫儲存程序 / 系統函式(以 SQL Server 為例):
1; exec master..xp_cmdshell 'DEL important_file.txt'
可在作業系統層級刪除檔案,甚至執行更進一步的惡意命令。
-
限制
不同資料庫/不同 API 支援度:MySQL + PHP(PDO)通常預設不支援堆疊查詢;SQL Server 幾乎支援;SQLite 依版本與驅動設定而異。權限不足:若資料庫使用者權限有限,也可能無法成功執行 DROP TABLE 或系統函式。需要資訊蒐集:攻擊者須事先知道資料表結構、欄位名稱、儲存程序名稱等。
三、PHP 範例程式中的漏洞分析
以下是一段示例程式,只有在使用者 $_SESSION['username'] 為 axel 時,才會執行插入與刪除操作:
1 | |
風險點:$cat_name 直接以 字串拼接 方式進入 SQL
1 | |
攻擊者可注入惡意字串,例如:
1 | |
此時 SQL 會變成:
1 | |
堆疊查詢可行:若 PDO 與 SQLite 環境允許一次執行多條查詢,就可以串接更多指令,例如:
1 | |
前提:攻擊者需要拿到 axel 的 Session 或能以 axel 身分發送 POST。否則程式不會跑這段邏輯。
四、繞過字元過濾:$forbidden_patterns = "/[+*{}',;<>()\\[\\]\\/\\:]/";
有時程式員會用 Regex 過濾特定符號。例如阻擋:+ * { } ’ , ; < > ( ) [ ] / :。攻擊者可用下列思路嘗試「繞過」:
多重編碼
- URL 編碼:( → %28,/ → %2F,; → %3B…
- HTML 實體:( → (,; → ;…
- Unicode 逃逸:( → \u0028…
如果應用程式只在「原始字串」階段檢查,之後自動解碼卻沒再比對,就 能「先繞再解」。
在資料庫端用函式生成字元
SQLite 可用 char(…) 或 x’…’ 拼接字元。例如:
SELECT char(59); – 產生';'
或使用EXECUTE IMMEDIATE (SQLite 3.20+):
1 | |
前提是能在語法層先繞過 (、)、; 等被禁止字元,可透過編碼、二次解碼等方式實現。
-
改用雙引號 / 其他引號
有時候 " 未被禁,但 ’ 被禁。SQLite 在鬆散模式下," 也能包住字串。 -
分段注入
先在資料表寫一部分字串,下次再把它讀出來接著執行。或使用 PRAGMA writable_schema=1 等非常技巧。
核心結論
只靠單純的 Regex 過濾往往防不勝防。
更安全的做法:參數化查詢(Prepared Statements),避免在 SQL 中直接拼接使用者輸入。
總結
-
SQLite RCE
攻擊手法:ATTACH DATABASE → 建立表 → 寫入 PHP 碼 → Web Server 解譯執行 → RCE。條件:必須真的能寫入 /var/www/ 並能執行 .php。 -
Stacked Queries
一次執行多條查詢,威力十足:增刪改、呼叫系統函式、DROP 表格等。支援度依資料庫與 API 而異。 -
PHP 程式漏洞
$_SESSION[‘username’] === ‘axel’ → 權限夠高,危險操作無法可防。
$cat_name 未參數化 → SQL Injection 大門敞開。 -
繞過過濾
編碼技術、資料庫函式、雙引號替代等方法,都可能逃脫單純 Regex 的阻攔。根本防禦:使用 Prepared Statements,並限制檔案寫入權限、正確設定 Web Server。