新聞中心
在今年的黑帽大會(huì)上James Kettle 講解了《Server-Side Template Injection: RCE for the modern webapp》,從服務(wù)端模板注入的形成到檢測(cè),再到驗(yàn)證和利用都進(jìn)行了詳細(xì)的介紹。本文在理解原文內(nèi)容的基礎(chǔ)上,結(jié)合更為具體的示例對(duì)服務(wù)端模板注入的原理和掃描檢測(cè)方法做一個(gè)淺析。

一、模板注入與常見Web注入
就注入類型的漏洞來說,常見 Web 注入有:SQL 注入,XSS 注入,XPATH 注入,XML 注入,代碼注入,命令注入等等。注入漏洞的實(shí)質(zhì)是服務(wù)端接受了用戶的輸入,未過濾或過濾不嚴(yán)謹(jǐn)執(zhí)行了拼接了用戶輸入的代碼,因此造成了各類注入。下面這段代碼足以說明這一點(diǎn):
// SQL 注入
$query = "select * from sometable where id=".$_GET['id'];
mysql_query($query);------------- 華麗的分割線 -------------// 模版注入
$temp->render("Hello ".$_GET['username']);而服務(wù)端模板注入和常見Web注入的成因一樣,也是服務(wù)端接收了用戶的輸入,將其作為 Web 應(yīng)用模板內(nèi)容的一部分,在進(jìn)行目標(biāo)編譯渲染的過程中,執(zhí)行了用戶插入的惡意內(nèi)容,因而可能導(dǎo)致了敏感信息泄露、代碼執(zhí)行、GetShell 等問題。其影響范圍主要取決于模版引擎的復(fù)雜性。
二、模板注入原理
模板注入涉及的是服務(wù)端Web應(yīng)用使用模板引擎渲染用戶請(qǐng)求的過程,這里我們使用 PHP 模版引擎 Twig 作為例子來說明模板注入產(chǎn)生的原理。考慮下面這段代碼:
render("Hello {{name}}", array("name" => $_GET["name"])); // 將用戶輸入作為模版變量的值
echo $output;使用 Twig 模版引擎渲染頁面,其中模版含有 {{name}} 變量,其模版變量值來自于 GET 請(qǐng)求參數(shù) $_GET["name"] 。顯然這段代碼并沒有什么問題,即使你想通過 name 參數(shù)傳遞一段 JavaScript 代碼給服務(wù)端進(jìn)行渲染,也許你會(huì)認(rèn)為這里可以進(jìn)行 XSS,但是由于模版引擎一般都默認(rèn)對(duì)渲染的變量值進(jìn)行編碼和轉(zhuǎn)義,所以并不會(huì)造成跨站腳本攻擊:
但是,如果渲染的模版內(nèi)容受到用戶的控制,情況就不一樣了。修改代碼為:
render("Hello {$_GET['name']}"); // 將用戶輸入作為模版內(nèi)容的一部分
echo $output;上面這段代碼在構(gòu)建模版時(shí),拼接了用戶輸入作為模板的內(nèi)容,現(xiàn)在如果再向服務(wù)端直接傳遞 JavaScript 代碼,用戶輸入會(huì)原樣輸出,測(cè)試結(jié)果顯而易見:
對(duì)比上面兩種情況,簡(jiǎn)單的說服務(wù)端模板注入的形成終究還是因?yàn)榉?wù)端相信了用戶的輸出而造成的(Web安全真諦:永遠(yuǎn)不要相信用戶的輸入!)。當(dāng)然了,第二種情況下,攻擊者不僅僅能插入 JavaScript 腳本,還能針對(duì)模板框架進(jìn)行進(jìn)一步的攻擊,此部分只說明原理,在后面會(huì)對(duì)攻擊利用進(jìn)行詳細(xì)說明和演示。
三、模板注入檢測(cè)
上面已經(jīng)講明了模板注入的形成原來,現(xiàn)在就來談?wù)剬?duì)其進(jìn)行檢測(cè)和掃描的方法。如果服務(wù)端將用戶的輸入作為了模板的一部分,那么在頁面渲染時(shí)也必定會(huì)將用戶輸入的內(nèi)容進(jìn)行模版編譯和解析最后輸出。
借用本文第二部分所用到的代碼:
render("Hello {$_GET['name']}"); // 將用戶輸入作為模版內(nèi)容的一部分
echo $output;在 Twig 模板引擎里,{{ var }} 除了可以輸出傳遞的變量以外,還能執(zhí)行一些基本的表達(dá)式然后將其結(jié)果作為該模板變量的值,例如這里用戶輸入 name={{2*10}} ,則在服務(wù)端拼接的模版內(nèi)容為:
Hello {{2*10}}Twig 模板引擎在編譯模板的過程中會(huì)計(jì)算 {{2*10}} 中的表達(dá)式 2*10 ,會(huì)將其返回值 20 作為模板變量的值輸出,如下圖:
現(xiàn)在把測(cè)試的數(shù)據(jù)改變一下,插入一些正常字符和 Twig 模板引擎默認(rèn)的注釋符,構(gòu)造 Payload 為:
IsVuln{# comment #}{{2*8}}OK實(shí)際服務(wù)端要進(jìn)行編譯的模板就被構(gòu)造為:
Hello IsVuln{# comment #}{{2*8}}OK這里簡(jiǎn)單分析一下,由于 {# comment #} 作為 Twig 模板引擎的默認(rèn)注釋形式,所以在前端輸出的時(shí)候并不會(huì)顯示,而 {{2*8}} 作為模板變量最終會(huì)返回 16 作為其值進(jìn)行顯示,因此前端最終會(huì)返回內(nèi)容 Hello IsVuln16OK ,如下圖:
通過上面兩個(gè)簡(jiǎn)單的示例,就能得到 SSTI 掃描檢測(cè)的大致流程(這里以 Twig 為例):
同常規(guī)的 SQL 注入檢測(cè),XSS 檢測(cè)一樣,模板注入漏洞的檢測(cè)也是向傳遞的參數(shù)中承載特定 Payload 并根據(jù)返回的內(nèi)容來進(jìn)行判斷的。每一個(gè)模板引擎都有著自己的語法,Payload 的構(gòu)造需要針對(duì)各類模板引擎制定其不同的掃描規(guī)則,就如同 SQL 注入中有著不同的數(shù)據(jù)庫類型一樣。
簡(jiǎn)單來說,就是更改請(qǐng)求參數(shù)使之承載含有模板引擎語法的 Payload,通過頁面渲染返回的內(nèi)容檢測(cè)承載的 Payload 是否有得到編譯解析,有解析則可以判定含有 Payload 對(duì)應(yīng)模板引擎注入,否則不存在 SSTI。
四、小結(jié)
本文簡(jiǎn)單介紹服務(wù)端模版注入漏洞如常規(guī) Web 注入漏洞之間的關(guān)系,分析了其產(chǎn)生的原理,并以 PHP 模板引擎 Twig 為例講解了 SSTI 常規(guī)的掃描和檢測(cè)方法。雖然說 SSTI 并不廣泛存在,但如果開發(fā)人員濫用模板引擎,進(jìn)行不安全的編碼,這樣 Web 應(yīng)用就可能出現(xiàn) SSTI,并且根據(jù)其模板引擎的復(fù)雜性和開發(fā)語言的特性,可能會(huì)造成非常嚴(yán)重的問題。
在后續(xù)的文章中會(huì)針對(duì)各語言流行的模板引擎做一個(gè)較為詳細(xì)的研究和分析,給出對(duì)應(yīng)的可利用點(diǎn)和方法。
網(wǎng)站標(biāo)題:服務(wù)端模板注入攻擊(SSTI)的原理和掃描檢測(cè)方法
轉(zhuǎn)載來于:http://fisionsoft.com.cn/article/dhpdogo.html


咨詢
建站咨詢
